summaryrefslogtreecommitdiff
path: root/chromium/extensions/browser
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-24 12:15:48 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 13:30:04 +0000
commitb014812705fc80bff0a5c120dfcef88f349816dc (patch)
tree25a2e2d9fa285f1add86aa333389a839f81a39ae /chromium/extensions/browser
parent9f4560b1027ae06fdb497023cdcaf91b8511fa74 (diff)
downloadqtwebengine-chromium-b014812705fc80bff0a5c120dfcef88f349816dc.tar.gz
BASELINE: Update Chromium to 68.0.3440.125
Change-Id: I23f19369e01f688e496f5bf179abb521ad73874f Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/extensions/browser')
-rw-r--r--chromium/extensions/browser/BUILD.gn5
-rw-r--r--chromium/extensions/browser/api/BUILD.gn1
-rw-r--r--chromium/extensions/browser/api/alarms/alarm_manager.cc1
-rw-r--r--chromium/extensions/browser/api/alarms/alarms_api_unittest.cc1
-rw-r--r--chromium/extensions/browser/api/bluetooth/bluetooth_apitest.cc4
-rw-r--r--chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc10
-rw-r--r--chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h1
-rw-r--r--chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api_unittest.cc2
-rw-r--r--chromium/extensions/browser/api/cast_channel/cast_channel_apitest.cc6
-rw-r--r--chromium/extensions/browser/api/cec_private/BUILD.gn23
-rw-r--r--chromium/extensions/browser/api/cec_private/cec_private_api.cc118
-rw-r--r--chromium/extensions/browser/api/cec_private/cec_private_api.h75
-rw-r--r--chromium/extensions/browser/api/cec_private/cec_private_apitest.cc76
-rw-r--r--chromium/extensions/browser/api/declarative/declarative_rule_unittest.cc1
-rw-r--r--chromium/extensions/browser/api/declarative/rules_registry.cc3
-rw-r--r--chromium/extensions/browser/api/declarative_net_request/indexed_rule.cc14
-rw-r--r--chromium/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc14
-rw-r--r--chromium/extensions/browser/api/declarative_net_request/ruleset_manager.cc107
-rw-r--r--chromium/extensions/browser/api/declarative_net_request/ruleset_manager.h27
-rw-r--r--chromium/extensions/browser/api/declarative_webrequest/webrequest_action.cc2
-rw-r--r--chromium/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc2
-rw-r--r--chromium/extensions/browser/api/extensions_api_client.cc2
-rw-r--r--chromium/extensions/browser/api/extensions_api_client.h8
-rw-r--r--chromium/extensions/browser/api/file_system/file_system_api.cc2
-rw-r--r--chromium/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc8
-rw-r--r--chromium/extensions/browser/api/idle/idle_api_unittest.cc6
-rw-r--r--chromium/extensions/browser/api/lock_screen_data/data_item_unittest.cc3
-rw-r--r--chromium/extensions/browser/api/lock_screen_data/lock_screen_item_storage_unittest.cc2
-rw-r--r--chromium/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc2
-rw-r--r--chromium/extensions/browser/api/management/management_api.cc51
-rw-r--r--chromium/extensions/browser/api/management/management_api_delegate.h4
-rw-r--r--chromium/extensions/browser/api/media_perception_private/media_perception_api_delegate.h5
-rw-r--r--chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.cc3
-rw-r--r--chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.h1
-rw-r--r--chromium/extensions/browser/api/media_perception_private/media_perception_private_api.cc11
-rw-r--r--chromium/extensions/browser/api/media_perception_private/media_perception_private_api.h17
-rw-r--r--chromium/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc7
-rw-r--r--chromium/extensions/browser/api/messaging/message_property_provider.cc11
-rw-r--r--chromium/extensions/browser/api/mime_handler_private/mime_handler_private.cc6
-rw-r--r--chromium/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc71
-rw-r--r--chromium/extensions/browser/api/networking_private/networking_private_linux.h1
-rw-r--r--chromium/extensions/browser/api/printer_provider/printer_provider_apitest.cc76
-rw-r--r--chromium/extensions/browser/api/printer_provider/printer_provider_print_job.h17
-rw-r--r--chromium/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc28
-rw-r--r--chromium/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc11
-rw-r--r--chromium/extensions/browser/api/storage/settings_storage_quota_enforcer.cc1
-rw-r--r--chromium/extensions/browser/api/system_display/display_info_provider.cc16
-rw-r--r--chromium/extensions/browser/api/system_display/display_info_provider.h4
-rw-r--r--chromium/extensions/browser/api/system_display/system_display_api.cc26
-rw-r--r--chromium/extensions/browser/api/usb/usb_api.cc11
-rw-r--r--chromium/extensions/browser/api/usb/usb_manual_apitest.cc6
-rw-r--r--chromium/extensions/browser/api/web_request/form_data_parser.cc20
-rw-r--r--chromium/extensions/browser/api/web_request/upload_data_presenter.cc43
-rw-r--r--chromium/extensions/browser/api/web_request/upload_data_presenter.h7
-rw-r--r--chromium/extensions/browser/api/web_request/upload_data_presenter_unittest.cc43
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_api.cc36
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_api_helpers.cc132
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_info.cc5
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_info.h8
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_permissions.cc92
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_permissions.h12
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_permissions_unittest.cc26
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc12
-rw-r--r--chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h12
-rw-r--r--chromium/extensions/browser/api_unittest.cc7
-rw-r--r--chromium/extensions/browser/app_window/app_delegate.h11
-rw-r--r--chromium/extensions/browser/app_window/app_window.cc12
-rw-r--r--chromium/extensions/browser/app_window/app_window.h8
-rw-r--r--chromium/extensions/browser/app_window/app_window_contents.cc2
-rw-r--r--chromium/extensions/browser/browsertest_util.cc21
-rw-r--r--chromium/extensions/browser/browsertest_util.h20
-rw-r--r--chromium/extensions/browser/computed_hashes.cc2
-rw-r--r--chromium/extensions/browser/content_hash_fetcher_unittest.cc2
-rw-r--r--chromium/extensions/browser/content_hash_tree.cc3
-rw-r--r--chromium/extensions/browser/content_hash_tree_unittest.cc2
-rw-r--r--chromium/extensions/browser/content_verifier/content_hash.cc7
-rw-r--r--chromium/extensions/browser/content_verifier/content_hash.h3
-rw-r--r--chromium/extensions/browser/content_verifier/content_verifier_key.h12
-rw-r--r--chromium/extensions/browser/content_verifier_unittest.cc6
-rw-r--r--chromium/extensions/browser/content_verify_job.cc6
-rw-r--r--chromium/extensions/browser/content_verify_job_unittest.cc4
-rw-r--r--chromium/extensions/browser/event_router.cc7
-rw-r--r--chromium/extensions/browser/event_router.h6
-rw-r--r--chromium/extensions/browser/extension_error_test_util.cc2
-rw-r--r--chromium/extensions/browser/extension_event_histogram_value.h7
-rw-r--r--chromium/extensions/browser/extension_function.cc8
-rw-r--r--chromium/extensions/browser/extension_function.h6
-rw-r--r--chromium/extensions/browser/extension_function_constants.cc20
-rw-r--r--chromium/extensions/browser/extension_function_constants.h17
-rw-r--r--chromium/extensions/browser/extension_function_dispatcher.cc6
-rw-r--r--chromium/extensions/browser/extension_function_histogram_value.h15
-rw-r--r--chromium/extensions/browser/extension_host.cc16
-rw-r--r--chromium/extensions/browser/extension_host.h2
-rw-r--r--chromium/extensions/browser/extension_host_delegate.h2
-rw-r--r--chromium/extensions/browser/extension_icon_image_unittest.cc2
-rw-r--r--chromium/extensions/browser/extension_navigation_throttle.cc7
-rw-r--r--chromium/extensions/browser/extension_pref_value_map_unittest.cc2
-rw-r--r--chromium/extensions/browser/extension_protocols.cc111
-rw-r--r--chromium/extensions/browser/extension_protocols.h26
-rw-r--r--chromium/extensions/browser/extension_system.h5
-rw-r--r--chromium/extensions/browser/file_reader_unittest.cc4
-rw-r--r--chromium/extensions/browser/guest_view/app_view/app_view_apitest.cc2
-rw-r--r--chromium/extensions/browser/guest_view/app_view/app_view_guest.cc4
-rw-r--r--chromium/extensions/browser/guest_view/extension_options/extension_options_apitest.cc4
-rw-r--r--chromium/extensions/browser/guest_view/extension_options/extension_options_guest.cc26
-rw-r--r--chromium/extensions/browser/guest_view/extension_options/extension_options_guest.h2
-rw-r--r--chromium/extensions/browser/guest_view/extension_view/extension_view_guest.cc4
-rw-r--r--chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc7
-rw-r--r--chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.h1
-rw-r--r--chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc104
-rw-r--r--chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc18
-rw-r--r--chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h6
-rw-r--r--chromium/extensions/browser/guest_view/web_view/web_view_apitest.cc36
-rw-r--r--chromium/extensions/browser/guest_view/web_view/web_view_guest.cc97
-rw-r--r--chromium/extensions/browser/guest_view/web_view/web_view_guest.h11
-rw-r--r--chromium/extensions/browser/guest_view/web_view/web_view_guest_delegate.h4
-rw-r--r--chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.cc3
-rw-r--r--chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.h6
-rw-r--r--chromium/extensions/browser/image_loader_unittest.cc2
-rw-r--r--chromium/extensions/browser/info_map_unittest.cc2
-rw-r--r--chromium/extensions/browser/install/BUILD.gn2
-rw-r--r--chromium/extensions/browser/install/crx_install_error.cc51
-rw-r--r--chromium/extensions/browser/install/crx_install_error.h85
-rw-r--r--chromium/extensions/browser/install/sandboxed_unpacker_failure_reason.h84
-rw-r--r--chromium/extensions/browser/json_file_sanitizer.cc2
-rw-r--r--chromium/extensions/browser/json_file_sanitizer.h2
-rw-r--r--chromium/extensions/browser/lazy_background_task_queue.cc97
-rw-r--r--chromium/extensions/browser/lazy_background_task_queue.h19
-rw-r--r--chromium/extensions/browser/lazy_background_task_queue_unittest.cc77
-rw-r--r--chromium/extensions/browser/management_policy.cc29
-rw-r--r--chromium/extensions/browser/management_policy.h13
-rw-r--r--chromium/extensions/browser/media_capture_util.cc110
-rw-r--r--chromium/extensions/browser/media_capture_util.h42
-rw-r--r--chromium/extensions/browser/mock_external_provider.cc37
-rw-r--r--chromium/extensions/browser/mock_external_provider.h8
-rw-r--r--chromium/extensions/browser/path_util.cc6
-rw-r--r--chromium/extensions/browser/path_util_unittest.cc2
-rw-r--r--chromium/extensions/browser/runtime_data_unittest.cc6
-rw-r--r--chromium/extensions/browser/sandboxed_unpacker.cc237
-rw-r--r--chromium/extensions/browser/sandboxed_unpacker.h94
-rw-r--r--chromium/extensions/browser/sandboxed_unpacker_unittest.cc149
-rw-r--r--chromium/extensions/browser/test_management_policy.cc9
-rw-r--r--chromium/extensions/browser/test_management_policy.h4
-rw-r--r--chromium/extensions/browser/updater/extension_downloader.cc57
-rw-r--r--chromium/extensions/browser/updater/extension_downloader.h32
-rw-r--r--chromium/extensions/browser/updater/request_queue_impl.h1
-rw-r--r--chromium/extensions/browser/updater/update_data_provider.cc76
-rw-r--r--chromium/extensions/browser/updater/update_data_provider.h7
-rw-r--r--chromium/extensions/browser/updater/update_data_provider_unittest.cc207
-rw-r--r--chromium/extensions/browser/updater/update_service.cc129
-rw-r--r--chromium/extensions/browser/updater/update_service.h13
-rw-r--r--chromium/extensions/browser/updater/update_service_unittest.cc157
-rw-r--r--chromium/extensions/browser/user_script_loader.cc2
-rw-r--r--chromium/extensions/browser/value_store/leveldb_value_store_unittest.cc1
-rw-r--r--chromium/extensions/browser/value_store/value_store_frontend_unittest.cc3
-rw-r--r--chromium/extensions/browser/verified_contents.cc16
-rw-r--r--chromium/extensions/browser/verified_contents.h6
-rw-r--r--chromium/extensions/browser/verified_contents_unittest.cc10
158 files changed, 2592 insertions, 1386 deletions
diff --git a/chromium/extensions/browser/BUILD.gn b/chromium/extensions/browser/BUILD.gn
index e1dcd075672..40b145b62c4 100644
--- a/chromium/extensions/browser/BUILD.gn
+++ b/chromium/extensions/browser/BUILD.gn
@@ -127,6 +127,8 @@ jumbo_source_set("browser_sources") {
"extension_file_task_runner.h",
"extension_function.cc",
"extension_function.h",
+ "extension_function_constants.cc",
+ "extension_function_constants.h",
"extension_function_dispatcher.cc",
"extension_function_dispatcher.h",
"extension_function_registry.cc",
@@ -276,6 +278,8 @@ jumbo_source_set("browser_sources") {
"load_monitoring_extension_host_queue.h",
"management_policy.cc",
"management_policy.h",
+ "media_capture_util.cc",
+ "media_capture_util.h",
"mojo/interface_registration.cc",
"mojo/interface_registration.h",
"mojo/keep_alive_impl.cc",
@@ -476,6 +480,7 @@ source_set("browser_tests") {
}
if (is_chromeos) {
sources += [
+ "api/cec_private/cec_private_apitest.cc",
"api/media_perception_private/media_perception_private_apitest.cc",
"api/virtual_keyboard/virtual_keyboard_apitest.cc",
]
diff --git a/chromium/extensions/browser/api/BUILD.gn b/chromium/extensions/browser/api/BUILD.gn
index 691e452964b..8045a127f65 100644
--- a/chromium/extensions/browser/api/BUILD.gn
+++ b/chromium/extensions/browser/api/BUILD.gn
@@ -131,6 +131,7 @@ source_set("api") {
]
public_deps += [
+ "//extensions/browser/api/cec_private",
"//extensions/browser/api/clipboard",
"//extensions/browser/api/diagnostics",
"//extensions/browser/api/networking_config",
diff --git a/chromium/extensions/browser/api/alarms/alarm_manager.cc b/chromium/extensions/browser/api/alarms/alarm_manager.cc
index f6f9171c524..2440e0c75e7 100644
--- a/chromium/extensions/browser/api/alarms/alarm_manager.cc
+++ b/chromium/extensions/browser/api/alarms/alarm_manager.cc
@@ -11,7 +11,6 @@
#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
-#include "base/message_loop/message_loop.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "base/time/time.h"
diff --git a/chromium/extensions/browser/api/alarms/alarms_api_unittest.cc b/chromium/extensions/browser/api/alarms/alarms_api_unittest.cc
index 0d2d2dd5558..c15047feba3 100644
--- a/chromium/extensions/browser/api/alarms/alarms_api_unittest.cc
+++ b/chromium/extensions/browser/api/alarms/alarms_api_unittest.cc
@@ -7,7 +7,6 @@
#include <stddef.h>
#include "base/json/json_reader.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/simple_test_clock.h"
#include "base/values.h"
diff --git a/chromium/extensions/browser/api/bluetooth/bluetooth_apitest.cc b/chromium/extensions/browser/api/bluetooth/bluetooth_apitest.cc
index 1db964d9590..a5f23ca635e 100644
--- a/chromium/extensions/browser/api/bluetooth/bluetooth_apitest.cc
+++ b/chromium/extensions/browser/api/bluetooth/bluetooth_apitest.cc
@@ -41,12 +41,12 @@ namespace {
static const char* kAdapterAddress = "A1:A2:A3:A4:A5:A6";
static const char* kName = "whatsinaname";
-class BluetoothApiTest : public ExtensionApiTest {
+class BluetoothApiTest : public extensions::ExtensionApiTest {
public:
BluetoothApiTest() {}
void SetUpOnMainThread() override {
- ExtensionApiTest::SetUpOnMainThread();
+ extensions::ExtensionApiTest::SetUpOnMainThread();
empty_extension_ = extensions::ExtensionBuilder("Test").Build();
SetUpMockAdapter();
}
diff --git a/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc b/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc
index cb2a3e454a7..69134a8a2a8 100644
--- a/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc
+++ b/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.cc
@@ -545,13 +545,13 @@ BluetoothSocketSendFunction::~BluetoothSocketSendFunction() {}
ExtensionFunction::ResponseAction BluetoothSocketSendFunction::Run() {
DCHECK_CURRENTLY_ON(work_thread_id());
- auto params = bluetooth_socket::Send::Params::Create(*args_);
- EXTENSION_FUNCTION_VALIDATE(params.get());
+ params_ = bluetooth_socket::Send::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(params_.get());
- io_buffer_size_ = params->data.size();
- io_buffer_ = new net::WrappedIOBuffer(params->data.data());
+ io_buffer_size_ = params_->data.size();
+ io_buffer_ = new net::WrappedIOBuffer(params_->data.data());
- BluetoothApiSocket* socket = GetSocket(params->socket_id);
+ BluetoothApiSocket* socket = GetSocket(params_->socket_id);
if (!socket)
return RespondNow(Error(kSocketNotFoundError));
diff --git a/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h b/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h
index 8178739413d..bbab919aacb 100644
--- a/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h
+++ b/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h
@@ -294,6 +294,7 @@ class BluetoothSocketSendFunction : public BluetoothSocketAsyncApiFunction {
void OnError(BluetoothApiSocket::ErrorReason reason,
const std::string& message);
+ std::unique_ptr<bluetooth_socket::Send::Params> params_;
scoped_refptr<net::IOBuffer> io_buffer_;
size_t io_buffer_size_;
diff --git a/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api_unittest.cc b/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api_unittest.cc
index 990505568ba..e755a3f612e 100644
--- a/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api_unittest.cc
+++ b/chromium/extensions/browser/api/bluetooth_socket/bluetooth_socket_api_unittest.cc
@@ -41,7 +41,7 @@ TEST_F(BluetoothSocketApiUnittest, CreateThenClose) {
.Set("name", "bluetooth app")
.Set("version", "1.0")
.Set("bluetooth",
- DictionaryBuilder().SetBoolean("socket", true).Build())
+ DictionaryBuilder().Set("socket", true).Build())
.Set("app",
DictionaryBuilder()
.Set("background",
diff --git a/chromium/extensions/browser/api/cast_channel/cast_channel_apitest.cc b/chromium/extensions/browser/api/cast_channel/cast_channel_apitest.cc
index 5e7e35ec1c0..39f14f846cf 100644
--- a/chromium/extensions/browser/api/cast_channel/cast_channel_apitest.cc
+++ b/chromium/extensions/browser/api/cast_channel/cast_channel_apitest.cc
@@ -84,12 +84,12 @@ ACTION_TEMPLATE(InvokeCompletionCallback,
} // namespace
-class CastChannelAPITest : public ExtensionApiTest {
+class CastChannelAPITest : public extensions::ExtensionApiTest {
public:
CastChannelAPITest() : ip_endpoint_(CreateIPEndPointForTest()) {}
void SetUpCommandLine(base::CommandLine* command_line) override {
- ExtensionApiTest::SetUpCommandLine(command_line);
+ extensions::ExtensionApiTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(
extensions::switches::kWhitelistedExtensionID, kTestExtensionId);
}
@@ -98,7 +98,7 @@ class CastChannelAPITest : public ExtensionApiTest {
// Stub out DualMediaSinkService so it does not interfere with the test.
media_router::DualMediaSinkService::SetInstanceForTest(
new media_router::NoopDualMediaSinkService());
- ExtensionApiTest::SetUp();
+ extensions::ExtensionApiTest::SetUp();
}
void SetUpMockCastSocket() {
diff --git a/chromium/extensions/browser/api/cec_private/BUILD.gn b/chromium/extensions/browser/api/cec_private/BUILD.gn
new file mode 100644
index 00000000000..eea3c3439b2
--- /dev/null
+++ b/chromium/extensions/browser/api/cec_private/BUILD.gn
@@ -0,0 +1,23 @@
+# Copyright 2018 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.
+
+import("//extensions/buildflags/buildflags.gni")
+
+assert(enable_extensions,
+ "Cannot depend on extensions because enable_extensions=false.")
+
+source_set("cec_private") {
+ sources = [
+ "cec_private_api.cc",
+ "cec_private_api.h",
+ ]
+
+ deps = [
+ "//extensions/common/api",
+ ]
+
+ public_deps = [
+ "//extensions/browser:browser_sources",
+ ]
+}
diff --git a/chromium/extensions/browser/api/cec_private/cec_private_api.cc b/chromium/extensions/browser/api/cec_private/cec_private_api.cc
new file mode 100644
index 00000000000..936a7895ef4
--- /dev/null
+++ b/chromium/extensions/browser/api/cec_private/cec_private_api.cc
@@ -0,0 +1,118 @@
+// Copyright 2018 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 "extensions/browser/api/cec_private/cec_private_api.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "chromeos/dbus/cec_service_client.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "extensions/common/api/cec_private.h"
+#include "extensions/common/manifest_handlers/kiosk_mode_info.h"
+
+namespace {
+
+const char kKioskOnlyError[] =
+ "Only kiosk enabled extensions are allowed to use this function.";
+
+extensions::api::cec_private::DisplayCecPowerState
+ConvertCecServiceClientPowerState(
+ chromeos::CecServiceClient::PowerState power_state) {
+ switch (power_state) {
+ case chromeos::CecServiceClient::PowerState::kError:
+ return extensions::api::cec_private::DISPLAY_CEC_POWER_STATE_ERROR;
+ case chromeos::CecServiceClient::PowerState::kAdapterNotConfigured:
+ return extensions::api::cec_private::
+ DISPLAY_CEC_POWER_STATE_ADAPTERNOTCONFIGURED;
+ case chromeos::CecServiceClient::PowerState::kNoDevice:
+ return extensions::api::cec_private::DISPLAY_CEC_POWER_STATE_NODEVICE;
+ case chromeos::CecServiceClient::PowerState::kOn:
+ return extensions::api::cec_private::DISPLAY_CEC_POWER_STATE_ON;
+ case chromeos::CecServiceClient::PowerState::kStandBy:
+ return extensions::api::cec_private::DISPLAY_CEC_POWER_STATE_STANDBY;
+ case chromeos::CecServiceClient::PowerState::kTransitioningToOn:
+ return extensions::api::cec_private::
+ DISPLAY_CEC_POWER_STATE_TRANSITIONINGTOON;
+ case chromeos::CecServiceClient::PowerState::kTransitioningToStandBy:
+ return extensions::api::cec_private::
+ DISPLAY_CEC_POWER_STATE_TRANSITIONINGTOSTANDBY;
+ case chromeos::CecServiceClient::PowerState::kUnknown:
+ return extensions::api::cec_private::DISPLAY_CEC_POWER_STATE_UNKNOWN;
+ }
+
+ NOTREACHED();
+ return extensions::api::cec_private::DISPLAY_CEC_POWER_STATE_UNKNOWN;
+}
+
+} // namespace
+
+namespace extensions {
+namespace api {
+
+CecPrivateFunction::CecPrivateFunction() = default;
+
+CecPrivateFunction::~CecPrivateFunction() = default;
+
+// Only allow calls from kiosk mode extensions.
+bool CecPrivateFunction::PreRunValidation(std::string* error) {
+ if (!UIThreadExtensionFunction::PreRunValidation(error))
+ return false;
+
+ if (KioskModeInfo::IsKioskEnabled(extension()))
+ return true;
+
+ *error = kKioskOnlyError;
+ return false;
+}
+
+CecPrivateSendStandByFunction::CecPrivateSendStandByFunction() = default;
+
+CecPrivateSendStandByFunction::~CecPrivateSendStandByFunction() = default;
+
+ExtensionFunction::ResponseAction CecPrivateSendStandByFunction::Run() {
+ chromeos::DBusThreadManager::Get()->GetCecServiceClient()->SendStandBy();
+ return RespondNow(NoArguments());
+}
+
+CecPrivateSendWakeUpFunction::CecPrivateSendWakeUpFunction() = default;
+
+CecPrivateSendWakeUpFunction::~CecPrivateSendWakeUpFunction() = default;
+
+ExtensionFunction::ResponseAction CecPrivateSendWakeUpFunction::Run() {
+ chromeos::DBusThreadManager::Get()->GetCecServiceClient()->SendWakeUp();
+ return RespondNow(NoArguments());
+}
+
+CecPrivateQueryDisplayCecPowerStateFunction::
+ CecPrivateQueryDisplayCecPowerStateFunction() = default;
+
+CecPrivateQueryDisplayCecPowerStateFunction::
+ ~CecPrivateQueryDisplayCecPowerStateFunction() = default;
+
+ExtensionFunction::ResponseAction
+CecPrivateQueryDisplayCecPowerStateFunction::Run() {
+ chromeos::DBusThreadManager::Get()
+ ->GetCecServiceClient()
+ ->QueryDisplayCecPowerState(base::BindOnce(
+ &CecPrivateQueryDisplayCecPowerStateFunction::HandlePowerStates,
+ this));
+ return RespondLater();
+}
+
+void CecPrivateQueryDisplayCecPowerStateFunction::HandlePowerStates(
+ const std::vector<chromeos::CecServiceClient::PowerState>& power_states) {
+ std::vector<cec_private::DisplayCecPowerState> result_power_states;
+
+ for (const chromeos::CecServiceClient::PowerState& state : power_states) {
+ result_power_states.push_back(ConvertCecServiceClientPowerState(state));
+ }
+
+ Respond(ArgumentList(cec_private::QueryDisplayCecPowerState::Results::Create(
+ result_power_states)));
+}
+
+} // namespace api
+} // namespace extensions
diff --git a/chromium/extensions/browser/api/cec_private/cec_private_api.h b/chromium/extensions/browser/api/cec_private/cec_private_api.h
new file mode 100644
index 00000000000..6a2029b5cda
--- /dev/null
+++ b/chromium/extensions/browser/api/cec_private/cec_private_api.h
@@ -0,0 +1,75 @@
+// Copyright 2018 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 EXTENSIONS_BROWSER_API_CEC_PRIVATE_CEC_PRIVATE_API_H_
+#define EXTENSIONS_BROWSER_API_CEC_PRIVATE_CEC_PRIVATE_API_H_
+
+#include <vector>
+
+#include "chromeos/dbus/cec_service_client.h"
+#include "extensions/browser/extension_function.h"
+#include "extensions/browser/extension_function_histogram_value.h"
+
+namespace extensions {
+namespace api {
+
+class CecPrivateFunction : public UIThreadExtensionFunction {
+ public:
+ CecPrivateFunction();
+
+ protected:
+ ~CecPrivateFunction() override;
+ bool PreRunValidation(std::string* error) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CecPrivateFunction);
+};
+
+class CecPrivateSendStandByFunction : public CecPrivateFunction {
+ public:
+ CecPrivateSendStandByFunction();
+ DECLARE_EXTENSION_FUNCTION("cecPrivate.sendStandBy", CECPRIVATE_SENDSTANDBY)
+
+ protected:
+ ~CecPrivateSendStandByFunction() override;
+ ResponseAction Run() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CecPrivateSendStandByFunction);
+};
+
+class CecPrivateSendWakeUpFunction : public CecPrivateFunction {
+ public:
+ CecPrivateSendWakeUpFunction();
+ DECLARE_EXTENSION_FUNCTION("cecPrivate.sendWakeUp", CECPRIVATE_SENDWAKEUP)
+
+ protected:
+ ~CecPrivateSendWakeUpFunction() override;
+ ResponseAction Run() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CecPrivateSendWakeUpFunction);
+};
+
+class CecPrivateQueryDisplayCecPowerStateFunction : public CecPrivateFunction {
+ public:
+ CecPrivateQueryDisplayCecPowerStateFunction();
+ DECLARE_EXTENSION_FUNCTION("cecPrivate.queryDisplayCecPowerState",
+ CECPRIVATE_QUERYDISPLAYCECPOWERSTATE)
+
+ protected:
+ ~CecPrivateQueryDisplayCecPowerStateFunction() override;
+ ResponseAction Run() override;
+
+ private:
+ void HandlePowerStates(
+ const std::vector<chromeos::CecServiceClient::PowerState>& power_states);
+
+ DISALLOW_COPY_AND_ASSIGN(CecPrivateQueryDisplayCecPowerStateFunction);
+};
+
+} // namespace api
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_API_CEC_PRIVATE_CEC_PRIVATE_API_H_
diff --git a/chromium/extensions/browser/api/cec_private/cec_private_apitest.cc b/chromium/extensions/browser/api/cec_private/cec_private_apitest.cc
new file mode 100644
index 00000000000..23c4b31c164
--- /dev/null
+++ b/chromium/extensions/browser/api/cec_private/cec_private_apitest.cc
@@ -0,0 +1,76 @@
+// Copyright 2018 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 "base/macros.h"
+#include "chromeos/dbus/cec_service_client.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_cec_service_client.h"
+#include "extensions/common/features/feature_session_type.h"
+#include "extensions/common/switches.h"
+#include "extensions/shell/test/shell_apitest.h"
+#include "extensions/test/extension_test_message_listener.h"
+#include "extensions/test/result_catcher.h"
+
+namespace extensions {
+
+namespace {
+
+constexpr char kTestAppId[] = "jabiebdnficieldhmegebckfhpfidfla";
+
+class CecPrivateKioskApiTest : public ShellApiTest {
+ public:
+ CecPrivateKioskApiTest()
+ : session_type_(
+ ScopedCurrentFeatureSessionType(FeatureSessionType::KIOSK)) {}
+ ~CecPrivateKioskApiTest() override = default;
+
+ void SetUpOnMainThread() override {
+ cec_ = static_cast<chromeos::FakeCecServiceClient*>(
+ chromeos::DBusThreadManager::Get()->GetCecServiceClient());
+ }
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitchASCII(
+ extensions::switches::kWhitelistedExtensionID, kTestAppId);
+ ShellApiTest::SetUpCommandLine(command_line);
+ }
+
+ protected:
+ chromeos::FakeCecServiceClient* cec_ = nullptr;
+
+ private:
+ std::unique_ptr<base::AutoReset<FeatureSessionType>> session_type_;
+ DISALLOW_COPY_AND_ASSIGN(CecPrivateKioskApiTest);
+};
+
+using CecPrivateNonKioskApiTest = ShellApiTest;
+
+} // namespace
+
+IN_PROC_BROWSER_TEST_F(CecPrivateKioskApiTest, TestAllApiFunctions) {
+ cec_->set_tv_power_states({chromeos::CecServiceClient::PowerState::kOn,
+ chromeos::CecServiceClient::PowerState::kOn});
+ extensions::ResultCatcher catcher;
+ ExtensionTestMessageListener standby_call_count("standby_call_count", true);
+ ExtensionTestMessageListener wakeup_call_count("wakeup_call_count", true);
+
+ ASSERT_TRUE(LoadApp("api_test/cec_private/api"));
+
+ ASSERT_TRUE(standby_call_count.WaitUntilSatisfied())
+ << standby_call_count.message();
+ standby_call_count.Reply(cec_->stand_by_call_count());
+
+ ASSERT_TRUE(wakeup_call_count.WaitUntilSatisfied())
+ << wakeup_call_count.message();
+ wakeup_call_count.Reply(cec_->wake_up_call_count());
+
+ ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
+}
+
+IN_PROC_BROWSER_TEST_F(CecPrivateNonKioskApiTest, TestCecPrivateNotAvailable) {
+ ASSERT_TRUE(RunAppTest("api_test/cec_private/non_kiosk_api_not_available"))
+ << message_;
+}
+
+} // namespace extensions
diff --git a/chromium/extensions/browser/api/declarative/declarative_rule_unittest.cc b/chromium/extensions/browser/api/declarative/declarative_rule_unittest.cc
index c7e869c200f..8cb2cb86ab2 100644
--- a/chromium/extensions/browser/api/declarative/declarative_rule_unittest.cc
+++ b/chromium/extensions/browser/api/declarative/declarative_rule_unittest.cc
@@ -5,7 +5,6 @@
#include "extensions/browser/api/declarative/declarative_rule.h"
#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
#include "base/test/values_test_util.h"
#include "base/values.h"
#include "components/url_matcher/url_matcher_constants.h"
diff --git a/chromium/extensions/browser/api/declarative/rules_registry.cc b/chromium/extensions/browser/api/declarative/rules_registry.cc
index 9066bfb0f49..b84cc3a1701 100644
--- a/chromium/extensions/browser/api/declarative/rules_registry.cc
+++ b/chromium/extensions/browser/api/declarative/rules_registry.cc
@@ -8,7 +8,6 @@
#include "base/bind.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
@@ -88,7 +87,7 @@ RulesRegistry::RulesRegistry(content::BrowserContext* browser_context,
ready_(/*signaled=*/!cache_delegate), // Immediately ready if no cache
// delegate to wait for.
last_generated_rule_identifier_id_(0),
- weak_ptr_factory_(browser_context_ ? this : NULL) {
+ weak_ptr_factory_(this) {
if (cache_delegate) {
cache_delegate_ = cache_delegate->GetWeakPtr();
cache_delegate->Init(this);
diff --git a/chromium/extensions/browser/api/declarative_net_request/indexed_rule.cc b/chromium/extensions/browser/api/declarative_net_request/indexed_rule.cc
index 9849a407b01..47e5d21b76d 100644
--- a/chromium/extensions/browser/api/declarative_net_request/indexed_rule.cc
+++ b/chromium/extensions/browser/api/declarative_net_request/indexed_rule.cc
@@ -155,6 +155,8 @@ flat_rule::ElementType GetElementType(dnr_api::ResourceType resource_type) {
switch (resource_type) {
case dnr_api::RESOURCE_TYPE_NONE:
return flat_rule::ElementType_NONE;
+ case dnr_api::RESOURCE_TYPE_MAIN_FRAME:
+ return flat_rule::ElementType_MAIN_FRAME;
case dnr_api::RESOURCE_TYPE_SUB_FRAME:
return flat_rule::ElementType_SUBDOCUMENT;
case dnr_api::RESOURCE_TYPE_STYLESHEET:
@@ -171,6 +173,8 @@ flat_rule::ElementType GetElementType(dnr_api::ResourceType resource_type) {
return flat_rule::ElementType_XMLHTTPREQUEST;
case dnr_api::RESOURCE_TYPE_PING:
return flat_rule::ElementType_PING;
+ case dnr_api::RESOURCE_TYPE_CSP_REPORT:
+ return flat_rule::ElementType_CSP_REPORT;
case dnr_api::RESOURCE_TYPE_MEDIA:
return flat_rule::ElementType_MEDIA;
case dnr_api::RESOURCE_TYPE_WEBSOCKET:
@@ -214,10 +218,12 @@ ParseResult ComputeElementTypes(const dnr_api::RuleCondition& condition,
if (include_element_type_mask & exclude_element_type_mask)
return ParseResult::ERROR_RESOURCE_TYPE_DUPLICATED;
- *element_types =
- include_element_type_mask
- ? include_element_type_mask
- : (flat_rule::ElementType_ANY & ~exclude_element_type_mask);
+ if (include_element_type_mask != flat_rule::ElementType_NONE)
+ *element_types = include_element_type_mask;
+ else if (exclude_element_type_mask != flat_rule::ElementType_NONE)
+ *element_types = flat_rule::ElementType_ANY & ~exclude_element_type_mask;
+ else
+ *element_types = url_pattern_index::kDefaultFlatElementTypesMask;
return ParseResult::SUCCESS;
}
diff --git a/chromium/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc b/chromium/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
index 334d50b51cd..7fe106ecdab 100644
--- a/chromium/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
+++ b/chromium/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
@@ -156,7 +156,8 @@ TEST_F(IndexedRuleTest, ResourceTypesParsing) {
// Only valid if |expected_result| is SUCCESS.
const uint16_t expected_element_types;
} cases[] = {
- {nullptr, nullptr, ParseResult::SUCCESS, flat_rule::ElementType_ANY},
+ {nullptr, nullptr, ParseResult::SUCCESS,
+ flat_rule::ElementType_ANY & ~flat_rule::ElementType_MAIN_FRAME},
{nullptr,
std::make_unique<ResourceTypeVec>(
ResourceTypeVec({dnr_api::RESOURCE_TYPE_SCRIPT})),
@@ -174,12 +175,13 @@ TEST_F(IndexedRuleTest, ResourceTypesParsing) {
flat_rule::ElementType_NONE},
{nullptr,
std::make_unique<ResourceTypeVec>(ResourceTypeVec(
- {dnr_api::RESOURCE_TYPE_SUB_FRAME, dnr_api::RESOURCE_TYPE_STYLESHEET,
- dnr_api::RESOURCE_TYPE_SCRIPT, dnr_api::RESOURCE_TYPE_IMAGE,
- dnr_api::RESOURCE_TYPE_FONT, dnr_api::RESOURCE_TYPE_OBJECT,
+ {dnr_api::RESOURCE_TYPE_MAIN_FRAME, dnr_api::RESOURCE_TYPE_SUB_FRAME,
+ dnr_api::RESOURCE_TYPE_STYLESHEET, dnr_api::RESOURCE_TYPE_SCRIPT,
+ dnr_api::RESOURCE_TYPE_IMAGE, dnr_api::RESOURCE_TYPE_FONT,
+ dnr_api::RESOURCE_TYPE_OBJECT,
dnr_api::RESOURCE_TYPE_XMLHTTPREQUEST, dnr_api::RESOURCE_TYPE_PING,
- dnr_api::RESOURCE_TYPE_MEDIA, dnr_api::RESOURCE_TYPE_WEBSOCKET,
- dnr_api::RESOURCE_TYPE_OTHER})),
+ dnr_api::RESOURCE_TYPE_CSP_REPORT, dnr_api::RESOURCE_TYPE_MEDIA,
+ dnr_api::RESOURCE_TYPE_WEBSOCKET, dnr_api::RESOURCE_TYPE_OTHER})),
ParseResult::ERROR_NO_APPLICABLE_RESOURCE_TYPES,
flat_rule::ElementType_NONE},
{std::make_unique<ResourceTypeVec>(ResourceTypeVec()),
diff --git a/chromium/extensions/browser/api/declarative_net_request/ruleset_manager.cc b/chromium/extensions/browser/api/declarative_net_request/ruleset_manager.cc
index 3090523b810..ba24ab6fb70 100644
--- a/chromium/extensions/browser/api/declarative_net_request/ruleset_manager.cc
+++ b/chromium/extensions/browser/api/declarative_net_request/ruleset_manager.cc
@@ -34,11 +34,11 @@ flat_rule::ElementType GetElementType(content::ResourceType type) {
case content::RESOURCE_TYPE_LAST_TYPE:
case content::RESOURCE_TYPE_PREFETCH:
case content::RESOURCE_TYPE_SUB_RESOURCE:
- // TODO(crbug.com/696822): Add support for main frame and csp report to
- // url_pattern_index. These are supported by the Web Request API.
+ return flat_rule::ElementType_OTHER;
case content::RESOURCE_TYPE_MAIN_FRAME:
+ return flat_rule::ElementType_MAIN_FRAME;
case content::RESOURCE_TYPE_CSP_REPORT:
- return flat_rule::ElementType_OTHER;
+ return flat_rule::ElementType_CSP_REPORT;
case content::RESOURCE_TYPE_SCRIPT:
case content::RESOURCE_TYPE_WORKER:
case content::RESOURCE_TYPE_SHARED_WORKER:
@@ -152,79 +152,76 @@ void RulesetManager::RemoveRuleset(const ExtensionId& extension_id) {
ClearRendererCacheOnNavigation();
}
-bool RulesetManager::ShouldBlockRequest(const WebRequestInfo& request,
- bool is_incognito_context) const {
+RulesetManager::Action RulesetManager::EvaluateRequest(
+ const WebRequestInfo& request,
+ bool is_incognito_context,
+ GURL* redirect_url) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(redirect_url);
if (!ShouldEvaluateRequest(request))
- return false;
-
- if (test_observer_)
- test_observer_->OnShouldBlockRequest(request, is_incognito_context);
+ return Action::NONE;
SCOPED_UMA_HISTOGRAM_TIMER(
- "Extensions.DeclarativeNetRequest.ShouldBlockRequestTime.AllExtensions");
+ "Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions");
+ if (test_observer_)
+ test_observer_->OnEvaluateRequest(request, is_incognito_context);
+
+ const GURL& url = request.url;
const url::Origin first_party_origin =
request.initiator.value_or(url::Origin());
const flat_rule::ElementType element_type = GetElementType(request);
- const bool is_third_party =
- IsThirdPartyRequest(request.url, first_party_origin);
-
- for (const auto& ruleset_data : rulesets_) {
- if (!ShouldEvaluateRulesetForRequest(ruleset_data, request,
- is_incognito_context)) {
- continue;
- }
+ const bool is_third_party = IsThirdPartyRequest(url, first_party_origin);
- if (ruleset_data.matcher->ShouldBlockRequest(
- request.url, first_party_origin, element_type, is_third_party)) {
- return true;
+ std::vector<bool> should_evaluate_rulesets_for_request(rulesets_.size());
+
+ // We first check if any extension wants the request to be blocked.
+ {
+ size_t i = 0;
+ auto ruleset_data = rulesets_.begin();
+ for (; ruleset_data != rulesets_.end(); ++ruleset_data, ++i) {
+ // As a minor optimization, cache the value of
+ // |ShouldEvaluateRulesetForRequest|.
+ should_evaluate_rulesets_for_request[i] = ShouldEvaluateRulesetForRequest(
+ *ruleset_data, request, is_incognito_context);
+
+ if (!should_evaluate_rulesets_for_request[i])
+ continue;
+
+ if (ruleset_data->matcher->ShouldBlockRequest(
+ url, first_party_origin, element_type, is_third_party)) {
+ return Action::BLOCK;
+ }
}
}
- return false;
-}
-
-bool RulesetManager::ShouldRedirectRequest(const WebRequestInfo& request,
- bool is_incognito_context,
- GURL* redirect_url) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(redirect_url);
- if (!ShouldEvaluateRequest(request))
- return false;
+ // The request shouldn't be blocked. Now check if any extension wants to
+ // redirect the request.
// Redirecting WebSocket handshake request is prohibited.
- const flat_rule::ElementType element_type = GetElementType(request);
if (element_type == flat_rule::ElementType_WEBSOCKET)
- return false;
-
- SCOPED_UMA_HISTOGRAM_TIMER(
- "Extensions.DeclarativeNetRequest.ShouldRedirectRequestTime."
- "AllExtensions");
-
- const GURL& url = request.url;
- const url::Origin first_party_origin =
- request.initiator.value_or(url::Origin());
- const bool is_third_party = IsThirdPartyRequest(url, first_party_origin);
+ return Action::NONE;
// This iterates in decreasing order of extension installation time. Hence
// more recently installed extensions get higher priority in choosing the
// redirect url.
- for (const auto& ruleset_data : rulesets_) {
- if (!ShouldEvaluateRulesetForRequest(ruleset_data, request,
- is_incognito_context)) {
- continue;
- }
-
- if (ruleset_data.matcher->ShouldRedirectRequest(
- url, first_party_origin, element_type, is_third_party,
- redirect_url)) {
- return true;
+ {
+ size_t i = 0;
+ auto ruleset_data = rulesets_.begin();
+ for (; ruleset_data != rulesets_.end(); ++ruleset_data, ++i) {
+ if (!should_evaluate_rulesets_for_request[i])
+ continue;
+
+ if (ruleset_data->matcher->ShouldRedirectRequest(
+ url, first_party_origin, element_type, is_third_party,
+ redirect_url)) {
+ return Action::REDIRECT;
+ }
}
}
- return false;
+ return Action::NONE;
}
void RulesetManager::SetObserverForTest(TestObserver* observer) {
@@ -295,7 +292,7 @@ bool RulesetManager::ShouldEvaluateRulesetForRequest(
// have to do for split mode incognito extensions, pass false for
// |crosses_incognito|.
const bool crosses_incognito = false;
- PermissionsData::AccessType result =
+ PermissionsData::PageAccess result =
WebRequestPermissions::CanExtensionAccessURL(
info_map_, ruleset.extension_id, request.url, tab_id,
crosses_incognito,
@@ -303,7 +300,7 @@ bool RulesetManager::ShouldEvaluateRulesetForRequest(
request.initiator);
// TODO(crbug.com/809680): Handle ACCESS_WITHHELD.
- return result == PermissionsData::ACCESS_ALLOWED;
+ return result == PermissionsData::PageAccess::kAllowed;
}
} // namespace declarative_net_request
diff --git a/chromium/extensions/browser/api/declarative_net_request/ruleset_manager.h b/chromium/extensions/browser/api/declarative_net_request/ruleset_manager.h
index c4b2d6ac926..dd161d229b0 100644
--- a/chromium/extensions/browser/api/declarative_net_request/ruleset_manager.h
+++ b/chromium/extensions/browser/api/declarative_net_request/ruleset_manager.h
@@ -28,14 +28,20 @@ class RulesetMatcher;
// same sequence.
class RulesetManager {
public:
+ enum class Action {
+ NONE,
+ BLOCK,
+ REDIRECT,
+ };
+
explicit RulesetManager(const InfoMap* info_map);
~RulesetManager();
// An interface used for testing purposes.
class TestObserver {
public:
- virtual void OnShouldBlockRequest(const WebRequestInfo& request,
- bool is_incognito_context) = 0;
+ virtual void OnEvaluateRequest(const WebRequestInfo& request,
+ bool is_incognito_context) = 0;
protected:
virtual ~TestObserver() {}
@@ -50,15 +56,14 @@ class RulesetManager {
// corresponding AddRuleset.
void RemoveRuleset(const ExtensionId& extension_id);
- // Returns whether the given |request| should be blocked.
- bool ShouldBlockRequest(const WebRequestInfo& request,
- bool is_incognito_context) const;
-
- // Returns whether the given |request| should be redirected along with the
- // |redirect_url|. |redirect_url| must not be null.
- bool ShouldRedirectRequest(const WebRequestInfo& request,
- bool is_incognito_context,
- GURL* redirect_url) const;
+ // Returns the action to take for the given request. |redirect_url| will be
+ // populated if the returned action is |REDIRECT|. Blocking rules have higher
+ // priority than redirect rules. For determining the |redirect_url|, most
+ // recently installed extensions are given preference. |redirect_url| must not
+ // be null.
+ Action EvaluateRequest(const WebRequestInfo& request,
+ bool is_incognito_context,
+ GURL* redirect_url) const;
// Returns the number of RulesetMatcher currently being managed.
size_t GetMatcherCountForTest() const { return rulesets_.size(); }
diff --git a/chromium/extensions/browser/api/declarative_webrequest/webrequest_action.cc b/chromium/extensions/browser/api/declarative_webrequest/webrequest_action.cc
index 0045f147a61..b6957e49d93 100644
--- a/chromium/extensions/browser/api/declarative_webrequest/webrequest_action.cc
+++ b/chromium/extensions/browser/api/declarative_webrequest/webrequest_action.cc
@@ -508,7 +508,7 @@ bool WebRequestAction::HasPermission(ApplyInfo* apply_info,
return WebRequestPermissions::CanExtensionAccessURL(
extension_info_map, extension_id, request->url, -1,
apply_info->crosses_incognito, permission_check,
- request->initiator) == PermissionsData::ACCESS_ALLOWED;
+ request->initiator) == PermissionsData::PageAccess::kAllowed;
}
// static
diff --git a/chromium/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/chromium/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
index c3d35ce84cd..6d5571f09df 100644
--- a/chromium/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
+++ b/chromium/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -41,7 +41,7 @@ const char kUnknownConditionName[] = "unknownType";
base::FilePath TestDataPath(base::StringPiece relative_to_src) {
base::FilePath src_dir;
- CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
+ CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
return src_dir.AppendASCII(relative_to_src);
}
diff --git a/chromium/extensions/browser/api/extensions_api_client.cc b/chromium/extensions/browser/api/extensions_api_client.cc
index 7e2881d24b4..213c0a76ae2 100644
--- a/chromium/extensions/browser/api/extensions_api_client.cc
+++ b/chromium/extensions/browser/api/extensions_api_client.cc
@@ -44,7 +44,7 @@ bool ExtensionsAPIClient::ShouldHideResponseHeader(
}
bool ExtensionsAPIClient::ShouldHideBrowserNetworkRequest(
- const GURL& url) const {
+ const WebRequestInfo& request) const {
return false;
}
diff --git a/chromium/extensions/browser/api/extensions_api_client.h b/chromium/extensions/browser/api/extensions_api_client.h
index c5e4a6d8c80..32ddf2ba2f2 100644
--- a/chromium/extensions/browser/api/extensions_api_client.h
+++ b/chromium/extensions/browser/api/extensions_api_client.h
@@ -55,6 +55,7 @@ class ValueStoreCache;
class ValueStoreFactory;
class VirtualKeyboardDelegate;
class WebRequestEventRouterDelegate;
+struct WebRequestInfo;
class WebViewGuest;
class WebViewGuestDelegate;
class WebViewPermissionHelper;
@@ -94,9 +95,10 @@ class ExtensionsAPIClient {
virtual bool ShouldHideResponseHeader(const GURL& url,
const std::string& header_name) const;
- // Returns true if a request from the given URL from the browser context
- // should be hidden from extensions.
- virtual bool ShouldHideBrowserNetworkRequest(const GURL& url) const;
+ // Returns true if the given |request| should be hidden from extensions. This
+ // should be invoked on the IO thread.
+ virtual bool ShouldHideBrowserNetworkRequest(
+ const WebRequestInfo& request) const;
// Creates the AppViewGuestDelegate.
virtual AppViewGuestDelegate* CreateAppViewGuestDelegate() const;
diff --git a/chromium/extensions/browser/api/file_system/file_system_api.cc b/chromium/extensions/browser/api/file_system/file_system_api.cc
index e4163081e8c..c1a510e26c8 100644
--- a/chromium/extensions/browser/api/file_system/file_system_api.cc
+++ b/chromium/extensions/browser/api/file_system/file_system_api.cc
@@ -551,7 +551,7 @@ void FileSystemChooseEntryFunction::ConfirmDirectoryAccessAsync(
for (size_t i = 0; i < arraysize(kGraylistedPaths); i++) {
base::FilePath graylisted_path;
- if (!PathService::Get(kGraylistedPaths[i], &graylisted_path))
+ if (!base::PathService::Get(kGraylistedPaths[i], &graylisted_path))
continue;
if (check_path != graylisted_path && !check_path.IsParent(graylisted_path))
continue;
diff --git a/chromium/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/chromium/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
index 8a11ac17bc8..7fb278f33d2 100644
--- a/chromium/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
+++ b/chromium/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -146,11 +146,9 @@ std::unique_ptr<extensions::UserScript> ParseContentScript(
// The default for WebUI is not having special access, but we can change that
// if needed.
- bool allowed_everywhere = false;
- if (extension &&
- extensions::PermissionsData::CanExecuteScriptEverywhere(extension))
- allowed_everywhere = true;
-
+ bool allowed_everywhere =
+ extension && extensions::PermissionsData::CanExecuteScriptEverywhere(
+ extension->id(), extension->location());
for (const std::string& match : script_value.matches) {
URLPattern pattern(UserScript::ValidUserScriptSchemes(allowed_everywhere));
if (pattern.Parse(match) != URLPattern::PARSE_SUCCESS) {
diff --git a/chromium/extensions/browser/api/idle/idle_api_unittest.cc b/chromium/extensions/browser/api/idle/idle_api_unittest.cc
index 3b1749619ec..72cc783ddff 100644
--- a/chromium/extensions/browser/api/idle/idle_api_unittest.cc
+++ b/chromium/extensions/browser/api/idle/idle_api_unittest.cc
@@ -32,10 +32,10 @@ namespace {
class MockEventDelegate : public IdleManager::EventDelegate {
public:
MockEventDelegate() {}
- virtual ~MockEventDelegate() {}
+ ~MockEventDelegate() override {}
MOCK_METHOD2(OnStateChanged, void(const std::string&, ui::IdleState));
- virtual void RegisterObserver(EventRouter::Observer* observer) {}
- virtual void UnregisterObserver(EventRouter::Observer* observer) {}
+ void RegisterObserver(EventRouter::Observer* observer) override {}
+ void UnregisterObserver(EventRouter::Observer* observer) override {}
};
class TestIdleProvider : public IdleManager::IdleTimeProvider {
diff --git a/chromium/extensions/browser/api/lock_screen_data/data_item_unittest.cc b/chromium/extensions/browser/api/lock_screen_data/data_item_unittest.cc
index b6b17f9b493..a12783f796a 100644
--- a/chromium/extensions/browser/api/lock_screen_data/data_item_unittest.cc
+++ b/chromium/extensions/browser/api/lock_screen_data/data_item_unittest.cc
@@ -13,6 +13,7 @@
#include "base/callback.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
+#include "base/sequenced_task_runner.h"
#include "base/values.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/test/test_browser_context.h"
@@ -170,7 +171,7 @@ class DataItemTest : public testing::Test {
ListBuilder app_handlers_builder;
app_handlers_builder.Append(DictionaryBuilder()
.Set("action", "new_note")
- .SetBoolean("enabled_on_lock_screen", true)
+ .Set("enabled_on_lock_screen", true)
.Build());
scoped_refptr<const Extension> extension =
ExtensionBuilder()
diff --git a/chromium/extensions/browser/api/lock_screen_data/lock_screen_item_storage_unittest.cc b/chromium/extensions/browser/api/lock_screen_data/lock_screen_item_storage_unittest.cc
index 0574a1b3f40..25dd3bb696b 100644
--- a/chromium/extensions/browser/api/lock_screen_data/lock_screen_item_storage_unittest.cc
+++ b/chromium/extensions/browser/api/lock_screen_data/lock_screen_item_storage_unittest.cc
@@ -656,7 +656,7 @@ class LockScreenItemStorageTest : public ExtensionsTest {
ListBuilder app_handlers_builder;
app_handlers_builder.Append(DictionaryBuilder()
.Set("action", "new_note")
- .SetBoolean("enabled_on_lock_screen", true)
+ .Set("enabled_on_lock_screen", true)
.Build());
scoped_refptr<const Extension> extension =
ExtensionBuilder()
diff --git a/chromium/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc b/chromium/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc
index a440c3fdd17..8594adec810 100644
--- a/chromium/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc
+++ b/chromium/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc
@@ -270,7 +270,7 @@ class LockScreenValueStoreMigratorImplTest : public testing::Test {
ListBuilder app_handlers_builder;
app_handlers_builder.Append(DictionaryBuilder()
.Set("action", "new_note")
- .SetBoolean("enabled_on_lock_screen", true)
+ .Set("enabled_on_lock_screen", true)
.Build());
scoped_refptr<const Extension> extension =
ExtensionBuilder()
diff --git a/chromium/extensions/browser/api/management/management_api.cc b/chromium/extensions/browser/api/management/management_api.cc
index 9c9fa6cb6e0..6aaccbe269e 100644
--- a/chromium/extensions/browser/api/management/management_api.cc
+++ b/chromium/extensions/browser/api/management/management_api.cc
@@ -37,6 +37,7 @@
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_icon_set.h"
+#include "extensions/common/manifest.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "extensions/common/manifest_handlers/offline_enabled_info.h"
#include "extensions/common/manifest_handlers/options_page_info.h"
@@ -96,6 +97,7 @@ std::vector<management::LaunchType> GetAvailableLaunchTypes(
}
management::ExtensionInfo CreateExtensionInfo(
+ const Extension* source_extension,
const Extension& extension,
content::BrowserContext* context) {
ExtensionSystem* system = ExtensionSystem::Get(context);
@@ -116,8 +118,8 @@ management::ExtensionInfo CreateExtensionInfo(
info.options_url = OptionsPageInfo::GetOptionsPage(&extension).spec();
info.homepage_url.reset(
new std::string(ManifestURL::GetHomepageURL(&extension).spec()));
- info.may_disable =
- system->management_policy()->UserMayModifySettings(&extension, NULL);
+ info.may_disable = system->management_policy()->ExtensionMayModifySettings(
+ source_extension, &extension, nullptr);
info.is_app = extension.is_app();
if (info.is_app) {
if (extension.is_legacy_packaged_app())
@@ -144,8 +146,8 @@ management::ExtensionInfo CreateExtensionInfo(
}
info.may_enable = std::make_unique<bool>(
- system->management_policy()->UserMayModifySettings(&extension,
- nullptr) &&
+ system->management_policy()->ExtensionMayModifySettings(
+ source_extension, &extension, nullptr) &&
!system->management_policy()->MustRemainDisabled(&extension, nullptr,
nullptr));
}
@@ -257,7 +259,8 @@ management::ExtensionInfo CreateExtensionInfo(
return info;
}
-void AddExtensionInfo(const ExtensionSet& extensions,
+void AddExtensionInfo(const Extension* source_extension,
+ const ExtensionSet& extensions,
ExtensionInfoList* extension_list,
content::BrowserContext* context) {
for (ExtensionSet::const_iterator iter = extensions.begin();
@@ -267,7 +270,8 @@ void AddExtensionInfo(const ExtensionSet& extensions,
if (!extension.ShouldExposeViaManagementAPI())
continue;
- extension_list->push_back(CreateExtensionInfo(extension, context));
+ extension_list->push_back(
+ CreateExtensionInfo(source_extension, extension, context));
}
}
@@ -277,11 +281,11 @@ ExtensionFunction::ResponseAction ManagementGetAllFunction::Run() {
ExtensionInfoList extensions;
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
- AddExtensionInfo(registry->enabled_extensions(), &extensions,
+ AddExtensionInfo(extension(), registry->enabled_extensions(), &extensions,
browser_context());
- AddExtensionInfo(registry->disabled_extensions(), &extensions,
+ AddExtensionInfo(extension(), registry->disabled_extensions(), &extensions,
browser_context());
- AddExtensionInfo(registry->terminated_extensions(), &extensions,
+ AddExtensionInfo(extension(), registry->terminated_extensions(), &extensions,
browser_context());
return RespondNow(
@@ -294,18 +298,18 @@ ExtensionFunction::ResponseAction ManagementGetFunction::Run() {
EXTENSION_FUNCTION_VALIDATE(params.get());
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
- const Extension* extension =
+ const Extension* target_extension =
registry->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING);
- if (!extension)
+ if (!target_extension)
return RespondNow(Error(keys::kNoExtensionError, params->id));
return RespondNow(ArgumentList(management::Get::Results::Create(
- CreateExtensionInfo(*extension, browser_context()))));
+ CreateExtensionInfo(extension(), *target_extension, browser_context()))));
}
ExtensionFunction::ResponseAction ManagementGetSelfFunction::Run() {
return RespondNow(ArgumentList(management::Get::Results::Create(
- CreateExtensionInfo(*extension_, browser_context()))));
+ CreateExtensionInfo(extension(), *extension_, browser_context()))));
}
ExtensionFunction::ResponseAction
@@ -436,8 +440,8 @@ ExtensionFunction::ResponseAction ManagementSetEnabledFunction::Run() {
bool enabled = params->enabled;
const ManagementPolicy* policy =
ExtensionSystem::Get(browser_context())->management_policy();
- if (!policy->UserMayModifySettings(target_extension, nullptr) ||
- (!enabled && policy->MustRemainEnabled(target_extension, nullptr)) ||
+ if (!policy->ExtensionMayModifySettings(extension(), target_extension,
+ nullptr) ||
(enabled &&
policy->MustRemainDisabled(target_extension, nullptr, nullptr))) {
return RespondNow(Error(keys::kUserCantModifyError, extension_id_));
@@ -471,8 +475,11 @@ ExtensionFunction::ResponseAction ManagementSetEnabledFunction::Run() {
}
delegate->EnableExtension(browser_context(), extension_id_);
} else if (currently_enabled && !params->enabled) {
- delegate->DisableExtension(browser_context(), extension_id_,
- disable_reason::DISABLE_USER_ACTION);
+ delegate->DisableExtension(
+ browser_context(), extension(), extension_id_,
+ Manifest::IsPolicyLocation(target_extension->location())
+ ? disable_reason::DISABLE_BLOCKED_BY_POLICY
+ : disable_reason::DISABLE_USER_ACTION);
}
return RespondNow(NoArguments());
@@ -769,9 +776,10 @@ void ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp(
const Extension* extension,
const WebApplicationInfo& web_app_info) {
ResponseValue response =
- extension ? ArgumentList(management::GenerateAppForLink::Results::Create(
- CreateExtensionInfo(*extension, browser_context())))
- : Error(keys::kGenerateAppForLinkInstallError);
+ extension
+ ? ArgumentList(management::GenerateAppForLink::Results::Create(
+ CreateExtensionInfo(nullptr, *extension, browser_context())))
+ : Error(keys::kGenerateAppForLinkInstallError);
Respond(std::move(response));
Release(); // Balanced in Run().
}
@@ -859,7 +867,8 @@ void ManagementEventRouter::BroadcastEvent(
if (event_name == management::OnUninstalled::kEventName) {
args->AppendString(extension->id());
} else {
- args->Append(CreateExtensionInfo(*extension, browser_context_).ToValue());
+ args->Append(
+ CreateExtensionInfo(nullptr, *extension, browser_context_).ToValue());
}
EventRouter::Get(browser_context_)
diff --git a/chromium/extensions/browser/api/management/management_api_delegate.h b/chromium/extensions/browser/api/management/management_api_delegate.h
index 7c5e0f70dc4..13a46e53765 100644
--- a/chromium/extensions/browser/api/management/management_api_delegate.h
+++ b/chromium/extensions/browser/api/management/management_api_delegate.h
@@ -87,9 +87,11 @@ class ManagementAPIDelegate {
virtual void EnableExtension(content::BrowserContext* context,
const std::string& extension_id) const = 0;
- // Disables the extension identified by |extension_id|.
+ // Disables the extension identified by |extension_id|. |source_extension| (if
+ // specified) is the extension that originated the request.
virtual void DisableExtension(
content::BrowserContext* context,
+ const Extension* source_extension,
const std::string& extension_id,
disable_reason::DisableReason disable_reason) const = 0;
diff --git a/chromium/extensions/browser/api/media_perception_private/media_perception_api_delegate.h b/chromium/extensions/browser/api/media_perception_private/media_perception_api_delegate.h
index a8db42327c4..b31f7150658 100644
--- a/chromium/extensions/browser/api/media_perception_private/media_perception_api_delegate.h
+++ b/chromium/extensions/browser/api/media_perception_private/media_perception_api_delegate.h
@@ -14,10 +14,9 @@ namespace extensions {
class MediaPerceptionAPIDelegate {
public:
// Callback for loading a CrOS component. |mount_point| will contain a path to
- // the loaded component, if installation succeeded. If the component failed to
- // install, |mount_point| will be empty.
+ // the loaded component, if |success| is true (installation succeeded).
using LoadCrOSComponentCallback =
- base::OnceCallback<void(const base::FilePath& mount_point)>;
+ base::OnceCallback<void(bool success, const base::FilePath& mount_point)>;
virtual ~MediaPerceptionAPIDelegate() {}
diff --git a/chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.cc b/chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
index 7864742b44f..700c923391f 100644
--- a/chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
+++ b/chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
@@ -137,8 +137,9 @@ void MediaPerceptionAPIManager::SetAnalyticsComponent(
void MediaPerceptionAPIManager::LoadComponentCallback(
APISetAnalyticsComponentCallback callback,
+ bool success,
const base::FilePath& mount_point) {
- if (mount_point.empty()) {
+ if (!success) {
std::move(callback).Run(GetFailedToInstallComponentState());
return;
}
diff --git a/chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.h b/chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.h
index c3e05f055c5..f0f88473b0b 100644
--- a/chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.h
+++ b/chromium/extensions/browser/api/media_perception_private/media_perception_api_manager.h
@@ -98,6 +98,7 @@ class MediaPerceptionAPIManager
// Callback with the mount point for a loaded component.
void LoadComponentCallback(APISetAnalyticsComponentCallback callback,
+ bool success,
const base::FilePath& mount_point);
bool ComponentIsLoaded();
diff --git a/chromium/extensions/browser/api/media_perception_private/media_perception_private_api.cc b/chromium/extensions/browser/api/media_perception_private/media_perception_private_api.cc
index b5295259e0b..f9f95881cf1 100644
--- a/chromium/extensions/browser/api/media_perception_private/media_perception_private_api.cc
+++ b/chromium/extensions/browser/api/media_perception_private/media_perception_private_api.cc
@@ -130,4 +130,15 @@ void MediaPerceptionPrivateSetAnalyticsComponentFunction::
Respond(OneArgument(component_state.ToValue()));
}
+MediaPerceptionPrivateSetComponentProcessStateFunction::
+ MediaPerceptionPrivateSetComponentProcessStateFunction() = default;
+
+MediaPerceptionPrivateSetComponentProcessStateFunction::
+ ~MediaPerceptionPrivateSetComponentProcessStateFunction() = default;
+
+ExtensionFunction::ResponseAction
+MediaPerceptionPrivateSetComponentProcessStateFunction::Run() {
+ return RespondNow(Error("Not implemented."));
+}
+
} // namespace extensions
diff --git a/chromium/extensions/browser/api/media_perception_private/media_perception_private_api.h b/chromium/extensions/browser/api/media_perception_private/media_perception_private_api.h
index 8d8bfb580e4..8c62bdb35e1 100644
--- a/chromium/extensions/browser/api/media_perception_private/media_perception_private_api.h
+++ b/chromium/extensions/browser/api/media_perception_private/media_perception_private_api.h
@@ -86,6 +86,23 @@ class MediaPerceptionPrivateSetAnalyticsComponentFunction
DISALLOW_COPY_AND_ASSIGN(MediaPerceptionPrivateSetAnalyticsComponentFunction);
};
+class MediaPerceptionPrivateSetComponentProcessStateFunction
+ : public UIThreadExtensionFunction {
+ public:
+ MediaPerceptionPrivateSetComponentProcessStateFunction();
+ DECLARE_EXTENSION_FUNCTION("mediaPerceptionPrivate.setComponentProcessState",
+ MEDIAPERCEPTIONPRIVATE_SETCOMPONENTPROCESSSTATE);
+
+ private:
+ ~MediaPerceptionPrivateSetComponentProcessStateFunction() override;
+
+ // ExtensionFunction:
+ ResponseAction Run() override;
+
+ DISALLOW_COPY_AND_ASSIGN(
+ MediaPerceptionPrivateSetComponentProcessStateFunction);
+};
+
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_MEDIA_PERCEPTION_PRIVATE_MEDIA_PERCEPTION_PRIVATE_API_H_
diff --git a/chromium/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc b/chromium/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc
index 9329523eef2..98e722f2c12 100644
--- a/chromium/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc
+++ b/chromium/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc
@@ -35,15 +35,16 @@ class TestMediaPerceptionAPIDelegate : public MediaPerceptionAPIDelegate {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
- std::move(load_callback),
+ std::move(load_callback), true,
base::FilePath("/run/imageloader/rtanalytics-light/1.0")));
return;
}
- // Firing callback with empty string indicates that the installation of the
+ // Firing callback with false indicates that the installation of the
// component failed.
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(load_callback), base::FilePath()));
+ FROM_HERE,
+ base::BindOnce(std::move(load_callback), false, base::FilePath()));
}
};
diff --git a/chromium/extensions/browser/api/messaging/message_property_provider.cc b/chromium/extensions/browser/api/messaging/message_property_provider.cc
index fee4361a8b0..bb1e14c8e5f 100644
--- a/chromium/extensions/browser/api/messaging/message_property_provider.cc
+++ b/chromium/extensions/browser/api/messaging/message_property_provider.cc
@@ -62,12 +62,19 @@ void MessagePropertyProvider::GetChannelIDOnIOThread(
const std::string& host,
const ChannelIDCallback& reply) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- net::ChannelIDService* channel_id_service =
- request_context_getter->GetURLRequestContext()->channel_id_service();
+ const net::HttpNetworkSession::Params* network_params =
+ request_context_getter->GetURLRequestContext()->GetNetworkSessionParams();
GetChannelIDOutput* output = new GetChannelIDOutput();
net::CompletionCallback net_completion_callback =
base::Bind(&MessagePropertyProvider::GotChannelID, original_task_runner,
base::Owned(output), reply);
+ if (!network_params->enable_token_binding &&
+ !network_params->enable_channel_id) {
+ GotChannelID(original_task_runner, output, reply, net::ERR_FILE_NOT_FOUND);
+ return;
+ }
+ net::ChannelIDService* channel_id_service =
+ request_context_getter->GetURLRequestContext()->channel_id_service();
int status = channel_id_service->GetChannelID(
host, &output->channel_id_key, net_completion_callback, &output->request);
if (status == net::ERR_IO_PENDING)
diff --git a/chromium/extensions/browser/api/mime_handler_private/mime_handler_private.cc b/chromium/extensions/browser/api/mime_handler_private/mime_handler_private.cc
index 3704ae0fb4b..09c6ff94b26 100644
--- a/chromium/extensions/browser/api/mime_handler_private/mime_handler_private.cc
+++ b/chromium/extensions/browser/api/mime_handler_private/mime_handler_private.cc
@@ -4,9 +4,9 @@
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
-#include <unordered_map>
#include <utility>
+#include "base/containers/flat_map.h"
#include "base/strings/string_util.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/browser/stream_info.h"
@@ -19,9 +19,9 @@
namespace extensions {
namespace {
-std::unordered_map<std::string, std::string> CreateResponseHeadersMap(
+base::flat_map<std::string, std::string> CreateResponseHeadersMap(
const net::HttpResponseHeaders* headers) {
- std::unordered_map<std::string, std::string> result;
+ base::flat_map<std::string, std::string> result;
if (!headers)
return result;
diff --git a/chromium/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc b/chromium/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc
index 58a2402e9d4..d3daa37da48 100644
--- a/chromium/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc
+++ b/chromium/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc
@@ -9,7 +9,6 @@
#include "base/callback.h"
#include "base/json/json_string_value_serializer.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
@@ -189,40 +188,44 @@ class NetworkingPrivateApiTest : public ApiUnitTest {
*device_policy_onc, base::DictionaryValue());
}
+ void SetDeviceProperty(const std::string& device_path,
+ const std::string& name,
+ const base::Value& value) {
+ device_test_->SetDeviceProperty(device_path, name, value,
+ /*notify_changed=*/false);
+ }
+
void SetUpCellular() {
// Add a Cellular GSM Device.
device_test_->AddDevice(kCellularDevicePath, shill::kTypeCellular,
"stub_cellular_device1");
- device_test_->SetDeviceProperty(kCellularDevicePath,
- shill::kCarrierProperty,
- base::Value("Cellular1_Carrier"));
+ SetDeviceProperty(kCellularDevicePath, shill::kCarrierProperty,
+ base::Value("Cellular1_Carrier"));
base::DictionaryValue home_provider;
home_provider.SetString("name", "Cellular1_Provider");
home_provider.SetString("code", "000000");
home_provider.SetString("country", "us");
- device_test_->SetDeviceProperty(
- kCellularDevicePath, shill::kHomeProviderProperty, home_provider);
- device_test_->SetDeviceProperty(kCellularDevicePath,
- shill::kTechnologyFamilyProperty,
- base::Value(shill::kNetworkTechnologyGsm));
- device_test_->SetDeviceProperty(kCellularDevicePath, shill::kMeidProperty,
- base::Value("test_meid"));
- device_test_->SetDeviceProperty(kCellularDevicePath, shill::kImeiProperty,
- base::Value("test_imei"));
- device_test_->SetDeviceProperty(kCellularDevicePath, shill::kIccidProperty,
- base::Value("test_iccid"));
- device_test_->SetDeviceProperty(kCellularDevicePath, shill::kImsiProperty,
- base::Value("test_imsi"));
- device_test_->SetDeviceProperty(kCellularDevicePath, shill::kEsnProperty,
- base::Value("test_esn"));
- device_test_->SetDeviceProperty(kCellularDevicePath, shill::kMdnProperty,
- base::Value("test_mdn"));
- device_test_->SetDeviceProperty(kCellularDevicePath, shill::kMinProperty,
- base::Value("test_min"));
- device_test_->SetDeviceProperty(kCellularDevicePath,
- shill::kModelIdProperty,
- base::Value("test_model_id"));
+ SetDeviceProperty(kCellularDevicePath, shill::kHomeProviderProperty,
+ home_provider);
+ SetDeviceProperty(kCellularDevicePath, shill::kTechnologyFamilyProperty,
+ base::Value(shill::kNetworkTechnologyGsm));
+ SetDeviceProperty(kCellularDevicePath, shill::kMeidProperty,
+ base::Value("test_meid"));
+ SetDeviceProperty(kCellularDevicePath, shill::kImeiProperty,
+ base::Value("test_imei"));
+ SetDeviceProperty(kCellularDevicePath, shill::kIccidProperty,
+ base::Value("test_iccid"));
+ SetDeviceProperty(kCellularDevicePath, shill::kImsiProperty,
+ base::Value("test_imsi"));
+ SetDeviceProperty(kCellularDevicePath, shill::kEsnProperty,
+ base::Value("test_esn"));
+ SetDeviceProperty(kCellularDevicePath, shill::kMdnProperty,
+ base::Value("test_mdn"));
+ SetDeviceProperty(kCellularDevicePath, shill::kMinProperty,
+ base::Value("test_min"));
+ SetDeviceProperty(kCellularDevicePath, shill::kModelIdProperty,
+ base::Value("test_model_id"));
std::unique_ptr<base::DictionaryValue> apn =
DictionaryBuilder()
.Set(shill::kApnProperty, "test-apn")
@@ -231,8 +234,8 @@ class NetworkingPrivateApiTest : public ApiUnitTest {
.Build();
std::unique_ptr<base::ListValue> apn_list =
ListBuilder().Append(apn->CreateDeepCopy()).Build();
- device_test_->SetDeviceProperty(kCellularDevicePath,
- shill::kCellularApnListProperty, *apn_list);
+ SetDeviceProperty(kCellularDevicePath, shill::kCellularApnListProperty,
+ *apn_list);
service_test_->AddService(kCellularServicePath, kCellularGuid,
kCellularName, shill::kTypeCellular,
@@ -1081,8 +1084,8 @@ TEST_F(NetworkingPrivateApiTest, GetCellularProperties) {
DictionaryBuilder()
.Set("Cellular",
DictionaryBuilder()
- .SetBoolean("AllowRoaming", false)
- .SetBoolean("AutoConnect", true)
+ .Set("AllowRoaming", false)
+ .Set("AutoConnect", true)
.Set("Carrier", "Cellular1_Carrier")
.Set("Family", "GSM")
.Set("HomeProvider", DictionaryBuilder()
@@ -1093,7 +1096,7 @@ TEST_F(NetworkingPrivateApiTest, GetCellularProperties) {
.Set("ModelID", "test_model_id")
.Set("NetworkTechnology", "GSM")
.Set("RoamingState", "Home")
- .SetBoolean("Scanning", false)
+ .Set("Scanning", false)
.Build())
.Set("ConnectionState", "Connected")
.Set("GUID", "cellular_guid")
@@ -1128,8 +1131,8 @@ TEST_F(NetworkingPrivateApiTest, GetCellularPropertiesFromWebUi) {
DictionaryBuilder()
.Set("Cellular",
DictionaryBuilder()
- .SetBoolean("AllowRoaming", false)
- .SetBoolean("AutoConnect", true)
+ .Set("AllowRoaming", false)
+ .Set("AutoConnect", true)
.Set("Carrier", "Cellular1_Carrier")
.Set("ESN", "test_esn")
.Set("Family", "GSM")
@@ -1147,7 +1150,7 @@ TEST_F(NetworkingPrivateApiTest, GetCellularPropertiesFromWebUi) {
.Set("MIN", "test_min")
.Set("NetworkTechnology", "GSM")
.Set("RoamingState", "Home")
- .SetBoolean("Scanning", false)
+ .Set("Scanning", false)
.Set("APNList", ListBuilder()
.Append(expected_apn->CreateDeepCopy())
.Build())
diff --git a/chromium/extensions/browser/api/networking_private/networking_private_linux.h b/chromium/extensions/browser/api/networking_private/networking_private_linux.h
index 2a15c2619d4..171824f8481 100644
--- a/chromium/extensions/browser/api/networking_private/networking_private_linux.h
+++ b/chromium/extensions/browser/api/networking_private/networking_private_linux.h
@@ -11,7 +11,6 @@
#include <vector>
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/browser/api/networking_private/networking_private_delegate.h"
diff --git a/chromium/extensions/browser/api/printer_provider/printer_provider_apitest.cc b/chromium/extensions/browser/api/printer_provider/printer_provider_apitest.cc
index 2b5d573e9fb..eccef576b68 100644
--- a/chromium/extensions/browser/api/printer_provider/printer_provider_apitest.cc
+++ b/chromium/extensions/browser/api/printer_provider/printer_provider_apitest.cc
@@ -8,10 +8,6 @@
#include <vector>
#include "base/bind.h"
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
#include "base/json/json_string_value_serializer.h"
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
@@ -95,16 +91,11 @@ class PrinterProviderApiTest : public ShellApiTest {
public:
enum PrintRequestDataType {
PRINT_REQUEST_DATA_TYPE_NOT_SET,
- PRINT_REQUEST_DATA_TYPE_FILE,
- PRINT_REQUEST_DATA_TYPE_FILE_DELETED,
PRINT_REQUEST_DATA_TYPE_BYTES
};
PrinterProviderApiTest() {}
- ~PrinterProviderApiTest() override {
- base::ScopedAllowBlockingForTesting allow_blocking;
- ignore_result(data_dir_.Delete());
- }
+ ~PrinterProviderApiTest() override = default;
void StartGetPrintersRequest(
const PrinterProviderAPI::GetPrintersCallback& callback) {
@@ -152,29 +143,6 @@ class PrinterProviderApiTest : public ShellApiTest {
->DispatchPrintRequested(job, std::move(callback));
}
- bool StartPrintRequestUsingFileInfo(
- const std::string& extension_id,
- PrinterProviderAPI::PrintCallback callback) {
- PrinterProviderPrintJob job;
-
- const char kBytes[] = {'b', 'y', 't', 'e', 's'};
- if (!CreateTempFileWithContents(kBytes, static_cast<int>(arraysize(kBytes)),
- &job.document_path, &job.file_info)) {
- ADD_FAILURE() << "Failed to create test file.";
- return false;
- }
-
- job.printer_id = extension_id + ":printer_id";
- job.job_title = base::ASCIIToUTF16("Print job");
- job.ticket_json = "{}";
- job.content_type = "image/pwg-raster";
-
- PrinterProviderAPIFactory::GetInstance()
- ->GetForBrowserContext(browser_context())
- ->DispatchPrintRequested(job, std::move(callback));
- return true;
- }
-
void StartCapabilityRequest(
const std::string& extension_id,
PrinterProviderAPI::GetCapabilityCallback callback) {
@@ -240,17 +208,6 @@ class PrinterProviderApiTest : public ShellApiTest {
case PRINT_REQUEST_DATA_TYPE_NOT_SET:
StartPrintRequestWithNoData(extension_id, std::move(callback));
break;
- case PRINT_REQUEST_DATA_TYPE_FILE:
- ASSERT_TRUE(
- StartPrintRequestUsingFileInfo(extension_id, std::move(callback)));
- break;
- case PRINT_REQUEST_DATA_TYPE_FILE_DELETED: {
- ASSERT_TRUE(
- StartPrintRequestUsingFileInfo(extension_id, std::move(callback)));
- base::ScopedAllowBlockingForTesting allow_blocking;
- ASSERT_TRUE(data_dir_.Delete());
- break;
- }
case PRINT_REQUEST_DATA_TYPE_BYTES:
StartPrintRequestUsingDocumentBytes(extension_id, std::move(callback));
break;
@@ -352,27 +309,6 @@ class PrinterProviderApiTest : public ShellApiTest {
device::MockUsbService usb_service_;
private:
- // Initializes |data_dir_| if needed and creates a file in it containing
- // provided data.
- bool CreateTempFileWithContents(const char* data,
- int size,
- base::FilePath* path,
- base::File::Info* file_info) {
- base::ScopedAllowBlockingForTesting allow_blocking;
- if (!data_dir_.IsValid() && !data_dir_.CreateUniqueTempDir())
- return false;
-
- *path = data_dir_.GetPath().AppendASCII("data.pwg");
- int written = base::WriteFile(*path, data, size);
- if (written != size)
- return false;
- if (!base::GetFileInfo(*path, file_info))
- return false;
- return true;
- }
-
- base::ScopedTempDir data_dir_;
-
DISALLOW_COPY_AND_ASSIGN(PrinterProviderApiTest);
};
@@ -386,16 +322,6 @@ IN_PROC_BROWSER_TEST_F(PrinterProviderApiTest, MAYBE_PrintJobSuccess) {
RunPrintRequestTestApp("OK", PRINT_REQUEST_DATA_TYPE_BYTES, "OK");
}
-IN_PROC_BROWSER_TEST_F(PrinterProviderApiTest, PrintJobWithFileSuccess) {
- RunPrintRequestTestApp("OK", PRINT_REQUEST_DATA_TYPE_FILE, "OK");
-}
-
-IN_PROC_BROWSER_TEST_F(PrinterProviderApiTest,
- PrintJobWithFile_FileDeletedBeforeDispatch) {
- RunPrintRequestTestApp("OK", PRINT_REQUEST_DATA_TYPE_FILE_DELETED,
- "INVALID_DATA");
-}
-
IN_PROC_BROWSER_TEST_F(PrinterProviderApiTest, PrintJobAsyncSuccess) {
RunPrintRequestTestApp("ASYNC_RESPONSE", PRINT_REQUEST_DATA_TYPE_BYTES, "OK");
}
diff --git a/chromium/extensions/browser/api/printer_provider/printer_provider_print_job.h b/chromium/extensions/browser/api/printer_provider/printer_provider_print_job.h
index a9f4b4b5555..682e150c44b 100644
--- a/chromium/extensions/browser/api/printer_provider/printer_provider_print_job.h
+++ b/chromium/extensions/browser/api/printer_provider/printer_provider_print_job.h
@@ -7,8 +7,6 @@
#include <string>
-#include "base/files/file.h"
-#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string16.h"
@@ -17,9 +15,7 @@ namespace extensions {
// Struct describing print job that should be forwarded to an extension via
// chrome.printerProvider.onPrintRequested event.
-// TODO(tbarzic): This should probably be a class and have some methods, e.g.
-// whether the job is initialized and whether the data is described using a file
-// or bytes.
+// TODO(tbarzic): This should probably be a class and have some methods.
struct PrinterProviderPrintJob {
PrinterProviderPrintJob();
PrinterProviderPrintJob(const PrinterProviderPrintJob& other);
@@ -41,17 +37,8 @@ struct PrinterProviderPrintJob {
// Content type of the document that should be printed.
std::string content_type;
- // The document data that should be printed. Should be NULL if document data
- // is kept in a file.
+ // The document data that should be printed.
scoped_refptr<base::RefCountedMemory> document_bytes;
-
- // Path of the file which contains data to be printed. Should be set only if
- // |document_bytes| are NULL.
- base::FilePath document_path;
-
- // Information about the file which contains data to be printed. Should be
- // set only if |document_path| is set.
- base::File::Info file_info;
};
} // namespace extensions
diff --git a/chromium/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc b/chromium/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc
index 220f9d8a04b..3400e9d7083 100644
--- a/chromium/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc
+++ b/chromium/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc
@@ -194,25 +194,17 @@ PrinterProviderInternalGetPrintDataFunction::Run() {
if (!job)
return RespondNow(Error("Print request not found."));
- if (job->document_bytes.get()) {
- // |job->document_bytes| are passed to the callback to make sure the ref
- // counted memory does not go away before the memory backed blob is created.
- content::BrowserContext::CreateMemoryBackedBlob(
- browser_context(), job->document_bytes->front_as<char>(),
- job->document_bytes->size(), "",
- base::Bind(&PrinterProviderInternalGetPrintDataFunction::OnBlob, this,
- job->content_type, job->document_bytes->size(),
- job->document_bytes));
- } else if (!job->document_path.empty()) {
- content::BrowserContext::CreateFileBackedBlob(
- browser_context(), job->document_path, 0 /* offset */,
- job->file_info.size, job->file_info.last_modified,
- base::Bind(&PrinterProviderInternalGetPrintDataFunction::OnBlob, this,
- job->content_type, job->file_info.size,
- scoped_refptr<base::RefCountedMemory>()));
- } else {
+ if (!job->document_bytes)
return RespondNow(Error("Job data not set"));
- }
+
+ // |job->document_bytes| are passed to the callback to make sure the ref
+ // counted memory does not go away before the memory backed blob is created.
+ content::BrowserContext::CreateMemoryBackedBlob(
+ browser_context(), job->document_bytes->front_as<char>(),
+ job->document_bytes->size(), "",
+ base::BindOnce(&PrinterProviderInternalGetPrintDataFunction::OnBlob, this,
+ job->content_type, job->document_bytes->size(),
+ job->document_bytes));
return RespondLater();
}
diff --git a/chromium/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc b/chromium/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc
index 3431997188d..884e1c7840d 100644
--- a/chromium/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc
+++ b/chromium/extensions/browser/api/sockets_udp/sockets_udp_apitest.cc
@@ -4,6 +4,7 @@
#include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "extensions/browser/api/dns/host_resolver_wrapper.h"
#include "extensions/browser/api/dns/mock_host_resolver_creator.h"
#include "extensions/browser/api/sockets_udp/sockets_udp_api.h"
@@ -71,7 +72,15 @@ IN_PROC_BROWSER_TEST_F(SocketsUdpApiTest, SocketsUdpCreateGood) {
ASSERT_TRUE(socketId > 0);
}
-IN_PROC_BROWSER_TEST_F(SocketsUdpApiTest, SocketsUdpExtension) {
+// Disable SocketsUdpExtension on Mac ASAN due to time out.
+// See https://crbug.com/844402
+#if defined(OS_MACOSX) && defined(ADDRESS_SANITIZER)
+#define MAYBE_SocketsUdpExtension DISABLED_SocketsUdpExtension
+#else
+#define MAYBE_SocketsUdpExtension SocketsUdpExtension
+#endif
+
+IN_PROC_BROWSER_TEST_F(SocketsUdpApiTest, MAYBE_SocketsUdpExtension) {
std::unique_ptr<net::SpawnedTestServer> test_server(
new net::SpawnedTestServer(
net::SpawnedTestServer::TYPE_UDP_ECHO,
diff --git a/chromium/extensions/browser/api/storage/settings_storage_quota_enforcer.cc b/chromium/extensions/browser/api/storage/settings_storage_quota_enforcer.cc
index 1b3603cec5e..30356b0e7f7 100644
--- a/chromium/extensions/browser/api/storage/settings_storage_quota_enforcer.cc
+++ b/chromium/extensions/browser/api/storage/settings_storage_quota_enforcer.cc
@@ -8,7 +8,6 @@
#include "base/bind.h"
#include "base/json/json_writer.h"
-#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "extensions/common/extension_api.h"
diff --git a/chromium/extensions/browser/api/system_display/display_info_provider.cc b/chromium/extensions/browser/api/system_display/display_info_provider.cc
index a1fb62f2951..e30270b70dc 100644
--- a/chromium/extensions/browser/api/system_display/display_info_provider.cc
+++ b/chromium/extensions/browser/api/system_display/display_info_provider.cc
@@ -48,15 +48,9 @@ DisplayInfoProvider* DisplayInfoProvider::Get() {
// static
void DisplayInfoProvider::InitializeForTesting(
DisplayInfoProvider* display_info_provider) {
- DCHECK(display_info_provider);
- g_display_info_provider = display_info_provider;
-}
-
-// static
-void DisplayInfoProvider::ResetForTesting() {
if (g_display_info_provider)
delete g_display_info_provider;
- g_display_info_provider = nullptr;
+ g_display_info_provider = display_info_provider;
}
// static
@@ -150,10 +144,6 @@ void DisplayInfoProvider::ShowNativeTouchCalibration(const std::string& id,
NOTREACHED(); // Implemented on Chrome OS only in override.
}
-bool DisplayInfoProvider::IsNativeTouchCalibrationActive() {
- return false;
-}
-
bool DisplayInfoProvider::StartCustomTouchCalibration(const std::string& id) {
NOTREACHED(); // Implemented on Chrome OS only in override.
return false;
@@ -171,10 +161,6 @@ bool DisplayInfoProvider::ClearTouchCalibration(const std::string& id) {
return false;
}
-bool DisplayInfoProvider::IsCustomTouchCalibrationActive() {
- return false;
-}
-
void DisplayInfoProvider::SetMirrorMode(
const api::system_display::MirrorModeInfo& info,
ErrorCallback callback) {
diff --git a/chromium/extensions/browser/api/system_display/display_info_provider.h b/chromium/extensions/browser/api/system_display/display_info_provider.h
index 3b5f72776d9..492ab33eed3 100644
--- a/chromium/extensions/browser/api/system_display/display_info_provider.h
+++ b/chromium/extensions/browser/api/system_display/display_info_provider.h
@@ -96,8 +96,6 @@ class DisplayInfoProvider {
// calibration has completed.
virtual void ShowNativeTouchCalibration(const std::string& id,
ErrorCallback callback);
- // Returns true if native touch calibration is in progress.
- virtual bool IsNativeTouchCalibrationActive();
// These methods implement custom touch calibration. They will return false
// if |id| is invalid or if the operation is invalid.
@@ -106,8 +104,6 @@ class DisplayInfoProvider {
const api::system_display::TouchCalibrationPairQuad& pairs,
const api::system_display::Bounds& bounds);
virtual bool ClearTouchCalibration(const std::string& id);
- // Returns true if custom touch calibration is in progress.
- virtual bool IsCustomTouchCalibrationActive();
// Sets the display mode to the specified mirror mode. See system_display.idl.
// |info|: Mirror mode properties to apply.
diff --git a/chromium/extensions/browser/api/system_display/system_display_api.cc b/chromium/extensions/browser/api/system_display/system_display_api.cc
index 150bbf16642..58528bfd3d8 100644
--- a/chromium/extensions/browser/api/system_display/system_display_api.cc
+++ b/chromium/extensions/browser/api/system_display/system_display_api.cc
@@ -317,13 +317,6 @@ ExtensionFunction::ResponseAction
SystemDisplayShowNativeTouchCalibrationFunction::Run() {
std::unique_ptr<display::ShowNativeTouchCalibration::Params> params(
display::ShowNativeTouchCalibration::Params::Create(*args_));
-
- if (DisplayInfoProvider::Get()->IsNativeTouchCalibrationActive())
- return RespondNow(Error("Native touch calibration already active."));
-
- if (DisplayInfoProvider::Get()->IsCustomTouchCalibrationActive())
- return RespondNow(Error("Custom touch calibration is active."));
-
DisplayInfoProvider::Get()->ShowNativeTouchCalibration(
params->id,
base::BindOnce(&SystemDisplayShowNativeTouchCalibrationFunction::
@@ -342,10 +335,6 @@ ExtensionFunction::ResponseAction
SystemDisplayStartCustomTouchCalibrationFunction::Run() {
std::unique_ptr<display::StartCustomTouchCalibration::Params> params(
display::StartCustomTouchCalibration::Params::Create(*args_));
-
- if (DisplayInfoProvider::Get()->IsNativeTouchCalibrationActive())
- return RespondNow(Error("Native touch calibration is active."));
-
if (!DisplayInfoProvider::Get()->StartCustomTouchCalibration(params->id)) {
return RespondNow(
Error("Custom touch calibration not available for display."));
@@ -357,13 +346,6 @@ ExtensionFunction::ResponseAction
SystemDisplayCompleteCustomTouchCalibrationFunction::Run() {
std::unique_ptr<display::CompleteCustomTouchCalibration::Params> params(
display::CompleteCustomTouchCalibration::Params::Create(*args_));
-
- if (DisplayInfoProvider::Get()->IsNativeTouchCalibrationActive())
- return RespondNow(Error("Native touch calibration is active."));
-
- if (!DisplayInfoProvider::Get()->IsCustomTouchCalibrationActive())
- return RespondNow(Error("Custom touch calibration is not active."));
-
if (!DisplayInfoProvider::Get()->CompleteCustomTouchCalibration(
params->pairs, params->bounds)) {
return RespondNow(Error("Custom touch calibration completion failed."));
@@ -375,14 +357,6 @@ ExtensionFunction::ResponseAction
SystemDisplayClearTouchCalibrationFunction::Run() {
std::unique_ptr<display::ClearTouchCalibration::Params> params(
display::ClearTouchCalibration::Params::Create(*args_));
-
- if (DisplayInfoProvider::Get()->IsNativeTouchCalibrationActive())
- return RespondNow(Error("Native touch calibration is active."));
-
- // TODO(malaykeshav@): Document and test whether
- // IsCustomTouchCalibrationActive() should be true or false and enforce in
- // DisplayInfoProvider::ClearTouchCalibration.
-
if (!DisplayInfoProvider::Get()->ClearTouchCalibration(params->id))
return RespondNow(Error("Failed to clear custom touch calibration data."));
return RespondNow(NoArguments());
diff --git a/chromium/extensions/browser/api/usb/usb_api.cc b/chromium/extensions/browser/api/usb/usb_api.cc
index fb8e4f0e269..eb6ddd6d9b7 100644
--- a/chromium/extensions/browser/api/usb/usb_api.cc
+++ b/chromium/extensions/browser/api/usb/usb_api.cc
@@ -26,6 +26,7 @@
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/api/usb/usb_device_resource.h"
#include "extensions/browser/api/usb/usb_guid_map.h"
+#include "extensions/browser/extension_function_constants.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/api/usb.h"
#include "extensions/common/permissions/permissions_data.h"
@@ -668,8 +669,14 @@ ExtensionFunction::ResponseAction UsbGetUserSelectedDevicesFunction::Run() {
filters.push_back(ConvertDeviceFilter(filter));
}
- prompt_ = ExtensionsAPIClient::Get()->CreateDevicePermissionsPrompt(
- GetAssociatedWebContents());
+ content::WebContents* web_contents = GetSenderWebContents();
+ if (!web_contents) {
+ return RespondNow(
+ Error(function_constants::kCouldNotFindSenderWebContents));
+ }
+
+ prompt_ =
+ ExtensionsAPIClient::Get()->CreateDevicePermissionsPrompt(web_contents);
if (!prompt_) {
return RespondNow(Error(kErrorNotSupported));
}
diff --git a/chromium/extensions/browser/api/usb/usb_manual_apitest.cc b/chromium/extensions/browser/api/usb/usb_manual_apitest.cc
index d28be9d390a..800e26f2826 100644
--- a/chromium/extensions/browser/api/usb/usb_manual_apitest.cc
+++ b/chromium/extensions/browser/api/usb/usb_manual_apitest.cc
@@ -5,11 +5,7 @@
#include "chrome/browser/extensions/api/permissions/permissions_api.h"
#include "chrome/browser/extensions/extension_apitest.h"
-namespace {
-
-class UsbManualApiTest : public ExtensionApiTest {};
-
-} // namespace
+using UsbManualApiTest = extensions::ExtensionApiTest;
IN_PROC_BROWSER_TEST_F(UsbManualApiTest, MANUAL_ListInterfaces) {
extensions::PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
diff --git a/chromium/extensions/browser/api/web_request/form_data_parser.cc b/chromium/extensions/browser/api/web_request/form_data_parser.cc
index f006684d015..aba2b4a6a1e 100644
--- a/chromium/extensions/browser/api/web_request/form_data_parser.cc
+++ b/chromium/extensions/browser/api/web_request/form_data_parser.cc
@@ -100,7 +100,6 @@ class FormDataParserUrlEncoded : public FormDataParser {
// Auxiliary constant for using RE2. Number of arguments for parsing
// name-value pairs (one for name, one for value).
static const size_t args_size_ = 2u;
- static const net::UnescapeRule::Type unescape_rules_;
re2::StringPiece source_;
bool source_set_;
@@ -369,12 +368,6 @@ std::unique_ptr<FormDataParser> FormDataParser::CreateFromContentTypeHeader(
FormDataParser::FormDataParser() {}
-const net::UnescapeRule::Type FormDataParserUrlEncoded::unescape_rules_ =
- net::UnescapeRule::PATH_SEPARATORS |
- net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
- net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS | net::UnescapeRule::SPACES |
- net::UnescapeRule::REPLACE_PLUS_WITH_SPACE;
-
FormDataParserUrlEncoded::FormDataParserUrlEncoded()
: source_(NULL),
source_set_(false),
@@ -399,9 +392,12 @@ bool FormDataParserUrlEncoded::GetNextNameValue(Result* result) {
bool success = RE2::ConsumeN(&source_, pattern(), args_, args_size_);
if (success) {
- result->set_name(net::UnescapeURLComponent(name_, unescape_rules_));
+ const net::UnescapeRule::Type kUnescapeRules =
+ net::UnescapeRule::REPLACE_PLUS_WITH_SPACE;
+
+ result->set_name(net::UnescapeBinaryURLComponent(name_, kUnescapeRules));
const std::string unescaped_value =
- net::UnescapeURLComponent(value_, unescape_rules_);
+ net::UnescapeBinaryURLComponent(value_, kUnescapeRules);
const base::StringPiece unescaped_data(unescaped_value.data(),
unescaped_value.length());
if (base::IsStringUTF8(unescaped_data)) {
@@ -550,11 +546,7 @@ bool FormDataParserMultipart::GetNextNameValue(Result* result) {
return_value = FinishReadingPart(value_assigned ? nullptr : &value);
}
- std::string unescaped_name = net::UnescapeURLComponent(
- name.as_string(),
- net::UnescapeRule::PATH_SEPARATORS |
- net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
- net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS);
+ std::string unescaped_name = net::UnescapeBinaryURLComponent(name);
result->set_name(unescaped_name);
if (value_assigned) {
// Hold filename as value.
diff --git a/chromium/extensions/browser/api/web_request/upload_data_presenter.cc b/chromium/extensions/browser/api/web_request/upload_data_presenter.cc
index 022abc08ac3..9ded224b58d 100644
--- a/chromium/extensions/browser/api/web_request/upload_data_presenter.cc
+++ b/chromium/extensions/browser/api/web_request/upload_data_presenter.cc
@@ -8,6 +8,7 @@
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
+#include "base/numerics/checked_math.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "extensions/browser/api/web_request/form_data_parser.h"
@@ -106,7 +107,39 @@ void ParsedDataPresenter::FeedBytes(base::StringPiece bytes) {
if (!success_)
return;
- if (!parser_->SetSource(bytes)) {
+ if (pending_bytes_.empty()) {
+ // First data chunk: track externally.
+ DCHECK(buffer_.empty());
+
+ pending_bytes_ = bytes;
+ return;
+ }
+
+ // Pending data is either tracked externally or is located in our buffer.
+ DCHECK(buffer_.empty() || pending_bytes_.data() == buffer_.data());
+ DCHECK(buffer_.empty() || pending_bytes_.size() == buffer_.size());
+
+ const auto safe_size = base::CheckAdd(pending_bytes_.size(), bytes.size());
+ if (!safe_size.IsValid()) {
+ Abort();
+ return;
+ }
+
+ buffer_.reserve(safe_size.ValueOrDie());
+ if (buffer_.empty()) {
+ // Second data chunk: copy pending external data to our internal buffer.
+ buffer_.append(pending_bytes_.data(), pending_bytes_.size());
+ }
+
+ buffer_.append(bytes.data(), bytes.size());
+ pending_bytes_.set(buffer_.data(), buffer_.size());
+}
+
+void ParsedDataPresenter::CommitPendingBytes() {
+ if (!success_ || pending_bytes_.empty())
+ return;
+
+ if (!parser_->SetSource(pending_bytes_)) {
Abort();
return;
}
@@ -116,11 +149,17 @@ void ParsedDataPresenter::FeedBytes(base::StringPiece bytes) {
base::Value* list = GetOrCreateList(dictionary_.get(), result.name());
list->GetList().emplace_back(result.take_value());
}
+
+ buffer_.clear();
+ pending_bytes_.clear();
}
-void ParsedDataPresenter::FeedFile(const base::FilePath& path) {}
+void ParsedDataPresenter::FeedFile(const base::FilePath&) {
+ CommitPendingBytes();
+}
bool ParsedDataPresenter::Succeeded() {
+ CommitPendingBytes();
if (success_ && !parser_->AllDataReadOK())
Abort();
return success_;
diff --git a/chromium/extensions/browser/api/web_request/upload_data_presenter.h b/chromium/extensions/browser/api/web_request/upload_data_presenter.h
index 98c0765dc59..3c9fa56b5bf 100644
--- a/chromium/extensions/browser/api/web_request/upload_data_presenter.h
+++ b/chromium/extensions/browser/api/web_request/upload_data_presenter.h
@@ -124,10 +124,17 @@ class ParsedDataPresenter : public UploadDataPresenter {
// Clears resources and the success flag.
void Abort();
+ // Flushes any pending data to the parser.
+ void CommitPendingBytes();
+
std::unique_ptr<FormDataParser> parser_;
bool success_;
std::unique_ptr<base::DictionaryValue> dictionary_;
+ // Buffered data (not yet commited to the parser).
+ base::StringPiece pending_bytes_;
+ std::string buffer_;
+
DISALLOW_COPY_AND_ASSIGN(ParsedDataPresenter);
};
diff --git a/chromium/extensions/browser/api/web_request/upload_data_presenter_unittest.cc b/chromium/extensions/browser/api/web_request/upload_data_presenter_unittest.cc
index 92f7afccca8..6716e11ac52 100644
--- a/chromium/extensions/browser/api/web_request/upload_data_presenter_unittest.cc
+++ b/chromium/extensions/browser/api/web_request/upload_data_presenter_unittest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/files/file_path.h"
#include "base/values.h"
#include "extensions/browser/api/web_request/upload_data_presenter.h"
#include "extensions/browser/api/web_request/web_request_api_constants.h"
@@ -81,4 +82,46 @@ TEST(WebRequestUploadDataPresenterTest, RawData) {
EXPECT_TRUE(result->Equals(&expected_list));
}
+TEST(WebRequestUploadDataPresenterTest, ParsedDataSegmented) {
+ // Input.
+ static constexpr char block1[] = "v1=FOO";
+ static constexpr char block2[] = "BAR&v2=BAZ";
+ static constexpr size_t block1_size = sizeof(block1) - 1;
+ static constexpr size_t block2_size = sizeof(block2) - 1;
+
+ // Expected output.
+ auto v1 = std::make_unique<base::ListValue>();
+ v1->AppendString("FOOBAR");
+ auto v2 = std::make_unique<base::ListValue>();
+ v2->AppendString("BAZ");
+
+ base::DictionaryValue expected_form;
+ expected_form.SetWithoutPathExpansion("v1", std::move(v1));
+ expected_form.SetWithoutPathExpansion("v2", std::move(v2));
+
+ {
+ // Consecutive data segments should be consolidated and parsed successfuly.
+ auto parsed_data_presenter = ParsedDataPresenter::CreateForTests();
+ ASSERT_TRUE(parsed_data_presenter.get());
+ parsed_data_presenter->FeedBytes(base::StringPiece(block1, block1_size));
+ parsed_data_presenter->FeedBytes(base::StringPiece(block2, block2_size));
+
+ EXPECT_TRUE(parsed_data_presenter->Succeeded());
+ auto result = parsed_data_presenter->Result();
+ ASSERT_TRUE(result);
+ EXPECT_EQ(*result, expected_form);
+ }
+
+ {
+ // Data segments separate by file inputs should not be consolidated.
+ auto parsed_data_presenter = ParsedDataPresenter::CreateForTests();
+ ASSERT_TRUE(parsed_data_presenter.get());
+ parsed_data_presenter->FeedBytes(base::StringPiece(block1, block1_size));
+ parsed_data_presenter->FeedFile(base::FilePath());
+ parsed_data_presenter->FeedBytes(base::StringPiece(block2, block2_size));
+
+ EXPECT_FALSE(parsed_data_presenter->Succeeded());
+ }
+}
+
} // namespace extensions
diff --git a/chromium/extensions/browser/api/web_request/web_request_api.cc b/chromium/extensions/browser/api/web_request/web_request_api.cc
index 6d8f151cf4b..82d2809d071 100644
--- a/chromium/extensions/browser/api/web_request/web_request_api.cc
+++ b/chromium/extensions/browser/api/web_request/web_request_api.cc
@@ -26,6 +26,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -451,12 +452,17 @@ bool WebRequestAPI::MaybeProxyURLLoaderFactory(
}
auto proxy = base::MakeRefCounted<WebRequestProxyingURLLoaderFactory>(
- frame->GetProcess()->GetBrowserContext(), info_map_);
+ frame->GetProcess()->GetBrowserContext(),
+ frame->GetProcess()->GetBrowserContext()->GetResourceContext(),
+ info_map_);
proxies_.emplace(proxy.get(), proxy);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&WebRequestProxyingURLLoaderFactory::StartProxying, proxy,
- frame->GetProcess()->GetID(), frame->GetRoutingID(),
+ // Match the behavior of the WebRequestInfo constructor
+ // which takes a net::URLRequest*.
+ is_navigation ? -1 : frame->GetProcess()->GetID(),
+ is_navigation ? MSG_ROUTING_NONE : frame->GetRoutingID(),
std::move(navigation_ui_data), std::move(proxied_request),
std::move(target_factory_info),
base::BindOnce(&WebRequestAPI::RemoveProxyThreadSafe,
@@ -671,16 +677,14 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest(
// OnBeforeRequest call.
// |extension_info_map| is null for system level requests.
if (extension_info_map) {
- // Give priority to blocking rules over redirect rules.
- if (extension_info_map->GetRulesetManager()->ShouldBlockRequest(
- *request, is_incognito_context)) {
- return net::ERR_BLOCKED_BY_CLIENT;
- }
+ using Action = declarative_net_request::RulesetManager::Action;
- if (extension_info_map->GetRulesetManager()->ShouldRedirectRequest(
- *request, is_incognito_context, new_url)) {
+ Action action = extension_info_map->GetRulesetManager()->EvaluateRequest(
+ *request, is_incognito_context, new_url);
+ if (action == Action::BLOCK)
+ return net::ERR_BLOCKED_BY_CLIENT;
+ if (action == Action::REDIRECT)
return net::OK;
- }
}
// Whether to initialized |blocked_requests_|.
@@ -1460,7 +1464,7 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl(
}
if (!request->is_web_view) {
- PermissionsData::AccessType access =
+ PermissionsData::PageAccess access =
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map, listener->id.extension_id, request->url,
request->frame_data ? request->frame_data->tab_id : -1,
@@ -1468,8 +1472,8 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl(
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
request->initiator);
- if (access != PermissionsData::ACCESS_ALLOWED) {
- if (access == PermissionsData::ACCESS_WITHHELD &&
+ if (access != PermissionsData::PageAccess::kAllowed) {
+ if (access == PermissionsData::PageAccess::kWithheld &&
web_request_event_router_delegate_) {
web_request_event_router_delegate_->NotifyWebRequestWithheld(
request->render_process_id, request->frame_id,
@@ -1937,8 +1941,6 @@ bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules(
has_declarative_rules);
}
- base::Time start = base::Time::Now();
-
bool deltas_created = false;
for (const auto& it : relevant_registries) {
WebRequestRulesRegistry* rules_registry = it.first;
@@ -1955,10 +1957,6 @@ bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules(
}
}
- base::TimeDelta elapsed_time = start - base::Time::Now();
- UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay",
- elapsed_time);
-
return deltas_created;
}
diff --git a/chromium/extensions/browser/api/web_request/web_request_api_helpers.cc b/chromium/extensions/browser/api/web_request/web_request_api_helpers.cc
index 75f4554fb2b..4f363a8fb4a 100644
--- a/chromium/extensions/browser/api/web_request/web_request_api_helpers.cc
+++ b/chromium/extensions/browser/api/web_request/web_request_api_helpers.cc
@@ -32,6 +32,7 @@
#include "extensions/common/extension_messages.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
+#include "net/http/http_request_headers.h"
#include "net/http/http_util.h"
#include "net/log/net_log_event_type.h"
#include "url/url_constants.h"
@@ -49,7 +50,7 @@ namespace extension_web_request_api_helpers {
namespace {
-using ParsedResponseCookies = std::vector<linked_ptr<net::ParsedCookie>>;
+using ParsedResponseCookies = std::vector<std::unique_ptr<net::ParsedCookie>>;
// Mirrors the histogram enum of the same name. DO NOT REORDER THESE VALUES OR
// CHANGE THEIR MEANING.
@@ -710,6 +711,101 @@ static std::string FindRemoveRequestHeader(
return std::string();
}
+// TODO(yhirano): Remove this once https://crbug.com/827582 is solved.
+class WebSocketRequestHeaderModificationStatusReporter final {
+ public:
+ WebSocketRequestHeaderModificationStatusReporter() = default;
+
+ void Report(const std::set<std::string>& removed_headers,
+ const std::set<std::string>& set_headers) {
+ auto modification =
+ WebRequestWSRequestHeadersModification::kRiskyModification;
+ if (removed_headers.empty() && set_headers.empty())
+ modification = WebRequestWSRequestHeadersModification::kNone;
+ if (removed_headers.empty() && set_headers.size() == 1 &&
+ base::ToLowerASCII(*set_headers.begin()) == "user-agent") {
+ modification = WebRequestWSRequestHeadersModification::kSetUserAgentOnly;
+ }
+ UMA_HISTOGRAM_ENUMERATION(
+ "Extensions.WebRequest.WS_RequestHeadersModification", modification);
+
+ for (const std::string& header : removed_headers)
+ Update(header);
+ for (const std::string& header : set_headers)
+ Update(header);
+
+ UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequest.WS_RequestHeaders_SecOrProxy",
+ modified_sec_or_proxy_headers_);
+ UMA_HISTOGRAM_BOOLEAN(
+ "Extensions.WebRequest.WS_RequestHeaders_SecOrProxyExceptProtocol",
+ modified_sec_or_proxy_headers_except_sec_websocket_protocol_);
+ UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequest.WS_RequestHeaders_Unsafe",
+ modified_unsafe_headers_);
+ UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequest.WS_RequestHeaders_WebSocket",
+ modified_websocket_headers_);
+ UMA_HISTOGRAM_BOOLEAN(
+ "Extensions.WebRequest.WS_RequestHeaders_WebSocketExceptProtocol",
+ modified_websocket_headers_except_sec_websocket_protocol_);
+ UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequest.WS_RequestHeaders_Origin",
+ modified_origin_);
+ UMA_HISTOGRAM_BOOLEAN(
+ "Extensions.WebRequest.WS_RequestHeaders_OriginOrCookie",
+ modified_origin_or_cookie_);
+ }
+
+ private:
+ void Update(const std::string& header) {
+ std::string lower_header = base::ToLowerASCII(header);
+
+ if (base::StartsWith(lower_header, "sec-", base::CompareCase::SENSITIVE)) {
+ if (lower_header != "sec-websocket-protocol")
+ modified_sec_or_proxy_headers_except_sec_websocket_protocol_ = true;
+ modified_sec_or_proxy_headers_ = true;
+
+ if (base::StartsWith(lower_header, "sec-websocket-",
+ base::CompareCase::SENSITIVE)) {
+ if (lower_header != "sec-websocket-protocol")
+ modified_websocket_headers_except_sec_websocket_protocol_ = true;
+ modified_websocket_headers_ = true;
+ }
+ } else if (base::StartsWith(lower_header, "proxy-",
+ base::CompareCase::SENSITIVE)) {
+ modified_sec_or_proxy_headers_ = true;
+ modified_sec_or_proxy_headers_except_sec_websocket_protocol_ = true;
+ } else if (lower_header == "cookie" || lower_header == "cookie2") {
+ modified_origin_or_cookie_ = true;
+ } else if (lower_header == "cache-control" || lower_header == "pragma" ||
+ lower_header == "upgrade" || lower_header == "connection" ||
+ lower_header == "host") {
+ modified_websocket_headers_ = true;
+ modified_websocket_headers_except_sec_websocket_protocol_ = true;
+ } else if (lower_header == "origin") {
+ // As we don't have an option to allow "origin" modification, all
+ // booleans should be set here.
+ modified_sec_or_proxy_headers_ = true;
+ modified_sec_or_proxy_headers_except_sec_websocket_protocol_ = true;
+ modified_unsafe_headers_ = true;
+ modified_websocket_headers_ = true;
+ modified_websocket_headers_except_sec_websocket_protocol_ = true;
+ modified_origin_ = true;
+ modified_origin_or_cookie_ = true;
+ } else if (!net::HttpUtil::IsSafeHeader(lower_header) &&
+ lower_header != "user-agent") {
+ modified_unsafe_headers_ = true;
+ }
+ }
+
+ bool modified_sec_or_proxy_headers_ = false;
+ bool modified_sec_or_proxy_headers_except_sec_websocket_protocol_ = false;
+ bool modified_unsafe_headers_ = false;
+ bool modified_websocket_headers_ = false;
+ bool modified_websocket_headers_except_sec_websocket_protocol_ = false;
+ bool modified_origin_ = false;
+ bool modified_origin_or_cookie_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(WebSocketRequestHeaderModificationStatusReporter);
+};
+
void MergeOnBeforeSendHeadersResponses(
const GURL& url,
const EventResponseDeltas& deltas,
@@ -842,18 +938,9 @@ void MergeOnBeforeSendHeadersResponses(
removal);
if (url.SchemeIsWSOrWSS()) {
- auto modification =
- WebRequestWSRequestHeadersModification::kRiskyModification;
- if (removed_headers.empty() && set_headers.empty())
- modification = WebRequestWSRequestHeadersModification::kNone;
- if (removed_headers.empty() && set_headers.size() == 1 &&
- base::ToLowerASCII(*set_headers.begin()) == "user-agent") {
- modification = WebRequestWSRequestHeadersModification::kSetUserAgentOnly;
- }
- UMA_HISTOGRAM_ENUMERATION(
- "Extensions.WebRequest.WS_RequestHeadersModification", modification);
+ WebSocketRequestHeaderModificationStatusReporter().Report(removed_headers,
+ set_headers);
}
-
MergeCookiesInOnBeforeSendHeadersResponses(url, deltas, request_headers,
conflicting_extensions, logger);
}
@@ -867,7 +954,7 @@ static ParsedResponseCookies GetResponseCookies(
std::string value;
while (override_response_headers->EnumerateHeader(&iter, "Set-Cookie",
&value)) {
- result.push_back(make_linked_ptr(new net::ParsedCookie(value)));
+ result.push_back(std::make_unique<net::ParsedCookie>(value));
}
return result;
}
@@ -878,9 +965,9 @@ static void StoreResponseCookies(
const ParsedResponseCookies& cookies,
scoped_refptr<net::HttpResponseHeaders> override_response_headers) {
override_response_headers->RemoveHeader("Set-Cookie");
- for (ParsedResponseCookies::const_iterator i = cookies.begin();
- i != cookies.end(); ++i) {
- override_response_headers->AddHeader("Set-Cookie: " + (*i)->ToCookieLine());
+ for (const std::unique_ptr<net::ParsedCookie>& cookie : cookies) {
+ override_response_headers->AddHeader("Set-Cookie: " +
+ cookie->ToCookieLine());
}
}
@@ -976,10 +1063,9 @@ static bool MergeAddResponseCookieModifications(
continue;
// Cookie names are not unique in response cookies so we always append
// and never override.
- linked_ptr<net::ParsedCookie> cookie(
- new net::ParsedCookie(std::string()));
+ auto cookie = std::make_unique<net::ParsedCookie>(std::string());
ApplyResponseCookieModification((*mod)->modification.get(), cookie.get());
- cookies->push_back(cookie);
+ cookies->push_back(std::move(cookie));
modified = true;
}
}
@@ -1003,12 +1089,10 @@ static bool MergeEditResponseCookieModifications(
if ((*mod)->type != EDIT || !(*mod)->modification.get())
continue;
- for (ParsedResponseCookies::iterator cookie = cookies->begin();
- cookie != cookies->end(); ++cookie) {
- if (DoesResponseCookieMatchFilter(cookie->get(),
- (*mod)->filter.get())) {
+ for (const std::unique_ptr<net::ParsedCookie>& cookie : *cookies) {
+ if (DoesResponseCookieMatchFilter(cookie.get(), (*mod)->filter.get())) {
modified |= ApplyResponseCookieModification(
- (*mod)->modification.get(), cookie->get());
+ (*mod)->modification.get(), cookie.get());
}
}
}
diff --git a/chromium/extensions/browser/api/web_request/web_request_info.cc b/chromium/extensions/browser/api/web_request/web_request_info.cc
index ac1873d2545..bc7969facf8 100644
--- a/chromium/extensions/browser/api/web_request/web_request_info.cc
+++ b/chromium/extensions/browser/api/web_request/web_request_info.cc
@@ -256,6 +256,7 @@ WebRequestInfo::WebRequestInfo(net::URLRequest* url_request)
type = info->GetResourceType();
web_request_type = ToWebRequestResourceType(type.value());
is_async = info->IsAsync();
+ resource_context = info->GetContext();
} else {
// There may be basic process and frame info associated with the request
// even when |info| is null. Attempt to grab it as a last ditch effort. If
@@ -286,6 +287,7 @@ WebRequestInfo::WebRequestInfo(
int render_frame_id,
std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data,
int32_t routing_id,
+ content::ResourceContext* resource_context,
const network::ResourceRequest& request)
: id(request_id),
url(request.url),
@@ -298,7 +300,8 @@ WebRequestInfo::WebRequestInfo(
initiator(request.request_initiator),
type(static_cast<content::ResourceType>(request.resource_type)),
extra_request_headers(request.headers),
- logger(std::make_unique<NetworkServiceLogger>()) {
+ logger(std::make_unique<NetworkServiceLogger>()),
+ resource_context(resource_context) {
if (url.SchemeIsWSOrWSS())
web_request_type = WebRequestResourceType::WEB_SOCKET;
else
diff --git a/chromium/extensions/browser/api/web_request/web_request_info.h b/chromium/extensions/browser/api/web_request/web_request_info.h
index f66459cf471..b8d01992a8b 100644
--- a/chromium/extensions/browser/api/web_request/web_request_info.h
+++ b/chromium/extensions/browser/api/web_request/web_request_info.h
@@ -24,6 +24,10 @@
#include "url/gurl.h"
#include "url/origin.h"
+namespace content {
+class ResourceContext;
+} // namespace content
+
namespace net {
class HttpResponseHeaders;
class URLRequest;
@@ -70,6 +74,7 @@ struct WebRequestInfo {
int render_frame_id,
std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data,
int32_t routing_id,
+ content::ResourceContext* resource_context,
const network::ResourceRequest& request);
~WebRequestInfo();
@@ -165,6 +170,9 @@ struct WebRequestInfo {
// of Logger above. This is always non-null.
std::unique_ptr<Logger> logger;
+ // The ResourceContext associated with this request. May be null.
+ content::ResourceContext* resource_context = nullptr;
+
private:
void InitializeWebViewAndFrameData(
const ExtensionNavigationUIData* navigation_ui_data);
diff --git a/chromium/extensions/browser/api/web_request/web_request_permissions.cc b/chromium/extensions/browser/api/web_request/web_request_permissions.cc
index 426bdc33602..2165a0e9d5a 100644
--- a/chromium/extensions/browser/api/web_request/web_request_permissions.cc
+++ b/chromium/extensions/browser/api/web_request/web_request_permissions.cc
@@ -42,7 +42,7 @@ bool HasWebRequestScheme(const GURL& url) {
bool g_allow_all_extension_locations_in_public_session = false;
-PermissionsData::AccessType GetHostAccessForURL(
+PermissionsData::PageAccess GetHostAccessForURL(
const extensions::Extension& extension,
const GURL& url,
int tab_id) {
@@ -50,28 +50,28 @@ PermissionsData::AccessType GetHostAccessForURL(
// anyway.
if (url.SchemeIs(url::kAboutScheme) ||
url::IsSameOriginWith(url, extension.url())) {
- return PermissionsData::ACCESS_ALLOWED;
+ return PermissionsData::PageAccess::kAllowed;
}
- return extension.permissions_data()->GetPageAccess(&extension, url, tab_id,
+ return extension.permissions_data()->GetPageAccess(url, tab_id,
nullptr /*error*/);
}
// Returns the most restricted access type out of |access1| and |access2|.
-PermissionsData::AccessType GetMinimumAccessType(
- PermissionsData::AccessType access1,
- PermissionsData::AccessType access2) {
- PermissionsData::AccessType access = PermissionsData::ACCESS_DENIED;
+PermissionsData::PageAccess GetMinimumAccessType(
+ PermissionsData::PageAccess access1,
+ PermissionsData::PageAccess access2) {
+ PermissionsData::PageAccess access = PermissionsData::PageAccess::kDenied;
switch (access1) {
- case PermissionsData::ACCESS_DENIED:
- access = PermissionsData::ACCESS_DENIED;
+ case PermissionsData::PageAccess::kDenied:
+ access = PermissionsData::PageAccess::kDenied;
break;
- case PermissionsData::ACCESS_WITHHELD:
- access = (access2 == PermissionsData::ACCESS_DENIED
- ? PermissionsData::ACCESS_DENIED
- : PermissionsData::ACCESS_WITHHELD);
+ case PermissionsData::PageAccess::kWithheld:
+ access = (access2 == PermissionsData::PageAccess::kDenied
+ ? PermissionsData::PageAccess::kDenied
+ : PermissionsData::PageAccess::kWithheld);
break;
- case PermissionsData::ACCESS_ALLOWED:
+ case PermissionsData::PageAccess::kAllowed:
access = access2;
break;
}
@@ -95,15 +95,15 @@ bool IsWebUIAllowedToMakeNetworkRequests(const url::Origin& origin) {
} // namespace
-// Returns true if the URL is sensitive and requests to this URL must not be
+// Returns true if the given |request| is sensitive and must not be
// modified/canceled by extensions, e.g. because it is targeted to the webstore
// to check for updates, extension blacklisting, etc.
-bool IsSensitiveURL(const GURL& url,
- base::Optional<url::Origin> initiator,
- bool is_request_from_browser,
- bool is_request_from_webui_renderer) {
+bool IsSensitiveRequest(const extensions::WebRequestInfo& request,
+ bool is_request_from_browser,
+ bool is_request_from_webui_renderer) {
const bool is_request_from_sensitive_source =
is_request_from_browser || is_request_from_webui_renderer;
+ const GURL& url = request.url;
const bool is_network_request =
url.SchemeIsHTTPOrHTTPS() || url.SchemeIsWSOrWSS();
@@ -114,10 +114,10 @@ bool IsSensitiveURL(const GURL& url,
// The DCHECK helps avoid proliferation of such behavior. In any case, we
// treat the requests as sensitive to ensure that the Web Request API
// doesn't see them.
- DCHECK(initiator.has_value());
- DCHECK(IsWebUIAllowedToMakeNetworkRequests(*initiator))
- << "Unsupported network request from " << initiator->GetURL().spec()
- << " for " << url.spec();
+ DCHECK(request.initiator.has_value());
+ DCHECK(IsWebUIAllowedToMakeNetworkRequests(*request.initiator))
+ << "Unsupported network request from "
+ << request.initiator->GetURL().spec() << " for " << url.spec();
return true;
}
@@ -168,14 +168,10 @@ bool IsSensitiveURL(const GURL& url,
base::CompareCase::SENSITIVE));
}
- if (is_request_from_sensitive_source) {
- sensitive_chrome_url =
- sensitive_chrome_url ||
- extensions::ExtensionsAPIClient::Get()->ShouldHideBrowserNetworkRequest(
- url);
- }
-
- return sensitive_chrome_url || extension_urls::IsWebstoreUpdateUrl(url) ||
+ return sensitive_chrome_url ||
+ extensions::ExtensionsAPIClient::Get()
+ ->ShouldHideBrowserNetworkRequest(request) ||
+ extension_urls::IsWebstoreUpdateUrl(url) ||
extension_urls::IsBlacklistUpdateUrl(url) ||
extension_urls::IsSafeBrowsingUrl(origin, url.path_piece());
}
@@ -221,8 +217,8 @@ bool WebRequestPermissions::HideRequest(
request.render_process_id);
}
- return IsSensitiveURL(request.url, request.initiator, is_request_from_browser,
- is_request_from_webui_renderer) ||
+ return IsSensitiveRequest(request, is_request_from_browser,
+ is_request_from_webui_renderer) ||
!HasWebRequestScheme(request.url);
}
@@ -233,7 +229,7 @@ void WebRequestPermissions::
}
// static
-PermissionsData::AccessType WebRequestPermissions::CanExtensionAccessURL(
+PermissionsData::PageAccess WebRequestPermissions::CanExtensionAccessURL(
const extensions::InfoMap* extension_info_map,
const std::string& extension_id,
const GURL& url,
@@ -243,18 +239,18 @@ PermissionsData::AccessType WebRequestPermissions::CanExtensionAccessURL(
const base::Optional<url::Origin>& initiator) {
// extension_info_map can be NULL in testing.
if (!extension_info_map)
- return PermissionsData::ACCESS_ALLOWED;
+ return PermissionsData::PageAccess::kAllowed;
const extensions::Extension* extension =
extension_info_map->extensions().GetByID(extension_id);
if (!extension)
- return PermissionsData::ACCESS_DENIED;
+ return PermissionsData::PageAccess::kDenied;
// Prevent viewing / modifying requests initiated by a host protected by
// policy.
if (initiator &&
- extension->permissions_data()->IsRuntimeBlockedHost(initiator->GetURL()))
- return PermissionsData::ACCESS_DENIED;
+ extension->permissions_data()->IsPolicyBlockedHost(initiator->GetURL()))
+ return PermissionsData::PageAccess::kDenied;
// When we are in a Public Session, allow all URLs for webRequests initiated
// by a regular extension (but don't allow chrome:// URLs).
@@ -267,35 +263,35 @@ PermissionsData::AccessType WebRequestPermissions::CanExtensionAccessURL(
// in Public Session is that all extensions are installed by policy).
CHECK(g_allow_all_extension_locations_in_public_session ||
extensions::Manifest::IsPolicyLocation(extension->location()));
- return PermissionsData::ACCESS_ALLOWED;
+ return PermissionsData::PageAccess::kAllowed;
}
#endif
// Check if this event crosses incognito boundaries when it shouldn't.
if (crosses_incognito && !extension_info_map->CanCrossIncognito(extension))
- return PermissionsData::ACCESS_DENIED;
+ return PermissionsData::PageAccess::kDenied;
- PermissionsData::AccessType access = PermissionsData::ACCESS_DENIED;
+ PermissionsData::PageAccess access = PermissionsData::PageAccess::kDenied;
switch (host_permissions_check) {
case DO_NOT_CHECK_HOST:
- access = PermissionsData::ACCESS_ALLOWED;
+ access = PermissionsData::PageAccess::kAllowed;
break;
case REQUIRE_HOST_PERMISSION_FOR_URL:
access = GetHostAccessForURL(*extension, url, tab_id);
break;
case REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR: {
- PermissionsData::AccessType request_access =
+ PermissionsData::PageAccess request_access =
GetHostAccessForURL(*extension, url, tab_id);
- PermissionsData::AccessType initiator_access =
+ PermissionsData::PageAccess initiator_access =
initiator
? GetHostAccessForURL(*extension, initiator->GetURL(), tab_id)
- : PermissionsData::ACCESS_ALLOWED;
+ : PermissionsData::PageAccess::kAllowed;
access = GetMinimumAccessType(request_access, initiator_access);
break;
}
case REQUIRE_ALL_URLS:
if (extension->permissions_data()->HasEffectiveAccessToAllHosts())
- access = PermissionsData::ACCESS_ALLOWED;
+ access = PermissionsData::PageAccess::kAllowed;
// else ACCESS_DENIED
break;
}
@@ -310,12 +306,12 @@ bool WebRequestPermissions::CanExtensionAccessInitiator(
const base::Optional<url::Origin>& initiator,
int tab_id,
bool crosses_incognito) {
- PermissionsData::AccessType access = PermissionsData::ACCESS_ALLOWED;
+ PermissionsData::PageAccess access = PermissionsData::PageAccess::kAllowed;
if (initiator) {
access = CanExtensionAccessURL(
extension_info_map, extension_id, initiator->GetURL(), tab_id,
crosses_incognito,
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL, base::nullopt);
}
- return access == PermissionsData::ACCESS_ALLOWED;
+ return access == PermissionsData::PageAccess::kAllowed;
}
diff --git a/chromium/extensions/browser/api/web_request/web_request_permissions.h b/chromium/extensions/browser/api/web_request/web_request_permissions.h
index 4a3c6fde7ea..af3608f1037 100644
--- a/chromium/extensions/browser/api/web_request/web_request_permissions.h
+++ b/chromium/extensions/browser/api/web_request/web_request_permissions.h
@@ -21,12 +21,12 @@ struct WebRequestInfo;
}
// Exposed for unit testing.
-bool IsSensitiveURL(const GURL& url,
- base::Optional<url::Origin> initiator,
- bool is_request_from_browser,
- bool is_request_from_webui_renderer);
+bool IsSensitiveRequest(const extensions::WebRequestInfo& request,
+ bool is_request_from_browser,
+ bool is_request_from_webui_renderer);
-// This class is used to test whether extensions may modify web requests.
+// This class is used to test whether extensions may modify web requests. It
+// should be used on the IO thread.
class WebRequestPermissions {
public:
// Different host permission checking modes for CanExtensionAccessURL.
@@ -50,7 +50,7 @@ class WebRequestPermissions {
// |host_permission_check| controls how permissions are checked with regard to
// |url| and |initiator| if an initiator exists.
- static extensions::PermissionsData::AccessType CanExtensionAccessURL(
+ static extensions::PermissionsData::PageAccess CanExtensionAccessURL(
const extensions::InfoMap* extension_info_map,
const std::string& extension_id,
const GURL& url,
diff --git a/chromium/extensions/browser/api/web_request/web_request_permissions_unittest.cc b/chromium/extensions/browser/api/web_request/web_request_permissions_unittest.cc
index f3afe687ba6..3df0f6c131c 100644
--- a/chromium/extensions/browser/api/web_request/web_request_permissions_unittest.cc
+++ b/chromium/extensions/browser/api/web_request/web_request_permissions_unittest.cc
@@ -5,12 +5,13 @@
#include "extensions/browser/api/web_request/web_request_permissions.h"
#include "extensions/browser/api/extensions_api_client.h"
+#include "extensions/browser/api/web_request/web_request_info.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace extensions {
-TEST(ExtensionWebRequestPermissions, IsSensitiveURL) {
+TEST(ExtensionWebRequestPermissions, IsSensitiveRequest) {
ExtensionsAPIClient api_client;
struct TestCase {
const char* url;
@@ -55,19 +56,22 @@ TEST(ExtensionWebRequestPermissions, IsSensitiveURL) {
{"https://chrome.google.com/webstore?query", true, true},
};
for (const TestCase& test : cases) {
- GURL url(test.url);
- EXPECT_TRUE(url.is_valid()) << test.url;
+ WebRequestInfo request;
+ request.url = GURL(test.url);
+ EXPECT_TRUE(request.url.is_valid()) << test.url;
+
+ request.initiator = url::Origin::Create(request.url);
EXPECT_EQ(test.is_sensitive_if_request_from_common_renderer,
- IsSensitiveURL(url, url::Origin::Create(url),
- false /* is_request_from_browser */,
- false /* is_request_from_web_ui_renderer */))
+ IsSensitiveRequest(request, false /* is_request_from_browser */,
+ false /* is_request_from_web_ui_renderer */))
<< test.url;
- const bool supported_in_webui_renderers = !url.SchemeIsHTTPOrHTTPS();
- EXPECT_EQ(
- test.is_sensitive_if_request_from_browser_or_webui_renderer,
- IsSensitiveURL(url, base::nullopt, true /* is_request_from_browser */,
- supported_in_webui_renderers))
+ const bool supported_in_webui_renderers =
+ !request.url.SchemeIsHTTPOrHTTPS();
+ request.initiator = base::nullopt;
+ EXPECT_EQ(test.is_sensitive_if_request_from_browser_or_webui_renderer,
+ IsSensitiveRequest(request, true /* is_request_from_browser */,
+ supported_in_webui_renderers))
<< test.url;
}
}
diff --git a/chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
index 466a63d172f..7b275e1abab 100644
--- a/chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
+++ b/chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -52,7 +52,7 @@ void WebRequestProxyingURLLoaderFactory::InProgressRequest::Restart() {
request_id_, factory_->render_process_id_, factory_->render_frame_id_,
factory_->navigation_ui_data_ ? factory_->navigation_ui_data_->DeepCopy()
: nullptr,
- routing_id_, request_);
+ routing_id_, factory_->resource_context_, request_);
auto continuation =
base::BindRepeating(&InProgressRequest::ContinueToBeforeSendHeaders,
@@ -83,14 +83,18 @@ void WebRequestProxyingURLLoaderFactory::InProgressRequest::Restart() {
ContinueToBeforeSendHeaders(net::OK);
}
-void WebRequestProxyingURLLoaderFactory::InProgressRequest::FollowRedirect() {
+void WebRequestProxyingURLLoaderFactory::InProgressRequest::FollowRedirect(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
+ DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
+ "headers was not supported "
+ "yet. crbug.com/845683";
if (ignore_next_follow_redirect_) {
ignore_next_follow_redirect_ = false;
return;
}
if (target_loader_.is_bound())
- target_loader_->FollowRedirect();
+ target_loader_->FollowRedirect(base::nullopt);
Restart();
}
@@ -404,10 +408,12 @@ void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnRequestError(
WebRequestProxyingURLLoaderFactory::WebRequestProxyingURLLoaderFactory(
void* browser_context,
+ content::ResourceContext* resource_context,
InfoMap* info_map)
: RefCountedDeleteOnSequence(content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::IO)),
browser_context_(browser_context),
+ resource_context_(resource_context),
info_map_(info_map) {}
void WebRequestProxyingURLLoaderFactory::StartProxying(
diff --git a/chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h b/chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
index c3c8283bff0..91edf881dcc 100644
--- a/chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
+++ b/chromium/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
@@ -25,6 +25,10 @@
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "url/gurl.h"
+namespace content {
+class ResourceContext;
+} // namespace content
+
namespace extensions {
class ExtensionNavigationUIData;
@@ -60,7 +64,8 @@ class WebRequestProxyingURLLoaderFactory
void Restart();
// network::mojom::URLLoader:
- void FollowRedirect() override;
+ void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) override;
@@ -131,7 +136,9 @@ class WebRequestProxyingURLLoaderFactory
DISALLOW_COPY_AND_ASSIGN(InProgressRequest);
};
- WebRequestProxyingURLLoaderFactory(void* browser_context, InfoMap* info_map);
+ WebRequestProxyingURLLoaderFactory(void* browser_context,
+ content::ResourceContext* resource_context,
+ InfoMap* info_map);
void StartProxying(
int render_process_id,
@@ -164,6 +171,7 @@ class WebRequestProxyingURLLoaderFactory
void RemoveRequest(uint64_t request_id);
void* const browser_context_;
+ content::ResourceContext* const resource_context_;
int render_process_id_ = -1;
int render_frame_id_ = -1;
std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data_;
diff --git a/chromium/extensions/browser/api_unittest.cc b/chromium/extensions/browser/api_unittest.cc
index c442c394b83..186b6d3d940 100644
--- a/chromium/extensions/browser/api_unittest.cc
+++ b/chromium/extensions/browser/api_unittest.cc
@@ -51,10 +51,9 @@ void ApiUnitTest::CreateBackgroundPage() {
GURL url = BackgroundInfo::GetBackgroundURL(extension());
if (url.is_empty())
url = GURL(url::kAboutBlankURL);
- contents_.reset(
- content::WebContents::Create(content::WebContents::CreateParams(
- browser_context(),
- content::SiteInstance::CreateForURL(browser_context(), url))));
+ contents_ = content::WebContents::Create(content::WebContents::CreateParams(
+ browser_context(),
+ content::SiteInstance::CreateForURL(browser_context(), url)));
}
}
diff --git a/chromium/extensions/browser/app_window/app_delegate.h b/chromium/extensions/browser/app_window/app_delegate.h
index a513cba211d..30c8fb3827c 100644
--- a/chromium/extensions/browser/app_window/app_delegate.h
+++ b/chromium/extensions/browser/app_window/app_delegate.h
@@ -48,11 +48,12 @@ class AppDelegate {
content::BrowserContext* context,
content::WebContents* source,
const content::OpenURLParams& params) = 0;
- virtual void AddNewContents(content::BrowserContext* context,
- content::WebContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_rect,
- bool user_gesture) = 0;
+ virtual void AddNewContents(
+ content::BrowserContext* context,
+ std::unique_ptr<content::WebContents> new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_rect,
+ bool user_gesture) = 0;
// Feature support.
virtual content::ColorChooser* ShowColorChooser(
diff --git a/chromium/extensions/browser/app_window/app_window.cc b/chromium/extensions/browser/app_window/app_window.cc
index 5b090151ef9..5de2af6210e 100644
--- a/chromium/extensions/browser/app_window/app_window.cc
+++ b/chromium/extensions/browser/app_window/app_window.cc
@@ -366,14 +366,14 @@ WebContents* AppWindow::OpenURLFromTab(WebContents* source,
}
void AppWindow::AddNewContents(WebContents* source,
- WebContents* new_contents,
+ std::unique_ptr<WebContents> new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
bool* was_blocked) {
DCHECK(new_contents->GetBrowserContext() == browser_context_);
- app_delegate_->AddNewContents(browser_context_, new_contents, disposition,
- initial_rect, user_gesture);
+ app_delegate_->AddNewContents(browser_context_, std::move(new_contents),
+ disposition, initial_rect, user_gesture);
}
content::KeyboardEventProcessingResult AppWindow::PreHandleKeyboardEvent(
@@ -904,8 +904,10 @@ void AppWindow::NavigationStateChanged(content::WebContents* source,
native_app_window_->UpdateWindowIcon();
}
-void AppWindow::EnterFullscreenModeForTab(content::WebContents* source,
- const GURL& origin) {
+void AppWindow::EnterFullscreenModeForTab(
+ content::WebContents* source,
+ const GURL& origin,
+ const blink::WebFullscreenOptions& options) {
ToggleFullscreenModeForTab(source, true);
}
diff --git a/chromium/extensions/browser/app_window/app_window.h b/chromium/extensions/browser/app_window/app_window.h
index 84026c02489..dff33dc639e 100644
--- a/chromium/extensions/browser/app_window/app_window.h
+++ b/chromium/extensions/browser/app_window/app_window.h
@@ -407,8 +407,10 @@ class AppWindow : public content::WebContentsDelegate,
const gfx::Rect& pos) override;
void NavigationStateChanged(content::WebContents* source,
content::InvalidateTypes changed_flags) override;
- void EnterFullscreenModeForTab(content::WebContents* source,
- const GURL& origin) override;
+ void EnterFullscreenModeForTab(
+ content::WebContents* source,
+ const GURL& origin,
+ const blink::WebFullscreenOptions& options) override;
void ExitFullscreenModeForTab(content::WebContents* source) override;
bool IsFullscreenForTabOrPending(
const content::WebContents* source) const override;
@@ -425,7 +427,7 @@ class AppWindow : public content::WebContentsDelegate,
content::WebContents* source,
const content::OpenURLParams& params) override;
void AddNewContents(content::WebContents* source,
- content::WebContents* new_contents,
+ std::unique_ptr<content::WebContents> new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
diff --git a/chromium/extensions/browser/app_window/app_window_contents.cc b/chromium/extensions/browser/app_window/app_window_contents.cc
index 2c4759af72b..9285be93623 100644
--- a/chromium/extensions/browser/app_window/app_window_contents.cc
+++ b/chromium/extensions/browser/app_window/app_window_contents.cc
@@ -34,7 +34,7 @@ void AppWindowContentsImpl::Initialize(content::BrowserContext* context,
context, creator_frame->GetSiteInstance());
create_params.opener_render_process_id = creator_frame->GetProcess()->GetID();
create_params.opener_render_frame_id = creator_frame->GetRoutingID();
- web_contents_.reset(content::WebContents::Create(create_params));
+ web_contents_ = content::WebContents::Create(create_params);
Observe(web_contents_.get());
web_contents_->GetMutableRendererPrefs()->
diff --git a/chromium/extensions/browser/browsertest_util.cc b/chromium/extensions/browser/browsertest_util.cc
index 0b24b689033..634d3801b42 100644
--- a/chromium/extensions/browser/browsertest_util.cc
+++ b/chromium/extensions/browser/browsertest_util.cc
@@ -12,9 +12,11 @@
namespace extensions {
namespace browsertest_util {
-std::string ExecuteScriptInBackgroundPage(content::BrowserContext* context,
- const std::string& extension_id,
- const std::string& script) {
+std::string ExecuteScriptInBackgroundPage(
+ content::BrowserContext* context,
+ const std::string& extension_id,
+ const std::string& script,
+ ScriptUserActivation script_user_activation) {
ExtensionHost* host =
ProcessManager::Get(context)->GetBackgroundHostForExtension(extension_id);
if (!host) {
@@ -23,8 +25,17 @@ std::string ExecuteScriptInBackgroundPage(content::BrowserContext* context,
}
std::string result;
- if (!content::ExecuteScriptAndExtractString(host->host_contents(), script,
- &result)) {
+ bool success;
+ if (script_user_activation == ScriptUserActivation::kActivate) {
+ success = content::ExecuteScriptAndExtractString(host->host_contents(),
+ script, &result);
+ } else {
+ DCHECK_EQ(script_user_activation, ScriptUserActivation::kDontActivate);
+ success = content::ExecuteScriptWithoutUserGestureAndExtractString(
+ host->host_contents(), script, &result);
+ }
+
+ if (!success) {
ADD_FAILURE() << "Executing script failed: " << script;
result.clear();
}
diff --git a/chromium/extensions/browser/browsertest_util.h b/chromium/extensions/browser/browsertest_util.h
index e2798c0ed6a..9774259f952 100644
--- a/chromium/extensions/browser/browsertest_util.h
+++ b/chromium/extensions/browser/browsertest_util.h
@@ -14,13 +14,25 @@ class BrowserContext;
namespace extensions {
namespace browsertest_util {
+// Determine if a user activation notification should be triggered before
+// executing a script
+enum class ScriptUserActivation {
+ kActivate,
+ kDontActivate,
+};
+
// Waits until |script| calls "window.domAutomationController.send(result)",
// where |result| is a string, and returns |result|. Fails the test and returns
// an empty string if |extension_id| isn't installed in |context| or doesn't
-// have a background page, or if executing the script fails.
-std::string ExecuteScriptInBackgroundPage(content::BrowserContext* context,
- const std::string& extension_id,
- const std::string& script);
+// have a background page, or if executing the script fails. The argument
+// |script_user_activation| determines if the script should be executed after a
+// user activation.
+std::string ExecuteScriptInBackgroundPage(
+ content::BrowserContext* context,
+ const std::string& extension_id,
+ const std::string& script,
+ ScriptUserActivation script_user_activation =
+ ScriptUserActivation::kActivate);
// Same as ExecuteScriptInBackgroundPage, but doesn't wait for the script
// to return a result. Fails the test and returns false if |extension_id|
diff --git a/chromium/extensions/browser/computed_hashes.cc b/chromium/extensions/browser/computed_hashes.cc
index de77d45341a..cfe0a9e84e8 100644
--- a/chromium/extensions/browser/computed_hashes.cc
+++ b/chromium/extensions/browser/computed_hashes.cc
@@ -187,7 +187,7 @@ void ComputedHashes::ComputeHashesForContent(const std::string& contents,
hashes->push_back(std::string());
std::string* buffer = &(hashes->back());
buffer->resize(crypto::kSHA256Length);
- hash->Finish(base::string_as_array(buffer), buffer->size());
+ hash->Finish(base::data(*buffer), buffer->size());
// If |contents| is empty, then we want to just exit here.
if (bytes_to_read == 0)
diff --git a/chromium/extensions/browser/content_hash_fetcher_unittest.cc b/chromium/extensions/browser/content_hash_fetcher_unittest.cc
index 8f7b3829260..c38800cab75 100644
--- a/chromium/extensions/browser/content_hash_fetcher_unittest.cc
+++ b/chromium/extensions/browser/content_hash_fetcher_unittest.cc
@@ -180,7 +180,7 @@ class ContentHashFetcherTest : public ExtensionsTest {
// data dir.
base::FilePath GetTestPath(const base::FilePath& relative_path) {
base::FilePath base_path;
- EXPECT_TRUE(PathService::Get(extensions::DIR_TEST_DATA, &base_path));
+ EXPECT_TRUE(base::PathService::Get(extensions::DIR_TEST_DATA, &base_path));
base_path = base_path.AppendASCII("content_hash_fetcher");
return base_path.Append(relative_path);
}
diff --git a/chromium/extensions/browser/content_hash_tree.cc b/chromium/extensions/browser/content_hash_tree.cc
index e1298cf4ca0..2e2180f680d 100644
--- a/chromium/extensions/browser/content_hash_tree.cc
+++ b/chromium/extensions/browser/content_hash_tree.cc
@@ -41,8 +41,7 @@ std::string ComputeTreeHashRoot(const std::vector<std::string>& leaf_hashes,
++i;
}
parent_nodes.push_back(std::string(crypto::kSHA256Length, 0));
- std::string* output = &(parent_nodes.back());
- hash->Finish(base::string_as_array(output), output->size());
+ hash->Finish(base::data(parent_nodes.back()), crypto::kSHA256Length);
}
current_nodes.swap(parent_nodes);
parent_nodes.clear();
diff --git a/chromium/extensions/browser/content_hash_tree_unittest.cc b/chromium/extensions/browser/content_hash_tree_unittest.cc
index f9be82eb8b8..9f7281eb1ec 100644
--- a/chromium/extensions/browser/content_hash_tree_unittest.cc
+++ b/chromium/extensions/browser/content_hash_tree_unittest.cc
@@ -43,7 +43,7 @@ TEST(ContentHashTreeTest, HashTreeBasics) {
std::unique_ptr<SecureHash> hash(SecureHash::Create(SecureHash::SHA256));
hash->Update(node1.data(), node1.size());
hash->Update(node2.data(), node2.size());
- hash->Finish(base::string_as_array(&expected), expected.size());
+ hash->Finish(base::data(expected), expected.size());
EXPECT_EQ(expected, ComputeTreeHashRoot(nodes, 16));
}
diff --git a/chromium/extensions/browser/content_verifier/content_hash.cc b/chromium/extensions/browser/content_verifier/content_hash.cc
index f12b5889a8f..87a0a1a3879 100644
--- a/chromium/extensions/browser/content_verifier/content_hash.cc
+++ b/chromium/extensions/browser/content_verifier/content_hash.cc
@@ -46,8 +46,7 @@ std::unique_ptr<VerifiedContents> GetVerifiedContents(
bool delete_invalid_file) {
base::AssertBlockingAllowed();
DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence());
- auto verified_contents = std::make_unique<VerifiedContents>(
- key.verifier_key.data, key.verifier_key.size);
+ auto verified_contents = std::make_unique<VerifiedContents>(key.verifier_key);
base::FilePath verified_contents_path =
file_util::GetVerifiedContentsPath(key.extension_root);
if (!verified_contents->InitFrom(verified_contents_path)) {
@@ -65,12 +64,14 @@ std::unique_ptr<VerifiedContents> GetVerifiedContents(
ContentHash::ExtensionKey::ExtensionKey(const ExtensionId& extension_id,
const base::FilePath& extension_root,
const base::Version& extension_version,
- const ContentVerifierKey& verifier_key)
+ ContentVerifierKey verifier_key)
: extension_id(extension_id),
extension_root(extension_root),
extension_version(extension_version),
verifier_key(verifier_key) {}
+ContentHash::ExtensionKey::~ExtensionKey() = default;
+
ContentHash::ExtensionKey::ExtensionKey(
const ContentHash::ExtensionKey& other) = default;
diff --git a/chromium/extensions/browser/content_verifier/content_hash.h b/chromium/extensions/browser/content_verifier/content_hash.h
index 4e7d8079eb5..56e8f86a951 100644
--- a/chromium/extensions/browser/content_verifier/content_hash.h
+++ b/chromium/extensions/browser/content_verifier/content_hash.h
@@ -62,7 +62,8 @@ class ContentHash : public base::RefCountedThreadSafe<ContentHash> {
ExtensionKey(const ExtensionId& extension_id,
const base::FilePath& extension_root,
const base::Version& extension_version,
- const ContentVerifierKey& verifier_key);
+ ContentVerifierKey verifier_key);
+ ~ExtensionKey();
ExtensionKey(const ExtensionKey& other);
ExtensionKey& operator=(const ExtensionKey& other);
diff --git a/chromium/extensions/browser/content_verifier/content_verifier_key.h b/chromium/extensions/browser/content_verifier/content_verifier_key.h
index a4aa4013fbb..6cba2694830 100644
--- a/chromium/extensions/browser/content_verifier/content_verifier_key.h
+++ b/chromium/extensions/browser/content_verifier/content_verifier_key.h
@@ -5,19 +5,11 @@
#ifndef EXTENSIONS_BROWSER_CONTENT_VERIFIER_CONTENT_VERIFIER_KEY_H_
#define EXTENSIONS_BROWSER_CONTENT_VERIFIER_CONTENT_VERIFIER_KEY_H_
-#include <stdint.h>
+#include "base/containers/span.h"
namespace extensions {
-// A pointer to the bytes of a public key, and the number of bytes for content
-// verification.
-struct ContentVerifierKey {
- const uint8_t* data;
- size_t size;
-
- ContentVerifierKey(const uint8_t* data, size_t size)
- : data(data), size(size) {}
-};
+using ContentVerifierKey = base::span<const uint8_t>;
} // namespace extensions
diff --git a/chromium/extensions/browser/content_verifier_unittest.cc b/chromium/extensions/browser/content_verifier_unittest.cc
index a64c252d18b..73ed463fe8f 100644
--- a/chromium/extensions/browser/content_verifier_unittest.cc
+++ b/chromium/extensions/browser/content_verifier_unittest.cc
@@ -17,6 +17,7 @@
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/manifest_handlers/content_scripts_handler.h"
+#include "extensions/common/scoped_testing_manifest_handler_registry.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
@@ -78,8 +79,7 @@ class ContentVerifierTest
// Manually register handlers since the |ContentScriptsHandler| is not
// usually registered in extensions_unittests.
- ManifestHandlerRegistry registry;
- ManifestHandlerRegistry::SetForTesting(&registry);
+ ScopedTestingManifestHandlerRegistry registry;
(new BackgroundManifestHandler)->Register();
(new ContentScriptsHandler)->Register();
ManifestHandler::FinalizeRegistration();
@@ -152,7 +152,7 @@ class ContentVerifierTest
manifest.Set(manifest_keys::kContentScripts, std::move(content_scripts));
base::FilePath path;
- EXPECT_TRUE(PathService::Get(DIR_TEST_DATA, &path));
+ EXPECT_TRUE(base::PathService::Get(DIR_TEST_DATA, &path));
std::string error;
scoped_refptr<Extension> extension(Extension::Create(
diff --git a/chromium/extensions/browser/content_verify_job.cc b/chromium/extensions/browser/content_verify_job.cc
index 086b2fd8558..01cf9616b1e 100644
--- a/chromium/extensions/browser/content_verify_job.cc
+++ b/chromium/extensions/browser/content_verify_job.cc
@@ -90,6 +90,7 @@ void ContentVerifyJob::DidGetContentHashOnIO(
void ContentVerifyJob::BytesRead(int count, const char* data) {
base::AutoLock auto_lock(lock_);
+ DCHECK(!done_reading_);
BytesReadImpl(count, data);
}
@@ -100,6 +101,7 @@ void ContentVerifyJob::DoneReading() {
return;
if (g_ignore_verification_for_tests)
return;
+ DCHECK(!done_reading_);
done_reading_ = true;
if (hashes_ready_) {
if (!FinishBlock()) {
@@ -167,7 +169,7 @@ bool ContentVerifyJob::FinishBlock() {
current_hash_ = crypto::SecureHash::Create(crypto::SecureHash::SHA256);
}
std::string final(crypto::kSHA256Length, 0);
- current_hash_->Finish(base::string_as_array(& final), final.size());
+ current_hash_->Finish(base::data(final), final.size());
current_hash_.reset();
current_hash_byte_count_ = 0;
@@ -218,7 +220,7 @@ void ContentVerifyJob::OnHashesReady(
if (!queue_.empty()) {
std::string tmp;
queue_.swap(tmp);
- BytesReadImpl(tmp.size(), base::string_as_array(&tmp));
+ BytesReadImpl(tmp.size(), base::data(tmp));
if (failed_)
return;
}
diff --git a/chromium/extensions/browser/content_verify_job_unittest.cc b/chromium/extensions/browser/content_verify_job_unittest.cc
index dcea5263acc..07171f2ec01 100644
--- a/chromium/extensions/browser/content_verify_job_unittest.cc
+++ b/chromium/extensions/browser/content_verify_job_unittest.cc
@@ -54,7 +54,7 @@ class ContentVerifyJobUnittest : public ExtensionsTest {
// data dir.
base::FilePath GetTestPath(const std::string& relative_path) {
base::FilePath base_path;
- EXPECT_TRUE(PathService::Get(DIR_TEST_DATA, &base_path));
+ EXPECT_TRUE(base::PathService::Get(DIR_TEST_DATA, &base_path));
return base_path.AppendASCII("content_hash_fetcher")
.AppendASCII(relative_path);
}
@@ -97,7 +97,7 @@ class ContentVerifyJobUnittest : public ExtensionsTest {
std::string* resource_contents) {
// Simulate serving |resource_contents| from |resource_path|.
verify_job->BytesRead(resource_contents->size(),
- base::string_as_array(resource_contents));
+ base::data(*resource_contents));
verify_job->DoneReading();
};
diff --git a/chromium/extensions/browser/event_router.cc b/chromium/extensions/browser/event_router.cc
index 066571ff141..3bde19d9349 100644
--- a/chromium/extensions/browser/event_router.cc
+++ b/chromium/extensions/browser/event_router.cc
@@ -11,7 +11,6 @@
#include "base/atomic_sequence_num.h"
#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/values.h"
@@ -273,9 +272,9 @@ void EventRouter::OnListenerRemoved(const EventListener* listener) {
observer->second->OnListenerRemoved(details);
}
-void EventRouter::RenderProcessExited(content::RenderProcessHost* host,
- base::TerminationStatus status,
- int exit_code) {
+void EventRouter::RenderProcessExited(
+ content::RenderProcessHost* host,
+ const content::ChildProcessTerminationInfo& info) {
listeners_.RemoveListenersForProcess(host);
observed_process_set_.erase(host);
host->RemoveObserver(this);
diff --git a/chromium/extensions/browser/event_router.h b/chromium/extensions/browser/event_router.h
index b7d81347b9c..512ff10bfcc 100644
--- a/chromium/extensions/browser/event_router.h
+++ b/chromium/extensions/browser/event_router.h
@@ -340,9 +340,9 @@ class EventRouter : public KeyedService,
void OnListenerRemoved(const EventListener* listener) override;
// RenderProcessHostObserver implementation.
- void RenderProcessExited(content::RenderProcessHost* host,
- base::TerminationStatus status,
- int exit_code) override;
+ void RenderProcessExited(
+ content::RenderProcessHost* host,
+ const content::ChildProcessTerminationInfo& info) override;
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
content::BrowserContext* const browser_context_;
diff --git a/chromium/extensions/browser/extension_error_test_util.cc b/chromium/extensions/browser/extension_error_test_util.cc
index 8f42ec937c8..583fcc1dba2 100644
--- a/chromium/extensions/browser/extension_error_test_util.cc
+++ b/chromium/extensions/browser/extension_error_test_util.cc
@@ -39,7 +39,7 @@ std::unique_ptr<ExtensionError> CreateNewRuntimeError(
new RuntimeError(extension_id, from_incognito, source,
base::UTF8ToUTF16(message), stack_trace,
GURL::EmptyGURL(), // no context url
- logging::LOG_INFO,
+ logging::LOG_ERROR,
0, // Render frame id
0)); // Render process id
}
diff --git a/chromium/extensions/browser/extension_event_histogram_value.h b/chromium/extensions/browser/extension_event_histogram_value.h
index e8ab2167436..11bc707d137 100644
--- a/chromium/extensions/browser/extension_event_histogram_value.h
+++ b/chromium/extensions/browser/extension_event_histogram_value.h
@@ -431,6 +431,13 @@ enum HistogramValue {
OMNIBOX_ON_DELETE_SUGGESTION,
VIRTUAL_KEYBOARD_PRIVATE_ON_KEYBOARD_CONFIG_CHANGED,
PASSWORDS_PRIVATE_ON_PASSWORDS_FILE_EXPORT_PROGRESS,
+ SAFE_BROWSING_PRIVATE_ON_POLICY_SPECIFIED_PASSWORD_REUSE_DETECTED,
+ SAFE_BROWSING_PRIVATE_ON_POLICY_SPECIFIED_PASSWORD_CHANGED,
+ SAFE_BROWSING_PRIVATE_ON_DANGEROUS_DOWNLOAD_OPENED,
+ SAFE_BROWSING_PRIVATE_ON_SECURITY_INTERSTITIAL_SHOWN,
+ SAFE_BROWSING_PRIVATE_ON_SECURITY_INTERSTITIAL_PROCEEDED,
+ ACCESSIBILITY_PRIVATE_ON_SELECT_TO_SPEAK_STATE_CHANGE_REQUESTED,
+ INPUT_METHOD_PRIVATE_ON_FOCUS,
// Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY
diff --git a/chromium/extensions/browser/extension_function.cc b/chromium/extensions/browser/extension_function.cc
index a093683ab40..2c14386244f 100644
--- a/chromium/extensions/browser/extension_function.cc
+++ b/chromium/extensions/browser/extension_function.cc
@@ -564,14 +564,6 @@ void UIThreadExtensionFunction::SetRenderFrameHost(
render_frame_host ? new RenderFrameHostTracker(this) : nullptr);
}
-content::WebContents* UIThreadExtensionFunction::GetAssociatedWebContents() {
- content::WebContents* web_contents = NULL;
- if (dispatcher())
- web_contents = dispatcher()->GetAssociatedWebContents();
-
- return web_contents;
-}
-
content::WebContents* UIThreadExtensionFunction::GetSenderWebContents() {
return render_frame_host_ ?
content::WebContents::FromRenderFrameHost(render_frame_host_) : nullptr;
diff --git a/chromium/extensions/browser/extension_function.h b/chromium/extensions/browser/extension_function.h
index 7b5d3b6a53d..0b70be6cfa6 100644
--- a/chromium/extensions/browser/extension_function.h
+++ b/chromium/extensions/browser/extension_function.h
@@ -538,12 +538,6 @@ class UIThreadExtensionFunction : public ExtensionFunction {
service_worker_version_id_ = version_id;
}
- // Gets the "current" web contents if any. If there is no associated web
- // contents then defaults to the foremost one.
- // NOTE: "current" can mean different things in different contexts. You
- // probably want to use GetSenderWebContents().
- virtual content::WebContents* GetAssociatedWebContents();
-
// Returns the web contents associated with the sending |render_frame_host_|.
// This can be null.
content::WebContents* GetSenderWebContents();
diff --git a/chromium/extensions/browser/extension_function_constants.cc b/chromium/extensions/browser/extension_function_constants.cc
new file mode 100644
index 00000000000..423a6ba6a4e
--- /dev/null
+++ b/chromium/extensions/browser/extension_function_constants.cc
@@ -0,0 +1,20 @@
+// Copyright 2018 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 "extensions/browser/extension_function_constants.h"
+
+namespace extensions {
+namespace function_constants {
+
+// An error thrown when determining the WebContents that sent the request for
+// the API call failed. Note: typically, this would only happen if the
+// WebContents disappeared after the API call (i.e., the caller is no longer
+// alive, such as a tab closing or background page suspending). For this reason,
+// the error is not overly helpful. However, it is important that we have a
+// specific error message in order to track down any peculiar cases.
+const char kCouldNotFindSenderWebContents[] =
+ "Could not find sender WebContents.";
+
+} // namespace function_constants
+} // namespace extensions
diff --git a/chromium/extensions/browser/extension_function_constants.h b/chromium/extensions/browser/extension_function_constants.h
new file mode 100644
index 00000000000..9fe331bad28
--- /dev/null
+++ b/chromium/extensions/browser/extension_function_constants.h
@@ -0,0 +1,17 @@
+// Copyright 2018 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 EXTENSIONS_BROWSER_EXTENSION_FUNCTION_CONSTANTS_H_
+#define EXTENSIONS_BROWSER_EXTENSION_FUNCTION_CONSTANTS_H_
+
+namespace extensions {
+namespace function_constants {
+
+// TODO(devlin): Move ExtensionFunction::kUnknownErrorDoNotUse here.
+extern const char kCouldNotFindSenderWebContents[];
+
+} // namespace function_constants
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_CONSTANTS_H_
diff --git a/chromium/extensions/browser/extension_function_dispatcher.cc b/chromium/extensions/browser/extension_function_dispatcher.cc
index 84143680b9f..249fd4c34ea 100644
--- a/chromium/extensions/browser/extension_function_dispatcher.cc
+++ b/chromium/extensions/browser/extension_function_dispatcher.cc
@@ -186,9 +186,9 @@ class ExtensionFunctionDispatcher::UIThreadWorkerResponseCallbackWrapper
~UIThreadWorkerResponseCallbackWrapper() override {}
// content::RenderProcessHostObserver override.
- void RenderProcessExited(content::RenderProcessHost* rph,
- base::TerminationStatus status,
- int exit_code) override {
+ void RenderProcessExited(
+ content::RenderProcessHost* rph,
+ const content::ChildProcessTerminationInfo& info) override {
CleanUp();
}
diff --git a/chromium/extensions/browser/extension_function_histogram_value.h b/chromium/extensions/browser/extension_function_histogram_value.h
index a119ce9d737..4b5f1c5096b 100644
--- a/chromium/extensions/browser/extension_function_histogram_value.h
+++ b/chromium/extensions/browser/extension_function_histogram_value.h
@@ -1302,6 +1302,21 @@ enum HistogramValue {
FILEMANAGERPRIVATE_ENSUREFILEDOWNLOADED,
FILEMANAGERPRIVATE_OPENSETTINGSSUBPAGE,
ENTERPRISEREPORTINGPRIVATE_UPLOADCHROMEDESKTOPREPORT,
+ CECPRIVATE_SENDSTANDBY,
+ CECPRIVATE_SENDWAKEUP,
+ WEBSTOREPRIVATE_GETREFERRERCHAIN,
+ AUTOTESTPRIVATE_UPDATEPRINTER,
+ AUTOTESTPRIVATE_REMOVEPRINTER,
+ WALLPAPERPRIVATE_GETCURRENTWALLPAPERTHUMBNAIL,
+ ACCESSIBILITY_PRIVATE_ONSELECTTOSPEAKSTATECHANGED,
+ INPUTMETHODPRIVATE_GETCOMPOSITIONBOUNDS,
+ FILEMANAGERPRIVATE_ISCROSTINIENABLED,
+ FILEMANAGERPRIVATE_MOUNTCROSTINICONTAINER,
+ CECPRIVATE_QUERYDISPLAYCECPOWERSTATE,
+ DEVELOPERPRIVATE_ADDHOSTPERMISSION,
+ DEVELOPERPRIVATE_REMOVEHOSTPERMISSION,
+ MEDIAPERCEPTIONPRIVATE_SETCOMPONENTPROCESSSTATE,
+ USERSPRIVATE_GETCURRENTUSER,
// Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY
diff --git a/chromium/extensions/browser/extension_host.cc b/chromium/extensions/browser/extension_host.cc
index a5a82184012..294243d2e7d 100644
--- a/chromium/extensions/browser/extension_host.cc
+++ b/chromium/extensions/browser/extension_host.cc
@@ -68,8 +68,8 @@ ExtensionHost::ExtensionHost(const Extension* extension,
DCHECK(host_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE ||
host_type == VIEW_TYPE_EXTENSION_DIALOG ||
host_type == VIEW_TYPE_EXTENSION_POPUP);
- host_contents_.reset(WebContents::Create(
- WebContents::CreateParams(browser_context_, site_instance))),
+ host_contents_ = WebContents::Create(
+ WebContents::CreateParams(browser_context_, site_instance)),
content::WebContentsObserver::Observe(host_contents_.get());
host_contents_->SetDelegate(this);
SetViewType(host_contents_.get(), host_type);
@@ -389,7 +389,7 @@ content::JavaScriptDialogManager* ExtensionHost::GetJavaScriptDialogManager(
}
void ExtensionHost::AddNewContents(WebContents* source,
- WebContents* new_contents,
+ std::unique_ptr<WebContents> new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
@@ -409,16 +409,16 @@ void ExtensionHost::AddNewContents(WebContents* source,
new_contents->GetBrowserContext()) {
WebContentsDelegate* delegate = associated_contents->GetDelegate();
if (delegate) {
- delegate->AddNewContents(
- associated_contents, new_contents, disposition, initial_rect,
- user_gesture, was_blocked);
+ delegate->AddNewContents(associated_contents, std::move(new_contents),
+ disposition, initial_rect, user_gesture,
+ was_blocked);
return;
}
}
}
- delegate_->CreateTab(
- new_contents, extension_id_, disposition, initial_rect, user_gesture);
+ delegate_->CreateTab(std::move(new_contents), extension_id_, disposition,
+ initial_rect, user_gesture);
}
void ExtensionHost::RenderViewReady() {
diff --git a/chromium/extensions/browser/extension_host.h b/chromium/extensions/browser/extension_host.h
index c93e3a48c7e..8c7a96fdc17 100644
--- a/chromium/extensions/browser/extension_host.h
+++ b/chromium/extensions/browser/extension_host.h
@@ -113,7 +113,7 @@ class ExtensionHost : public DeferredStartRenderHost,
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
void AddNewContents(content::WebContents* source,
- content::WebContents* new_contents,
+ std::unique_ptr<content::WebContents> new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
diff --git a/chromium/extensions/browser/extension_host_delegate.h b/chromium/extensions/browser/extension_host_delegate.h
index a7c908cde91..c7b0096651f 100644
--- a/chromium/extensions/browser/extension_host_delegate.h
+++ b/chromium/extensions/browser/extension_host_delegate.h
@@ -45,7 +45,7 @@ class ExtensionHostDelegate {
// Creates a new tab or popup window with |web_contents|. The embedder may
// choose to do nothing if tabs and popups are not supported.
- virtual void CreateTab(content::WebContents* web_contents,
+ virtual void CreateTab(std::unique_ptr<content::WebContents> web_contents,
const std::string& extension_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
diff --git a/chromium/extensions/browser/extension_icon_image_unittest.cc b/chromium/extensions/browser/extension_icon_image_unittest.cc
index c823bd2fc2f..9ef5962c8d5 100644
--- a/chromium/extensions/browser/extension_icon_image_unittest.cc
+++ b/chromium/extensions/browser/extension_icon_image_unittest.cc
@@ -87,7 +87,7 @@ class ExtensionIconImageTest : public ExtensionsTest,
Manifest::Location location) {
// Create and load an extension.
base::FilePath test_file;
- if (!PathService::Get(DIR_TEST_DATA, &test_file)) {
+ if (!base::PathService::Get(DIR_TEST_DATA, &test_file)) {
EXPECT_FALSE(true);
return NULL;
}
diff --git a/chromium/extensions/browser/extension_navigation_throttle.cc b/chromium/extensions/browser/extension_navigation_throttle.cc
index 9ff926c267d..880a1b8b25d 100644
--- a/chromium/extensions/browser/extension_navigation_throttle.cc
+++ b/chromium/extensions/browser/extension_navigation_throttle.cc
@@ -85,13 +85,6 @@ ExtensionNavigationThrottle::WillStartOrRedirectRequest() {
navigation_handle()->GetStartingSiteInstance()->GetSiteURL());
if (!url_has_extension_scheme && !current_frame_is_extension_process) {
- // Relax this restriction for navigations that will result in downloads.
- // See https://crbug.com/714373.
- if (target_origin.scheme() == kExtensionScheme &&
- navigation_handle()->GetSuggestedFilename().has_value()) {
- return content::NavigationThrottle::PROCEED;
- }
-
// Relax this restriction for apps that use <webview>. See
// https://crbug.com/652077.
bool has_webview_permission =
diff --git a/chromium/extensions/browser/extension_pref_value_map_unittest.cc b/chromium/extensions/browser/extension_pref_value_map_unittest.cc
index 36c2fb936d7..5c0c7289915 100644
--- a/chromium/extensions/browser/extension_pref_value_map_unittest.cc
+++ b/chromium/extensions/browser/extension_pref_value_map_unittest.cc
@@ -76,7 +76,7 @@ class ExtensionPrefValueMapObserverMock
: public ExtensionPrefValueMap::Observer {
public:
ExtensionPrefValueMapObserverMock() {}
- virtual ~ExtensionPrefValueMapObserverMock() {}
+ ~ExtensionPrefValueMapObserverMock() override {}
MOCK_METHOD1(OnPrefValueChanged, void(const std::string&));
MOCK_METHOD0(OnInitializationCompleted, void());
diff --git a/chromium/extensions/browser/extension_protocols.cc b/chromium/extensions/browser/extension_protocols.cc
index 56b5cb968c4..543b08cedae 100644
--- a/chromium/extensions/browser/extension_protocols.cc
+++ b/chromium/extensions/browser/extension_protocols.cc
@@ -21,7 +21,6 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_functions.h"
@@ -263,7 +262,7 @@ class URLRequestExtensionJob : public net::URLRequestFileJob {
// proceed; see crbug.com/703888.
if (verify_job_.get()) {
std::string tmp;
- verify_job_->BytesRead(0, base::string_as_array(&tmp));
+ verify_job_->BytesRead(0, base::data(tmp));
verify_job_->DoneReading();
}
}
@@ -695,20 +694,6 @@ class FileLoaderObserver : public content::FileURLLoaderObserver {
request_timer_.reset(new base::ElapsedTimer());
}
- void OnOpenComplete(int result) override {
- if (result < 0) {
- // This can happen when the file is unreadable (which can happen during
- // corruption or third-party interaction). We need to be sure to inform
- // the verification job that we've finished reading so that it can
- // proceed; see crbug.com/703888.
- if (verify_job_.get()) {
- std::string tmp;
- verify_job_->BytesRead(0, base::string_as_array(&tmp));
- verify_job_->DoneReading();
- }
- }
- }
-
void OnSeekComplete(int64_t result) override {
DCHECK_EQ(seek_position_, 0);
base::AutoLock auto_lock(lock_);
@@ -755,17 +740,30 @@ class FileLoaderObserver : public content::FileURLLoaderObserver {
class ExtensionURLLoaderFactory : public network::mojom::URLLoaderFactory {
public:
- // |frame_host| is the RenderFrameHost which is either being navigated or
- // loading a subresource. For navigation requests, |frame_url| is empty; for
- // subresource requests it's the URL of the currently committed navigation on
- // |frame_host|.
- explicit ExtensionURLLoaderFactory(
- content::RenderFrameHost* frame_host,
- const GURL& frame_url,
- scoped_refptr<extensions::InfoMap> extension_info_map)
- : frame_host_(frame_host),
- frame_url_(frame_url),
- extension_info_map_(std::move(extension_info_map)) {}
+ ExtensionURLLoaderFactory(int render_process_id, int render_frame_id)
+ : render_process_id_(render_process_id) {
+ content::RenderProcessHost* process_host =
+ content::RenderProcessHost::FromID(render_process_id);
+ browser_context_ = process_host->GetBrowserContext();
+ is_web_view_request_ = WebViewGuest::FromFrameID(
+ render_process_id_, render_frame_id) != nullptr;
+ Init();
+ }
+
+ ExtensionURLLoaderFactory(content::BrowserContext* browser_context,
+ bool is_web_view_request)
+ : browser_context_(browser_context),
+ is_web_view_request_(is_web_view_request),
+ render_process_id_(-1) {
+ Init();
+ }
+
+ void Init() {
+ extension_info_map_ =
+ extensions::ExtensionSystem::Get(browser_context_)->info_map();
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ }
+
~ExtensionURLLoaderFactory() override = default;
// network::mojom::URLLoaderFactory:
@@ -779,23 +777,21 @@ class ExtensionURLLoaderFactory : public network::mojom::URLLoaderFactory {
traffic_annotation) override {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!request.download_to_file);
- const content::RenderProcessHost* process_host = frame_host_->GetProcess();
- BrowserContext* browser_context = process_host->GetBrowserContext();
const std::string extension_id = request.url.host();
- ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
+ ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
scoped_refptr<const Extension> extension =
registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
const ExtensionSet& enabled_extensions = registry->enabled_extensions();
- const ProcessMap* process_map = ProcessMap::Get(browser_context);
+ const ProcessMap* process_map = ProcessMap::Get(browser_context_);
bool incognito_enabled =
- extensions::util::IsIncognitoEnabled(extension_id, browser_context);
+ extensions::util::IsIncognitoEnabled(extension_id, browser_context_);
if (!AllowExtensionResourceLoad(
request.url,
static_cast<content::ResourceType>(request.resource_type),
static_cast<ui::PageTransition>(request.transition_type),
- process_host->GetID(), browser_context->IsOffTheRecord(),
+ render_process_id_, browser_context_->IsOffTheRecord(),
extension.get(), incognito_enabled, enabled_extensions,
*process_map)) {
client->OnComplete(
@@ -830,13 +826,9 @@ class ExtensionURLLoaderFactory : public network::mojom::URLLoaderFactory {
bool send_cors_header = false;
bool follow_symlinks_anywhere = false;
if (extension) {
- const bool is_web_view_request =
- WebViewGuest::FromWebContents(
- content::WebContents::FromRenderFrameHost(frame_host_)) !=
- nullptr;
- GetSecurityPolicyForURL(request.url, extension.get(), is_web_view_request,
- &content_security_policy, &send_cors_header,
- &follow_symlinks_anywhere);
+ GetSecurityPolicyForURL(request.url, extension.get(),
+ is_web_view_request_, &content_security_policy,
+ &send_cors_header, &follow_symlinks_anywhere);
}
if (IsBackgroundPageURL(request.url)) {
@@ -900,9 +892,7 @@ class ExtensionURLLoaderFactory : public network::mojom::URLLoaderFactory {
std::string new_relative_path;
SharedModuleInfo::ParseImportedPath(path, &new_extension_id,
&new_relative_path);
- BrowserContext* browser_context =
- frame_host_->GetProcess()->GetBrowserContext();
- ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
+ ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
const Extension* new_extension =
registry->enabled_extensions().GetByID(new_extension_id);
if (SharedModuleInfo::ImportsExtensionById(extension.get(),
@@ -986,8 +976,12 @@ class ExtensionURLLoaderFactory : public network::mojom::URLLoaderFactory {
std::move(response_headers));
}
- content::RenderFrameHost* const frame_host_;
- const GURL frame_url_;
+ content::BrowserContext* browser_context_;
+ bool is_web_view_request_;
+ // We store the ID and get RenderProcessHost each time it's needed. This is to
+ // avoid holding on to stale pointers if we get requests past the lifetime of
+ // the objects.
+ const int render_process_id_;
scoped_refptr<extensions::InfoMap> extension_info_map_;
mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
@@ -1047,29 +1041,16 @@ void SetExtensionProtocolTestHandler(ExtensionProtocolTestHandler* handler) {
std::unique_ptr<network::mojom::URLLoaderFactory>
CreateExtensionNavigationURLLoaderFactory(
- content::RenderFrameHost* frame_host,
- scoped_refptr<extensions::InfoMap> extension_info_map) {
- return std::make_unique<ExtensionURLLoaderFactory>(
- frame_host, GURL(), std::move(extension_info_map));
+ content::BrowserContext* browser_context,
+ bool is_web_view_request) {
+ return std::make_unique<ExtensionURLLoaderFactory>(browser_context,
+ is_web_view_request);
}
std::unique_ptr<network::mojom::URLLoaderFactory>
-MaybeCreateExtensionSubresourceURLLoaderFactory(
- content::RenderFrameHost* frame_host,
- const GURL& frame_url,
- scoped_refptr<extensions::InfoMap> extension_info_map) {
- // Ensure we have a non-empty URL so that the factory we create knows it's
- // only for subresources.
- CHECK(!frame_url.is_empty());
-
- // TODO(rockot): We can probably avoid creating this factory in cases where
- // |frame_url| corresponds to a non-extensions URL and the URL in question
- // cannot have any active content scripts running and has no access to
- // any extension's web accessible resources. For now we always create a
- // factory, because the loader itself correctly prevents disallowed resources
- // from loading in an invalid context.
- return std::make_unique<ExtensionURLLoaderFactory>(
- frame_host, frame_url, std::move(extension_info_map));
+CreateExtensionURLLoaderFactory(int render_process_id, int render_frame_id) {
+ return std::make_unique<ExtensionURLLoaderFactory>(render_process_id,
+ render_frame_id);
}
} // namespace extensions
diff --git a/chromium/extensions/browser/extension_protocols.h b/chromium/extensions/browser/extension_protocols.h
index 4188fdc6f2a..1ddcd71d3ee 100644
--- a/chromium/extensions/browser/extension_protocols.h
+++ b/chromium/extensions/browser/extension_protocols.h
@@ -19,15 +19,13 @@ class Time;
}
namespace content {
-class RenderFrameHost;
+class BrowserContext;
}
namespace net {
class HttpResponseHeaders;
}
-class GURL;
-
namespace extensions {
class InfoMap;
@@ -57,18 +55,18 @@ void SetExtensionProtocolTestHandler(ExtensionProtocolTestHandler* handler);
// handling navigation requests to extension URLs.
std::unique_ptr<network::mojom::URLLoaderFactory>
CreateExtensionNavigationURLLoaderFactory(
- content::RenderFrameHost* frame_host,
- scoped_refptr<extensions::InfoMap> extension_info_map);
-
-// Attempts to create a network::mojom::URLLoaderFactory implementation suitable
-// for handling subresource requests for extension URLs from |frame_host|. May
-// return null if |frame_host| is never allowed to load extension subresources
-// from its current navigation URL.
+ content::BrowserContext* browser_context,
+ bool is_web_view_request);
+
+// Creates a network::mojom::URLLoaderFactory implementation suitable for
+// handling subresource requests for extension URLs for the frame identified by
+// |render_process_id| and |render_frame_id|.
+// This function can also be used to make a factory for other non-subresource
+// requests to extension URLs, such as for the service worker script when
+// starting a service worker. In that case, render_frame_id will be
+// MSG_ROUTING_NONE.
std::unique_ptr<network::mojom::URLLoaderFactory>
-MaybeCreateExtensionSubresourceURLLoaderFactory(
- content::RenderFrameHost* frame_host,
- const GURL& frame_url,
- scoped_refptr<extensions::InfoMap> extension_info_map);
+CreateExtensionURLLoaderFactory(int render_process_id, int render_frame_id);
} // namespace extensions
diff --git a/chromium/extensions/browser/extension_system.h b/chromium/extensions/browser/extension_system.h
index 21ea3b6d691..303b2277075 100644
--- a/chromium/extensions/browser/extension_system.h
+++ b/chromium/extensions/browser/extension_system.h
@@ -9,8 +9,10 @@
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "build/build_config.h"
#include "components/keyed_service/core/keyed_service.h"
+#include "extensions/browser/install/crx_install_error.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension.h"
@@ -47,7 +49,8 @@ class ValueStoreFactory;
class ExtensionSystem : public KeyedService {
public:
// A callback to be executed when InstallUpdate finishes.
- using InstallUpdateCallback = base::OnceCallback<void(bool success)>;
+ using InstallUpdateCallback =
+ base::OnceCallback<void(const base::Optional<CrxInstallError>& result)>;
ExtensionSystem();
~ExtensionSystem() override;
diff --git a/chromium/extensions/browser/file_reader_unittest.cc b/chromium/extensions/browser/file_reader_unittest.cc
index dcee191f88e..b839f5c8c71 100644
--- a/chromium/extensions/browser/file_reader_unittest.cc
+++ b/chromium/extensions/browser/file_reader_unittest.cc
@@ -62,7 +62,7 @@ class Receiver {
void RunBasicTest(const char* filename) {
base::FilePath path;
- PathService::Get(DIR_TEST_DATA, &path);
+ base::PathService::Get(DIR_TEST_DATA, &path);
std::string extension_id = crx_file::id_util::GenerateId("test");
ExtensionResource resource(
extension_id, path, base::FilePath().AppendASCII(filename));
@@ -88,7 +88,7 @@ TEST_F(FileReaderTest, BiggerFile) {
TEST_F(FileReaderTest, NonExistantFile) {
base::FilePath path;
- PathService::Get(DIR_TEST_DATA, &path);
+ base::PathService::Get(DIR_TEST_DATA, &path);
std::string extension_id = crx_file::id_util::GenerateId("test");
ExtensionResource resource(extension_id, path, base::FilePath(
FILE_PATH_LITERAL("file_that_does_not_exist")));
diff --git a/chromium/extensions/browser/guest_view/app_view/app_view_apitest.cc b/chromium/extensions/browser/guest_view/app_view/app_view_apitest.cc
index b6a87bf948b..28a1dfde439 100644
--- a/chromium/extensions/browser/guest_view/app_view/app_view_apitest.cc
+++ b/chromium/extensions/browser/guest_view/app_view/app_view_apitest.cc
@@ -116,7 +116,7 @@ class AppViewTest : public AppShellTest,
const Extension* LoadApp(const std::string& app_location) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath test_data_dir;
- PathService::Get(DIR_TEST_DATA, &test_data_dir);
+ base::PathService::Get(DIR_TEST_DATA, &test_data_dir);
test_data_dir = test_data_dir.AppendASCII(app_location.c_str());
return extension_system_->LoadApp(test_data_dir);
}
diff --git a/chromium/extensions/browser/guest_view/app_view/app_view_guest.cc b/chromium/extensions/browser/guest_view/app_view/app_view_guest.cc
index 6ca37ed2230..af1c95c7fa2 100644
--- a/chromium/extensions/browser/guest_view/app_view/app_view_guest.cc
+++ b/chromium/extensions/browser/guest_view/app_view/app_view_guest.cc
@@ -247,7 +247,9 @@ void AppViewGuest::CompleteCreateWebContents(
content::SiteInstance::CreateForURL(browser_context(),
guest_extension->url()));
params.guest_delegate = this;
- callback.Run(WebContents::Create(params));
+ // TODO(erikchen): Fix ownership semantics for guest views.
+ // https://crbug.com/832879.
+ callback.Run(WebContents::Create(params).release());
}
void AppViewGuest::LaunchAppAndFireEvent(
diff --git a/chromium/extensions/browser/guest_view/extension_options/extension_options_apitest.cc b/chromium/extensions/browser/guest_view/extension_options/extension_options_apitest.cc
index 7e69ab7bcc0..8abfe07e7ac 100644
--- a/chromium/extensions/browser/guest_view/extension_options/extension_options_apitest.cc
+++ b/chromium/extensions/browser/guest_view/extension_options/extension_options_apitest.cc
@@ -18,10 +18,10 @@
using extensions::Extension;
using extensions::FeatureSwitch;
-class ExtensionOptionsApiTest : public ExtensionApiTest,
+class ExtensionOptionsApiTest : public extensions::ExtensionApiTest,
public testing::WithParamInterface<bool> {
void SetUpCommandLine(base::CommandLine* command_line) override {
- ExtensionApiTest::SetUpCommandLine(command_line);
+ extensions::ExtensionApiTest::SetUpCommandLine(command_line);
bool use_cross_process_frames_for_guests = GetParam();
if (use_cross_process_frames_for_guests) {
diff --git a/chromium/extensions/browser/guest_view/extension_options/extension_options_guest.cc b/chromium/extensions/browser/guest_view/extension_options/extension_options_guest.cc
index 1a748720200..53d7ee31c07 100644
--- a/chromium/extensions/browser/guest_view/extension_options/extension_options_guest.cc
+++ b/chromium/extensions/browser/guest_view/extension_options/extension_options_guest.cc
@@ -110,9 +110,9 @@ void ExtensionOptionsGuest::CreateWebContents(
browser_context(),
content::SiteInstance::CreateForURL(browser_context(), extension_url));
params.guest_delegate = this;
- WebContents* wc = WebContents::Create(params);
- SetViewType(wc, VIEW_TYPE_EXTENSION_GUEST);
- callback.Run(wc);
+ // TODO(erikchen): Fix ownership semantics for guest views.
+ // https://crbug.com/832879.
+ callback.Run(WebContents::Create(params).release());
}
void ExtensionOptionsGuest::DidInitialize(
@@ -152,17 +152,23 @@ void ExtensionOptionsGuest::OnPreferredSizeChanged(const gfx::Size& pref_size) {
options.ToValue()));
}
-void ExtensionOptionsGuest::AddNewContents(WebContents* source,
- WebContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_rect,
- bool user_gesture,
- bool* was_blocked) {
+void ExtensionOptionsGuest::AddNewContents(
+ WebContents* source,
+ std::unique_ptr<WebContents> new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_rect,
+ bool user_gesture,
+ bool* was_blocked) {
+ // |new_contents| is potentially used as a non-embedded WebContents, so we
+ // check that it isn't a guest. The only place that this method should be
+ // called is WebContentsImpl::ViewSource - which generates a non-guest
+ // WebContents.
+ DCHECK(!ExtensionOptionsGuest::FromWebContents(new_contents.get()));
if (!attached() || !embedder_web_contents()->GetDelegate())
return;
embedder_web_contents()->GetDelegate()->AddNewContents(
- source, new_contents, disposition, initial_rect, user_gesture,
+ source, std::move(new_contents), disposition, initial_rect, user_gesture,
was_blocked);
}
diff --git a/chromium/extensions/browser/guest_view/extension_options/extension_options_guest.h b/chromium/extensions/browser/guest_view/extension_options/extension_options_guest.h
index 12250fc127d..9ff1ba65bd5 100644
--- a/chromium/extensions/browser/guest_view/extension_options/extension_options_guest.h
+++ b/chromium/extensions/browser/guest_view/extension_options/extension_options_guest.h
@@ -39,7 +39,7 @@ class ExtensionOptionsGuest
// content::WebContentsDelegate implementation.
void AddNewContents(content::WebContents* source,
- content::WebContents* new_contents,
+ std::unique_ptr<content::WebContents> new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
diff --git a/chromium/extensions/browser/guest_view/extension_view/extension_view_guest.cc b/chromium/extensions/browser/guest_view/extension_view/extension_view_guest.cc
index 34a16b9c547..2d4dd61c9e9 100644
--- a/chromium/extensions/browser/guest_view/extension_view/extension_view_guest.cc
+++ b/chromium/extensions/browser/guest_view/extension_view/extension_view_guest.cc
@@ -93,7 +93,9 @@ void ExtensionViewGuest::CreateWebContents(
browser_context(),
content::SiteInstance::CreateForURL(browser_context(), extension_url_));
params.guest_delegate = this;
- callback.Run(WebContents::Create(params));
+ // TODO(erikchen): Fix ownership semantics for guest views.
+ // https://crbug.com/832879.
+ callback.Run(WebContents::Create(params).release());
}
void ExtensionViewGuest::DidInitialize(
diff --git a/chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc b/chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc
index 1661c0c6582..ffa79cf2918 100644
--- a/chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc
+++ b/chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc
@@ -24,6 +24,7 @@
#include "extensions/browser/guest_view/web_view/web_view_guest.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_map.h"
+#include "extensions/browser/view_type_utils.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
@@ -40,6 +41,12 @@ ExtensionsGuestViewManagerDelegate::ExtensionsGuestViewManagerDelegate(
ExtensionsGuestViewManagerDelegate::~ExtensionsGuestViewManagerDelegate() {
}
+void ExtensionsGuestViewManagerDelegate::OnGuestAdded(
+ content::WebContents* guest_web_contents) const {
+ // Set the view type so extensions sees the guest view as a foreground page.
+ SetViewType(guest_web_contents, VIEW_TYPE_EXTENSION_GUEST);
+}
+
void ExtensionsGuestViewManagerDelegate::DispatchEvent(
const std::string& event_name,
std::unique_ptr<base::DictionaryValue> args,
diff --git a/chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.h b/chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.h
index 8bbdf1d38da..211e602acee 100644
--- a/chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.h
+++ b/chromium/extensions/browser/guest_view/extensions_guest_view_manager_delegate.h
@@ -22,6 +22,7 @@ class ExtensionsGuestViewManagerDelegate
~ExtensionsGuestViewManagerDelegate() override;
// GuestViewManagerDelegate implementation.
+ void OnGuestAdded(content::WebContents* guest_web_contents) const override;
void DispatchEvent(const std::string& event_name,
std::unique_ptr<base::DictionaryValue> args,
guest_view::GuestViewBase* guest,
diff --git a/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc b/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
index 7a8be11115b..59b822431b2 100644
--- a/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
+++ b/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
@@ -25,8 +25,7 @@
#include "extensions/browser/process_manager.h"
#include "extensions/test/result_catcher.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "net/url_request/url_request_filter.h"
-#include "net/url_request/url_request_interceptor.h"
+#include "net/test/embedded_test_server/http_request.h"
using extensions::ExtensionsAPIClient;
using extensions::MimeHandlerViewGuest;
@@ -39,89 +38,7 @@ using guest_view::TestGuestViewManagerFactory;
// The test extension id is set by the key value in the manifest.
const char kExtensionId[] = "oickdpebdnfbgkcaoklfcdhjniefkcji";
-// Counts the number of URL requests made for a given URL.
-class URLRequestCounter {
- public:
- explicit URLRequestCounter(const GURL& url) : url_(url), count_(0) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- base::RunLoop run_loop;
- content::BrowserThread::PostTaskAndReply(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&URLRequestCounter::AddInterceptor, base::Unretained(this)),
- run_loop.QuitClosure());
- run_loop.Run();
- }
-
- ~URLRequestCounter() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- base::RunLoop run_loop;
- content::BrowserThread::PostTaskAndReply(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&URLRequestCounter::RemoveInterceptor,
- base::Unretained(this)),
- run_loop.QuitClosure());
- run_loop.Run();
- }
-
- int GetCount() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- // Do a round-trip to the IO thread to guarantee that the UI thread has
- // been notified of all the requests triggered by the IO thread.
- base::RunLoop run_loop;
- content::BrowserThread::PostTaskAndReply(content::BrowserThread::IO,
- FROM_HERE, base::DoNothing(),
- run_loop.QuitClosure());
- run_loop.Run();
- return count_;
- }
-
- private:
- // This class runs a callback when a URL request is intercepted. It doesn't
- // handle the request itself.
- class SimpleRequestInterceptor : public net::URLRequestInterceptor {
- public:
- explicit SimpleRequestInterceptor(const base::Closure& callback)
- : callback_(callback) {}
-
- // URLRequestInterceptor implementation:
- net::URLRequestJob* MaybeInterceptRequest(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const override {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- callback_);
- return nullptr;
- }
-
- private:
- const base::Closure callback_;
- };
-
- void RequestFired() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- ++count_;
- }
-
- void AddInterceptor() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
- url_, std::make_unique<SimpleRequestInterceptor>(base::Bind(
- &URLRequestCounter::RequestFired, base::Unretained(this))));
- }
-
- void RemoveInterceptor() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- net::URLRequestFilter::GetInstance()->RemoveUrlHandler(url_);
- }
-
- const GURL url_;
- // |count_| is only accessed on the UI thread.
- int count_;
-
- DISALLOW_COPY_AND_ASSIGN(URLRequestCounter);
-};
-
-class MimeHandlerViewTest : public ExtensionApiTest,
+class MimeHandlerViewTest : public extensions::ExtensionApiTest,
public testing::WithParamInterface<bool> {
public:
MimeHandlerViewTest() {
@@ -131,10 +48,12 @@ class MimeHandlerViewTest : public ExtensionApiTest,
~MimeHandlerViewTest() override {}
void SetUpOnMainThread() override {
- ExtensionApiTest::SetUpOnMainThread();
+ extensions::ExtensionApiTest::SetUpOnMainThread();
embedded_test_server()->ServeFilesFromDirectory(
test_data_dir_.AppendASCII("mime_handler_view"));
+ embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
+ &MimeHandlerViewTest::MonitorRequest, base::Unretained(this)));
ASSERT_TRUE(StartEmbeddedTestServer());
}
@@ -144,7 +63,7 @@ class MimeHandlerViewTest : public ExtensionApiTest,
// MimeHandlerViewGuest will be based on OOPIF and we can remove this comment
// (https://crbug.com/642826).
void SetUpCommandLine(base::CommandLine* command_line) override {
- ExtensionApiTest::SetUpCommandLine(command_line);
+ extensions::ExtensionApiTest::SetUpCommandLine(command_line);
bool use_cross_process_frames_for_guests = GetParam();
if (use_cross_process_frames_for_guests) {
@@ -207,9 +126,17 @@ class MimeHandlerViewTest : public ExtensionApiTest,
RunTestWithUrl(embedded_test_server()->GetURL("/" + path));
}
+ int basic_count() const { return basic_count_; }
+
private:
+ void MonitorRequest(const net::test_server::HttpRequest& request) {
+ if (request.relative_url == "/testBasic.csv")
+ basic_count_++;
+ }
+
TestGuestViewManagerFactory factory_;
base::test::ScopedFeatureList scoped_feature_list_;
+ int basic_count_ = 0;
};
INSTANTIATE_TEST_CASE_P(MimeHandlerViewTests,
@@ -281,9 +208,8 @@ IN_PROC_BROWSER_TEST_P(MimeHandlerViewTest, ResizeBeforeAttach) {
// Regression test for crbug.com/587709.
IN_PROC_BROWSER_TEST_P(MimeHandlerViewTest, SingleRequest) {
GURL url(embedded_test_server()->GetURL("/testBasic.csv"));
- URLRequestCounter request_counter(url);
RunTest("testBasic.csv");
- EXPECT_EQ(1, request_counter.GetCount());
+ EXPECT_EQ(1, basic_count());
}
// Test that a mime handler view can keep a background page alive.
diff --git a/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
index 57e98ae8a5b..07f7fb42f53 100644
--- a/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
+++ b/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -193,9 +193,13 @@ void MimeHandlerViewGuest::CreateWebContents(
WebContents::CreateParams params(browser_context(),
guest_site_instance.get());
params.guest_delegate = this;
- auto* web_contents = WebContents::Create(params);
- SetViewType(web_contents, VIEW_TYPE_EXTENSION_GUEST);
- callback.Run(web_contents);
+ // TODO(erikchen): Fix ownership semantics for guest views.
+ // https://crbug.com/832879.
+ callback.Run(
+ WebContents::CreateWithSessionStorage(
+ params,
+ owner_web_contents()->GetController().GetSessionStorageNamespaceMap())
+ .release());
registry_.AddInterface(
base::Bind(&MimeHandlerServiceImpl::Create, stream_->GetWeakPtr()));
@@ -308,11 +312,13 @@ void MimeHandlerViewGuest::OnRenderFrameHostDeleted(int process_id,
}
}
-void MimeHandlerViewGuest::EnterFullscreenModeForTab(content::WebContents*,
- const GURL& origin) {
+void MimeHandlerViewGuest::EnterFullscreenModeForTab(
+ content::WebContents*,
+ const GURL& origin,
+ const blink::WebFullscreenOptions& options) {
if (SetFullscreenState(true)) {
embedder_web_contents()->GetDelegate()->EnterFullscreenModeForTab(
- embedder_web_contents(), origin);
+ embedder_web_contents(), origin, options);
}
}
diff --git a/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
index 2bc53e063aa..7f0df3d7dc3 100644
--- a/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
+++ b/chromium/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -121,8 +121,10 @@ class MimeHandlerViewGuest :
content::WebContents* source) final;
bool SaveFrame(const GURL& url, const content::Referrer& referrer) final;
void OnRenderFrameHostDeleted(int process_id, int routing_id) final;
- void EnterFullscreenModeForTab(content::WebContents* web_contents,
- const GURL& origin) override;
+ void EnterFullscreenModeForTab(
+ content::WebContents* web_contents,
+ const GURL& origin,
+ const blink::WebFullscreenOptions& options) override;
void ExitFullscreenModeForTab(content::WebContents*) override;
bool IsFullscreenForTabOrPending(
const content::WebContents* web_contents) const override;
diff --git a/chromium/extensions/browser/guest_view/web_view/web_view_apitest.cc b/chromium/extensions/browser/guest_view/web_view/web_view_apitest.cc
index 2258fc3a77e..91b21b4489e 100644
--- a/chromium/extensions/browser/guest_view/web_view/web_view_apitest.cc
+++ b/chromium/extensions/browser/guest_view/web_view/web_view_apitest.cc
@@ -10,6 +10,7 @@
#include "base/command_line.h"
#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -21,6 +22,7 @@
#include "components/guest_view/browser/test_guest_view_manager.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
@@ -45,6 +47,10 @@
#include "net/test/embedded_test_server/http_response.h"
#include "ui/display/display_switches.h"
+#if defined(USE_AURA)
+#include "third_party/blink/public/platform/web_mouse_event.h"
+#endif
+
using guest_view::GuestViewManager;
using guest_view::TestGuestViewManager;
@@ -144,7 +150,7 @@ WebViewAPITest::WebViewAPITest() {
void WebViewAPITest::LaunchApp(const std::string& app_location) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath test_data_dir;
- PathService::Get(DIR_TEST_DATA, &test_data_dir);
+ base::PathService::Get(DIR_TEST_DATA, &test_data_dir);
test_data_dir = test_data_dir.AppendASCII(app_location.c_str());
const Extension* extension = extension_system_->LoadApp(test_data_dir);
@@ -200,7 +206,7 @@ void WebViewAPITest::StartTestServer(const std::string& app_location) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath test_data_dir;
- PathService::Get(DIR_TEST_DATA, &test_data_dir);
+ base::PathService::Get(DIR_TEST_DATA, &test_data_dir);
test_data_dir = test_data_dir.AppendASCII(app_location.c_str());
embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
@@ -471,6 +477,32 @@ IN_PROC_BROWSER_TEST_F(WebViewAPITest, TestContentLoadEvent) {
RunTest("testContentLoadEvent", "web_view/apitest");
}
+#if defined(USE_AURA)
+// Verifies that trying to show the context menu doesn't crash
+// (https://crbug.com/820604).
+IN_PROC_BROWSER_TEST_F(WebViewAPITest, TestContextMenu) {
+ // Launch some test app that displays a webview.
+ LaunchApp("web_view/visibility_changed");
+
+ // Ensure the webview's surface is ready for hit testing.
+ content::WebContents* guest_web_contents = GetGuestWebContents();
+ content::WaitForGuestSurfaceReady(guest_web_contents);
+
+ // Register a ContextMenuFilter to wait for the context menu event to be sent.
+ content::RenderProcessHost* guest_process_host =
+ guest_web_contents->GetMainFrame()->GetProcess();
+ auto context_menu_filter = base::MakeRefCounted<content::ContextMenuFilter>();
+ guest_process_host->AddFilter(context_menu_filter.get());
+
+ // Trigger the context menu. AppShell doesn't show a context menu; this is
+ // just a sanity check that nothing breaks.
+ content::SimulateRoutedMouseClickAt(
+ guest_web_contents, blink::WebInputEvent::kNoModifiers,
+ blink::WebMouseEvent::Button::kRight, gfx::Point(10, 10));
+ context_menu_filter->Wait();
+}
+#endif
+
IN_PROC_BROWSER_TEST_F(WebViewAPITest, TestDeclarativeWebRequestAPI) {
std::string app_location = "web_view/apitest";
StartTestServer(app_location);
diff --git a/chromium/extensions/browser/guest_view/web_view/web_view_guest.cc b/chromium/extensions/browser/guest_view/web_view/web_view_guest.cc
index 122bd3cfed8..8611c34be99 100644
--- a/chromium/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/chromium/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -12,7 +12,6 @@
#include <utility>
#include "base/lazy_instance.h"
-#include "base/message_loop/message_loop.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@@ -371,7 +370,9 @@ void WebViewGuest::CreateWebContents(
owner_render_process_host->GetBrowserContext(),
std::move(guest_site_instance));
params.guest_delegate = this;
- WebContents* new_contents = WebContents::Create(params);
+ // TODO(erikchen): Fix ownership semantics for guest views.
+ // https://crbug.com/832879.
+ WebContents* new_contents = WebContents::Create(params).release();
// Grant access to the origin of the embedder to the guest process. This
// allows blob:/filesystem: URLs with the embedder origin to be created
@@ -424,29 +425,26 @@ void WebViewGuest::ClearDataInternal(base::Time remove_since,
return;
}
- content::StoragePartition::CookieMatcherFunction cookie_matcher;
-
- bool remove_session_cookies =
- !!(removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_SESSION_COOKIES);
- bool remove_persistent_cookies =
- !!(removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_PERSISTENT_COOKIES);
- bool remove_all_cookies =
- (!!(removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_COOKIES)) ||
- (remove_session_cookies && remove_persistent_cookies);
-
- // Leaving the cookie_matcher unset will cause all cookies to be purged.
- if (!remove_all_cookies) {
- if (remove_session_cookies) {
- cookie_matcher =
- base::Bind([](const net::CanonicalCookie& cookie) -> bool {
- return !cookie.IsPersistent();
- });
- } else if (remove_persistent_cookies) {
- cookie_matcher =
- base::Bind([](const net::CanonicalCookie& cookie) -> bool {
- return cookie.IsPersistent();
- });
- }
+ auto cookie_delete_filter = network::mojom::CookieDeletionFilter::New();
+ // Intentionally do not set the deletion filter time interval because the
+ // time interval parameters to ClearData() will be used.
+
+ // TODO(cmumford): Make this (and webview::* constants) constexpr.
+ const uint32_t ALL_COOKIES_MASK =
+ webview::WEB_VIEW_REMOVE_DATA_MASK_SESSION_COOKIES |
+ webview::WEB_VIEW_REMOVE_DATA_MASK_PERSISTENT_COOKIES;
+
+ if ((removal_mask & ALL_COOKIES_MASK) == ALL_COOKIES_MASK) {
+ cookie_delete_filter->session_control =
+ network::mojom::CookieDeletionSessionControl::IGNORE_CONTROL;
+ } else if (removal_mask &
+ webview::WEB_VIEW_REMOVE_DATA_MASK_SESSION_COOKIES) {
+ cookie_delete_filter->session_control =
+ network::mojom::CookieDeletionSessionControl::SESSION_COOKIES;
+ } else if (removal_mask &
+ webview::WEB_VIEW_REMOVE_DATA_MASK_PERSISTENT_COOKIES) {
+ cookie_delete_filter->session_control =
+ network::mojom::CookieDeletionSessionControl::PERSISTENT_COOKIES;
}
content::StoragePartition* partition =
@@ -456,8 +454,9 @@ void WebViewGuest::ClearDataInternal(base::Time remove_since,
partition->ClearData(
storage_partition_removal_mask,
content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL,
- content::StoragePartition::OriginMatcherFunction(), cookie_matcher,
- remove_since, base::Time::Now(), callback);
+ content::StoragePartition::OriginMatcherFunction(),
+ std::move(cookie_delete_filter), remove_since, base::Time::Now(),
+ callback);
}
void WebViewGuest::GuestViewDidStopLoading() {
@@ -572,14 +571,6 @@ void WebViewGuest::FindReply(WebContents* source,
active_match_ordinal, final_update);
}
-void WebViewGuest::OnAudioStateChanged(content::WebContents* web_contents,
- bool audible) {
- auto args = std::make_unique<base::DictionaryValue>();
- args->Set(webview::kAudible, std::make_unique<base::Value>(audible));
- DispatchEventToView(std::make_unique<GuestViewEvent>(
- webview::kEventAudioStateChanged, std::move(args)));
-}
-
double WebViewGuest::GetZoom() const {
double zoom_level =
ZoomController::FromWebContents(web_contents())->GetZoomLevel();
@@ -733,7 +724,7 @@ void WebViewGuest::Stop() {
void WebViewGuest::Terminate() {
base::RecordAction(UserMetricsAction("WebView.Guest.Terminate"));
base::ProcessHandle process_handle =
- web_contents()->GetMainFrame()->GetProcess()->GetHandle();
+ web_contents()->GetMainFrame()->GetProcess()->GetProcess().Handle();
if (process_handle) {
web_contents()->GetMainFrame()->GetProcess()->Shutdown(
content::RESULT_CODE_KILLED);
@@ -916,6 +907,13 @@ void WebViewGuest::FrameNameChanged(RenderFrameHost* render_frame_host,
ReportFrameNameChange(name);
}
+void WebViewGuest::OnAudioStateChanged(bool audible) {
+ auto args = std::make_unique<base::DictionaryValue>();
+ args->Set(webview::kAudible, std::make_unique<base::Value>(audible));
+ DispatchEventToView(std::make_unique<GuestViewEvent>(
+ webview::kEventAudioStateChanged, std::move(args)));
+}
+
void WebViewGuest::ReportFrameNameChange(const std::string& name) {
name_ = name;
auto args = std::make_unique<base::DictionaryValue>();
@@ -1195,7 +1193,7 @@ void WebViewGuest::SetTransparency() {
if (allow_transparency_)
view->SetBackgroundColor(SK_ColorTRANSPARENT);
else
- view->SetBackgroundColorToDefault();
+ view->SetBackgroundColor(SK_ColorWHITE);
}
void WebViewGuest::SetAllowScaling(bool allow) {
@@ -1246,17 +1244,17 @@ bool WebViewGuest::LoadDataWithBaseURL(const std::string& data_url,
}
void WebViewGuest::AddNewContents(WebContents* source,
- WebContents* new_contents,
+ std::unique_ptr<WebContents> new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
bool* was_blocked) {
+ // TODO(erikchen): Fix ownership semantics for WebContents inside this class.
+ // https://crbug.com/832879.
if (was_blocked)
*was_blocked = false;
- RequestNewWindowPermission(disposition,
- initial_rect,
- user_gesture,
- new_contents);
+ RequestNewWindowPermission(disposition, initial_rect, user_gesture,
+ new_contents.release());
}
WebContents* WebViewGuest::OpenURLFromTab(
@@ -1337,8 +1335,10 @@ void WebViewGuest::WebContentsCreated(WebContents* source_contents,
std::make_pair(guest, NewWindowInfo(target_url, frame_name)));
}
-void WebViewGuest::EnterFullscreenModeForTab(WebContents* web_contents,
- const GURL& origin) {
+void WebViewGuest::EnterFullscreenModeForTab(
+ WebContents* web_contents,
+ const GURL& origin,
+ const blink::WebFullscreenOptions& options) {
// Ask the embedder for permission.
base::DictionaryValue request_info;
request_info.SetString(webview::kOrigin, origin.spec());
@@ -1516,9 +1516,12 @@ void WebViewGuest::SetFullscreenState(bool is_fullscreen) {
DispatchEventToView(std::make_unique<GuestViewEvent>(
webview::kEventExitFullscreen, std::move(args)));
}
- // Since we changed fullscreen state, sending a Resize message ensures that
- // renderer/ sees the change.
- web_contents()->GetRenderViewHost()->GetWidget()->WasResized();
+ // Since we changed fullscreen state, sending a SynchronizeVisualProperties
+ // message ensures that renderer/ sees the change.
+ web_contents()
+ ->GetRenderViewHost()
+ ->GetWidget()
+ ->SynchronizeVisualProperties();
}
} // namespace extensions
diff --git a/chromium/extensions/browser/guest_view/web_view/web_view_guest.h b/chromium/extensions/browser/guest_view/web_view/web_view_guest.h
index 5c06f37873f..da06ab393b3 100644
--- a/chromium/extensions/browser/guest_view/web_view/web_view_guest.h
+++ b/chromium/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -232,7 +232,7 @@ class WebViewGuest : public guest_view::GuestView<WebViewGuest> {
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) final;
void AddNewContents(content::WebContents* source,
- content::WebContents* new_contents,
+ std::unique_ptr<content::WebContents> new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
@@ -246,16 +246,16 @@ class WebViewGuest : public guest_view::GuestView<WebViewGuest> {
const std::string& frame_name,
const GURL& target_url,
content::WebContents* new_contents) final;
- void EnterFullscreenModeForTab(content::WebContents* web_contents,
- const GURL& origin) final;
+ void EnterFullscreenModeForTab(
+ content::WebContents* web_contents,
+ const GURL& origin,
+ const blink::WebFullscreenOptions& options) final;
void ExitFullscreenModeForTab(content::WebContents* web_contents) final;
bool IsFullscreenForTabOrPending(
const content::WebContents* web_contents) const final;
void RequestToLockMouse(content::WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) override;
- void OnAudioStateChanged(content::WebContents* web_contents,
- bool audible) final;
// WebContentsObserver implementation.
void DidStartNavigation(content::NavigationHandle* navigation_handle) final;
@@ -267,6 +267,7 @@ class WebViewGuest : public guest_view::GuestView<WebViewGuest> {
void UserAgentOverrideSet(const std::string& user_agent) final;
void FrameNameChanged(content::RenderFrameHost* render_frame_host,
const std::string& name) final;
+ void OnAudioStateChanged(bool audible) final;
// Informs the embedder of a frame name change.
void ReportFrameNameChange(const std::string& name);
diff --git a/chromium/extensions/browser/guest_view/web_view/web_view_guest_delegate.h b/chromium/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
index b9a33b02e5f..38562b99938 100644
--- a/chromium/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
+++ b/chromium/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
@@ -20,10 +20,6 @@ class WebViewGuestDelegate {
// Shows the context menu for the guest.
virtual void OnShowContextMenu(int request_id) = 0;
-
- // Returns true if the WebViewGuest should handle find requests for its
- // embedder.
- virtual bool ShouldHandleFindRequestsForEmbedder() const = 0;
};
} // namespace extensions
diff --git a/chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.cc b/chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.cc
index b83fbaf23f0..085189a61ca 100644
--- a/chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.cc
+++ b/chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.cc
@@ -150,6 +150,7 @@ WebViewPermissionHelper::WebViewPermissionHelper(WebViewGuest* web_view_guest)
: content::WebContentsObserver(web_view_guest->web_contents()),
next_permission_request_id_(guest_view::kInstanceIDNone),
web_view_guest_(web_view_guest),
+ default_media_access_permission_(false),
weak_factory_(this) {
web_view_permission_helper_delegate_.reset(
ExtensionsAPIClient::Get()->CreateWebViewPermissionHelperDelegate(
@@ -202,7 +203,7 @@ void WebViewPermissionHelper::RequestMediaAccessPermission(
weak_factory_.GetWeakPtr(),
request,
callback),
- false /* allowed_by_default */);
+ default_media_access_permission_);
}
bool WebViewPermissionHelper::CheckMediaAccessPermission(
diff --git a/chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.h b/chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.h
index 4e3a7f0f53f..8ae06ab2409 100644
--- a/chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.h
+++ b/chromium/extensions/browser/guest_view/web_view/web_view_permission_helper.h
@@ -119,6 +119,10 @@ class WebViewPermissionHelper
WebViewGuest* web_view_guest() { return web_view_guest_; }
+ void set_default_media_access_permission(bool allow_media_access) {
+ default_media_access_permission_ = allow_media_access;
+ }
+
private:
void OnMediaPermissionResponse(const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback,
@@ -142,6 +146,8 @@ class WebViewPermissionHelper
WebViewGuest* const web_view_guest_;
+ bool default_media_access_permission_;
+
base::WeakPtrFactory<WebViewPermissionHelper> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WebViewPermissionHelper);
diff --git a/chromium/extensions/browser/image_loader_unittest.cc b/chromium/extensions/browser/image_loader_unittest.cc
index 20e9a598d76..26dfbedcf9b 100644
--- a/chromium/extensions/browser/image_loader_unittest.cc
+++ b/chromium/extensions/browser/image_loader_unittest.cc
@@ -66,7 +66,7 @@ class ImageLoaderTest : public ExtensionsTest {
Manifest::Location location) {
// Create and load an extension.
base::FilePath extension_dir;
- if (!PathService::Get(DIR_TEST_DATA, &extension_dir)) {
+ if (!base::PathService::Get(DIR_TEST_DATA, &extension_dir)) {
EXPECT_FALSE(true);
return NULL;
}
diff --git a/chromium/extensions/browser/info_map_unittest.cc b/chromium/extensions/browser/info_map_unittest.cc
index 271ed11bb79..14d3a816c18 100644
--- a/chromium/extensions/browser/info_map_unittest.cc
+++ b/chromium/extensions/browser/info_map_unittest.cc
@@ -27,7 +27,7 @@ class InfoMapTest : public testing::Test {
// Returns a barebones test Extension object with the given name.
static scoped_refptr<Extension> CreateExtension(const std::string& name) {
base::FilePath path;
- PathService::Get(DIR_TEST_DATA, &path);
+ base::PathService::Get(DIR_TEST_DATA, &path);
return ExtensionBuilder(name).SetPath(path.AppendASCII(name)).Build();
}
diff --git a/chromium/extensions/browser/install/BUILD.gn b/chromium/extensions/browser/install/BUILD.gn
index 5922ff52fbe..0eb97983e5a 100644
--- a/chromium/extensions/browser/install/BUILD.gn
+++ b/chromium/extensions/browser/install/BUILD.gn
@@ -9,9 +9,11 @@ assert(enable_extensions,
source_set("install") {
sources = [
+ "crx_install_error.cc",
"crx_install_error.h",
"extension_install_ui.cc",
"extension_install_ui.h",
+ "sandboxed_unpacker_failure_reason.h",
]
deps = [
diff --git a/chromium/extensions/browser/install/crx_install_error.cc b/chromium/extensions/browser/install/crx_install_error.cc
new file mode 100644
index 00000000000..22305ee035e
--- /dev/null
+++ b/chromium/extensions/browser/install/crx_install_error.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2018 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 "extensions/browser/install/crx_install_error.h"
+#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
+
+namespace extensions {
+
+CrxInstallError::CrxInstallError(CrxInstallErrorType type,
+ CrxInstallErrorDetail detail,
+ const base::string16& message)
+ : type_(type), detail_(detail), message_(message) {
+ DCHECK_NE(CrxInstallErrorType::NONE, type);
+ DCHECK_NE(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE, type);
+}
+
+CrxInstallError::CrxInstallError(CrxInstallErrorType type,
+ CrxInstallErrorDetail detail)
+ : CrxInstallError(type, detail, base::string16()) {}
+
+CrxInstallError::CrxInstallError(SandboxedUnpackerFailureReason reason,
+ const base::string16& message)
+ : type_(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE),
+ detail_(CrxInstallErrorDetail::NONE),
+ sandbox_failure_detail_(reason),
+ message_(message) {}
+
+CrxInstallError::CrxInstallError(const CrxInstallError& other) = default;
+CrxInstallError::CrxInstallError(CrxInstallError&& other) = default;
+CrxInstallError& CrxInstallError::operator=(const CrxInstallError& other) =
+ default;
+CrxInstallError& CrxInstallError::operator=(CrxInstallError&& other) = default;
+
+CrxInstallError::~CrxInstallError() = default;
+
+// For SANDBOXED_UNPACKER_FAILURE type, use sandbox_failure_detail().
+CrxInstallErrorDetail CrxInstallError::detail() const {
+ DCHECK_NE(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE, type_);
+ return detail_;
+}
+
+// sandbox_failure_detail() only returns a value when the error type is
+// SANDBOXED_UNPACKER_FAILURE.
+SandboxedUnpackerFailureReason CrxInstallError::sandbox_failure_detail() const {
+ DCHECK_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE, type_);
+ DCHECK(sandbox_failure_detail_);
+ return sandbox_failure_detail_.value();
+}
+
+} // namespace extensions
diff --git a/chromium/extensions/browser/install/crx_install_error.h b/chromium/extensions/browser/install/crx_install_error.h
index af25df66dbc..ca747b278d5 100644
--- a/chromium/extensions/browser/install/crx_install_error.h
+++ b/chromium/extensions/browser/install/crx_install_error.h
@@ -5,41 +5,82 @@
#ifndef EXTENSIONS_BROWSER_INSTALL_CRX_INSTALL_ERROR_H_
#define EXTENSIONS_BROWSER_INSTALL_CRX_INSTALL_ERROR_H_
+#include "base/optional.h"
#include "base/strings/string16.h"
namespace extensions {
-// Simple error class for CrxInstaller.
-class CrxInstallError {
- public:
- // Typed errors that need to be handled specially by clients.
- // ERROR_OFF_STORE for disallowed off-store installations.
- // ERROR_DECLINED for situations when a .crx file seems to be OK, but there
+enum class SandboxedUnpackerFailureReason;
+
+// Typed errors that need to be handled specially by clients.
+// Do not change the order of the entries or remove entries in this list.
+enum class CrxInstallErrorType {
+ NONE = 0,
+ // DECLINED for situations when a .crx file seems to be OK, but there
// are some policy restrictions or unmet dependencies that prevent it from
// being installed.
- // ERROR_HASH_MISMATCH if the expected extension SHA256 hash sum is different
- // from the actual one.
- enum Type {
- ERROR_NONE,
- ERROR_OFF_STORE,
- ERROR_DECLINED,
- ERROR_HASH_MISMATCH,
- ERROR_OTHER
- };
+ DECLINED = 1,
+ // SANDBOXED_UNPACKER_FAILURE for sandboxed unpacker error.
+ // CrxInstallErrorDetail will give more detail about the failure.
+ SANDBOXED_UNPACKER_FAILURE = 2,
+ OTHER = 3,
+};
- CrxInstallError() : type_(ERROR_NONE) {}
+// Extended error code that may help explain the error type.
+// Do not change the order of the entries or remove entries in this list.
+enum class CrxInstallErrorDetail {
+ NONE, // 0
+ CONVERT_USER_SCRIPT_TO_EXTENSION_FAILED, // 1
+ UNEXPECTED_ID, // 2
+ UNEXPECTED_VERSION, // 3
+ MISMATCHED_VERSION, // 4
+ MANIFEST_INVALID, // 5
+ INSTALL_NOT_ENABLED, // 6
+ OFFSTORE_INSTALL_DISALLOWED, // 7
+ INCORRECT_APP_CONTENT_TYPE, // 8
+ NOT_INSTALLED_FROM_GALLERY, // 9
+ INCORRECT_INSTALL_HOST, // 10
+ DEPENDENCY_NOT_SHARED_MODULE, // 11
+ DEPENDENCY_OLD_VERSION, // 12
+ DEPENDENCY_NOT_ALLOWLISTED, // 13
+ UNSUPPORTED_REQUIREMENTS, // 14
+ EXTENSION_IS_BLOCKLISTED, // 15
+ DISALLOWED_BY_POLICY, // 16
+ KIOSK_MODE_ONLY, // 17
+ OVERLAPPING_WEB_EXTENT, // 18
+ CANT_DOWNGRADE_VERSION, // 19
+ MOVE_DIRECTORY_TO_PROFILE_FAILED, // 20
+ CANT_LOAD_EXTENSION, // 21
+ USER_CANCELED, // 22
+ USER_ABORTED, // 23
+ UPDATE_NON_EXISTING_EXTENSION, // 24
+};
- explicit CrxInstallError(const base::string16& message)
- : type_(message.empty() ? ERROR_NONE : ERROR_OTHER), message_(message) {}
+// Simple error class for CrxInstaller.
+class CrxInstallError {
+ public:
+ CrxInstallError(CrxInstallErrorType type,
+ CrxInstallErrorDetail detail,
+ const base::string16& message);
+ CrxInstallError(CrxInstallErrorType type, CrxInstallErrorDetail detail);
+ CrxInstallError(SandboxedUnpackerFailureReason reason,
+ const base::string16& message);
+ ~CrxInstallError();
- CrxInstallError(Type type, const base::string16& message)
- : type_(type), message_(message) {}
+ CrxInstallError(const CrxInstallError& other);
+ CrxInstallError(CrxInstallError&& other);
+ CrxInstallError& operator=(const CrxInstallError& other);
+ CrxInstallError& operator=(CrxInstallError&& other);
- Type type() const { return type_; }
+ CrxInstallErrorType type() const { return type_; }
const base::string16& message() const { return message_; }
+ CrxInstallErrorDetail detail() const;
+ SandboxedUnpackerFailureReason sandbox_failure_detail() const;
private:
- Type type_;
+ CrxInstallErrorType type_;
+ CrxInstallErrorDetail detail_;
+ base::Optional<SandboxedUnpackerFailureReason> sandbox_failure_detail_;
base::string16 message_;
};
diff --git a/chromium/extensions/browser/install/sandboxed_unpacker_failure_reason.h b/chromium/extensions/browser/install/sandboxed_unpacker_failure_reason.h
new file mode 100644
index 00000000000..7571fed3e29
--- /dev/null
+++ b/chromium/extensions/browser/install/sandboxed_unpacker_failure_reason.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2018 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 EXTENSIONS_BROWSER_INSTALL_SANDBOXED_UNPACKER_FAILURE_REASON_H_
+#define EXTENSIONS_BROWSER_INSTALL_SANDBOXED_UNPACKER_FAILURE_REASON_H_
+
+namespace extensions {
+
+// Enumerate all the ways SandboxedUnpacker can fail.
+// Don't change the order or change the value of the enums.
+enum class SandboxedUnpackerFailureReason {
+ // SandboxedUnpacker::CreateTempDirectory()
+ COULD_NOT_GET_TEMP_DIRECTORY = 0,
+ COULD_NOT_CREATE_TEMP_DIRECTORY = 1,
+
+ // SandboxedUnpacker::Start()
+ FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY = 2,
+ COULD_NOT_GET_SANDBOX_FRIENDLY_PATH = 3,
+
+ // SandboxedUnpacker::UnpackExtensionSucceeded()
+ COULD_NOT_LOCALIZE_EXTENSION = 4,
+ INVALID_MANIFEST = 5,
+
+ // SandboxedUnpacker::UnpackExtensionFailed()
+ UNPACKER_CLIENT_FAILED = 6,
+
+ // SandboxedUnpacker::UtilityProcessCrashed()
+ UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL = 7,
+
+ // SandboxedUnpacker::ValidateSignature()
+ CRX_FILE_NOT_READABLE = 8,
+ CRX_HEADER_INVALID = 9,
+ CRX_MAGIC_NUMBER_INVALID = 10,
+ CRX_VERSION_NUMBER_INVALID = 11,
+ CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE = 12,
+ CRX_ZERO_KEY_LENGTH = 13,
+ CRX_ZERO_SIGNATURE_LENGTH = 14,
+ CRX_PUBLIC_KEY_INVALID = 15,
+ CRX_SIGNATURE_INVALID = 16,
+ CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED = 17,
+ CRX_SIGNATURE_VERIFICATION_FAILED = 18,
+
+ // SandboxedUnpacker::RewriteManifestFile()
+ ERROR_SERIALIZING_MANIFEST_JSON = 19,
+ ERROR_SAVING_MANIFEST_JSON = 20,
+
+ // SandboxedUnpacker::RewriteImageFiles()
+ COULD_NOT_READ_IMAGE_DATA_FROM_DISK_UNUSED = 21,
+ DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST_UNUSED = 22,
+ INVALID_PATH_FOR_BROWSER_IMAGE = 23,
+ ERROR_REMOVING_OLD_IMAGE_FILE = 24,
+ INVALID_PATH_FOR_BITMAP_IMAGE = 25,
+ ERROR_RE_ENCODING_THEME_IMAGE = 26,
+ ERROR_SAVING_THEME_IMAGE = 27,
+ DEPRECATED_ABORTED_DUE_TO_SHUTDOWN = 28, // No longer used; kept for UMA.
+
+ // SandboxedUnpacker::RewriteCatalogFiles()
+ COULD_NOT_READ_CATALOG_DATA_FROM_DISK_UNUSED = 29,
+ INVALID_CATALOG_DATA = 30,
+ INVALID_PATH_FOR_CATALOG_UNUSED = 31,
+ ERROR_SERIALIZING_CATALOG = 32,
+ ERROR_SAVING_CATALOG = 33,
+
+ // SandboxedUnpacker::ValidateSignature()
+ CRX_HASH_VERIFICATION_FAILED = 34,
+
+ UNZIP_FAILED = 35,
+ DIRECTORY_MOVE_FAILED = 36,
+
+ // SandboxedUnpacker::ValidateSignature()
+ CRX_FILE_IS_DELTA_UPDATE = 37,
+ CRX_EXPECTED_HASH_INVALID = 38,
+
+ // SandboxedUnpacker::IndexAndPersistRulesIfNeeded()
+ ERROR_PARSING_DNR_RULESET = 39,
+ ERROR_INDEXING_DNR_RULESET = 40,
+
+ NUM_FAILURE_REASONS
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_INSTALL_SANDBOXED_UNPACKER_FAILURE_REASON_H_
diff --git a/chromium/extensions/browser/json_file_sanitizer.cc b/chromium/extensions/browser/json_file_sanitizer.cc
index e57e5761853..fb864c649cd 100644
--- a/chromium/extensions/browser/json_file_sanitizer.cc
+++ b/chromium/extensions/browser/json_file_sanitizer.cc
@@ -94,7 +94,7 @@ void JsonFileSanitizer::JsonFileRead(
void JsonFileSanitizer::JsonParsingDone(
const base::FilePath& file_path,
- std::unique_ptr<base::Value> json_value,
+ base::Optional<base::Value> json_value,
const base::Optional<std::string>& error) {
if (!json_value || !json_value->is_dict()) {
ReportError(Status::kDecodingError, error ? *error : std::string());
diff --git a/chromium/extensions/browser/json_file_sanitizer.h b/chromium/extensions/browser/json_file_sanitizer.h
index b90e73b5739..4d8181d1b64 100644
--- a/chromium/extensions/browser/json_file_sanitizer.h
+++ b/chromium/extensions/browser/json_file_sanitizer.h
@@ -77,7 +77,7 @@ class JsonFileSanitizer {
std::tuple<std::string, bool, bool> read_and_delete_result);
void JsonParsingDone(const base::FilePath& file_path,
- std::unique_ptr<base::Value> json_value,
+ base::Optional<base::Value> json_value,
const base::Optional<std::string>& error);
void JsonFileWritten(const base::FilePath& file_path,
diff --git a/chromium/extensions/browser/lazy_background_task_queue.cc b/chromium/extensions/browser/lazy_background_task_queue.cc
index 8efc9fde866..ee3eb077cbc 100644
--- a/chromium/extensions/browser/lazy_background_task_queue.cc
+++ b/chromium/extensions/browser/lazy_background_task_queue.cc
@@ -42,6 +42,16 @@ void PendingTaskAdapter(LazyContextTaskQueue::PendingTask original_task,
}
}
+// Attempts to create a background host for a lazy background page. Returns true
+// if the background host is created.
+bool CreateLazyBackgroundHost(ProcessManager* pm, const Extension* extension) {
+ pm->IncrementLazyKeepaliveCount(extension);
+ // Creating the background host may fail, e.g. if the extension isn't enabled
+ // in incognito mode.
+ return pm->CreateBackgroundHost(extension,
+ BackgroundInfo::GetBackgroundURL(extension));
+}
+
} // namespace
LazyBackgroundTaskQueue::LazyBackgroundTaskQueue(
@@ -104,26 +114,21 @@ void LazyBackgroundTaskQueue::AddPendingTask(
PendingTasksKey key(browser_context, extension_id);
PendingTasksMap::iterator it = pending_tasks_.find(key);
if (it == pending_tasks_.end()) {
- auto tasks_list_tmp = std::make_unique<PendingTasksList>();
- tasks_list = tasks_list_tmp.get();
- pending_tasks_[key] = std::move(tasks_list_tmp);
-
- const Extension* extension =
- ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID(
- extension_id);
+ const Extension* extension = ExtensionRegistry::Get(browser_context)
+ ->enabled_extensions()
+ .GetByID(extension_id);
if (extension && BackgroundInfo::HasLazyBackgroundPage(extension)) {
// If this is the first enqueued task, and we're not waiting for the
// background page to unload, ensure the background page is loaded.
- ProcessManager* pm = ProcessManager::Get(browser_context);
- pm->IncrementLazyKeepaliveCount(extension);
- // Creating the background host may fail, e.g. if |profile| is incognito
- // but the extension isn't enabled in incognito mode.
- if (!pm->CreateBackgroundHost(
- extension, BackgroundInfo::GetBackgroundURL(extension))) {
+ if (!CreateLazyBackgroundHost(ProcessManager::Get(browser_context),
+ extension)) {
std::move(task).Run(nullptr);
return;
}
}
+ auto tasks_list_tmp = std::make_unique<PendingTasksList>();
+ tasks_list = tasks_list_tmp.get();
+ pending_tasks_[key] = std::move(tasks_list_tmp);
} else {
tasks_list = it->second.get();
}
@@ -158,14 +163,28 @@ void LazyBackgroundTaskQueue::ProcessPendingTasks(
pending_tasks_.erase(key);
- // Balance the keepalive in AddPendingTask. Note we don't do this on a
- // failure to load, because the keepalive count is reset in that case.
+ // Balance the keepalive in CreateLazyBackgroundHost. Note we don't do this on
+ // a failure to load, because the keepalive count is reset in that case.
if (host && BackgroundInfo::HasLazyBackgroundPage(extension)) {
ProcessManager::Get(browser_context)
->DecrementLazyKeepaliveCount(extension);
}
}
+void LazyBackgroundTaskQueue::NotifyTasksExtensionFailedToLoad(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ ProcessPendingTasks(nullptr, browser_context, extension);
+ // If this extension is also running in an off-the-record context, notify that
+ // task queue as well.
+ ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get();
+ if (browser_client->HasOffTheRecordContext(browser_context)) {
+ ProcessPendingTasks(nullptr,
+ browser_client->GetOffTheRecordContext(browser_context),
+ extension);
+ }
+}
+
void LazyBackgroundTaskQueue::Observe(
int type,
const content::NotificationSource& source,
@@ -203,20 +222,48 @@ void LazyBackgroundTaskQueue::Observe(
}
}
-void LazyBackgroundTaskQueue::OnExtensionUnloaded(
+void LazyBackgroundTaskQueue::OnExtensionLoaded(
content::BrowserContext* browser_context,
- const Extension* extension,
- UnloadedExtensionReason reason) {
- // Notify consumers that the page failed to load.
- ProcessPendingTasks(NULL, browser_context, extension);
- // If this extension is also running in an off-the-record context, notify that
- // task queue as well.
+ const Extension* extension) {
+ // If there are pending tasks for a lazy background page, and its background
+ // host has not been created yet, then create it. This can happen if a pending
+ // task was added while the extension is not yet enabled (e.g., component
+ // extension crashed and waiting to reload, https://crbug.com/835017).
+ if (!BackgroundInfo::HasLazyBackgroundPage(extension))
+ return;
+
+ CreateLazyBackgroundHostOnExtensionLoaded(browser_context, extension);
+
+ // Also try to create the background host for the off-the-record context.
ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get();
if (browser_client->HasOffTheRecordContext(browser_context)) {
- ProcessPendingTasks(NULL,
- browser_client->GetOffTheRecordContext(browser_context),
- extension);
+ CreateLazyBackgroundHostOnExtensionLoaded(
+ browser_client->GetOffTheRecordContext(browser_context), extension);
}
}
+void LazyBackgroundTaskQueue::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionReason reason) {
+ NotifyTasksExtensionFailedToLoad(browser_context, extension);
+}
+
+void LazyBackgroundTaskQueue::CreateLazyBackgroundHostOnExtensionLoaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ PendingTasksKey key(browser_context, extension->id());
+ if (!base::ContainsKey(pending_tasks_, key))
+ return;
+
+ ProcessManager* pm = ProcessManager::Get(browser_context);
+
+ // Background host already created, just wait for it to finish loading.
+ if (pm->GetBackgroundHostForExtension(extension->id()))
+ return;
+
+ if (!CreateLazyBackgroundHost(pm, extension))
+ ProcessPendingTasks(nullptr, browser_context, extension);
+}
+
} // namespace extensions
diff --git a/chromium/extensions/browser/lazy_background_task_queue.h b/chromium/extensions/browser/lazy_background_task_queue.h
index e5e918b281d..f1571cb4d0b 100644
--- a/chromium/extensions/browser/lazy_background_task_queue.h
+++ b/chromium/extensions/browser/lazy_background_task_queue.h
@@ -76,7 +76,8 @@ class LazyBackgroundTaskQueue : public KeyedService,
private:
FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, AddPendingTask);
FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, ProcessPendingTasks);
-
+ FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest,
+ CreateLazyBackgroundPageOnExtensionLoaded);
// A map between a BrowserContext/extension_id pair and the queue of tasks
// pending the load of its background page.
using PendingTasksKey = std::pair<content::BrowserContext*, ExtensionId>;
@@ -90,17 +91,31 @@ class LazyBackgroundTaskQueue : public KeyedService,
const content::NotificationDetails& details) override;
// ExtensionRegistryObserver interface.
+ void OnExtensionLoaded(content::BrowserContext* browser_context,
+ const Extension* extension) override;
void OnExtensionUnloaded(content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionReason reason) override;
+ // If there are pending tasks for |extension| in |browser_context|, try to
+ // create the background host. If the background host cannot be created, the
+ // pending tasks are invoked with nullptr.
+ void CreateLazyBackgroundHostOnExtensionLoaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension);
+
// Called when a lazy background page has finished loading, or has failed to
- // load (host is NULL in that case). All enqueued tasks are run in order.
+ // load (host is nullptr in that case). All enqueued tasks are run in order.
void ProcessPendingTasks(
ExtensionHost* host,
content::BrowserContext* context,
const Extension* extension);
+ // Notifies queued tasks that a lazy background page has failed to load.
+ void NotifyTasksExtensionFailedToLoad(
+ content::BrowserContext* browser_context,
+ const Extension* extension);
+
content::BrowserContext* browser_context_;
content::NotificationRegistrar registrar_;
PendingTasksMap pending_tasks_;
diff --git a/chromium/extensions/browser/lazy_background_task_queue_unittest.cc b/chromium/extensions/browser/lazy_background_task_queue_unittest.cc
index bb7370edce3..fd99b79aa92 100644
--- a/chromium/extensions/browser/lazy_background_task_queue_unittest.cc
+++ b/chromium/extensions/browser/lazy_background_task_queue_unittest.cc
@@ -70,6 +70,7 @@ class LazyBackgroundTaskQueueTest : public ExtensionsTest {
~LazyBackgroundTaskQueueTest() override {}
int task_run_count() { return task_run_count_; }
+ TestProcessManager* process_manager() { return process_manager_; }
// A simple callback for AddPendingTask.
void RunPendingTask(ExtensionHost* host) {
@@ -79,12 +80,7 @@ class LazyBackgroundTaskQueueTest : public ExtensionsTest {
// Creates and registers an extension without a background page.
scoped_refptr<Extension> CreateSimpleExtension() {
scoped_refptr<Extension> extension =
- ExtensionBuilder()
- .SetManifest(DictionaryBuilder()
- .Set("name", "No background")
- .Set("version", "1")
- .Set("manifest_version", 2)
- .Build())
+ ExtensionBuilder("No background")
.SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
.Build();
ExtensionRegistry::Get(browser_context())->AddEnabled(extension);
@@ -94,17 +90,8 @@ class LazyBackgroundTaskQueueTest : public ExtensionsTest {
// Creates and registers an extension with a lazy background page.
scoped_refptr<Extension> CreateLazyBackgroundExtension() {
scoped_refptr<Extension> extension =
- ExtensionBuilder()
- .SetManifest(
- DictionaryBuilder()
- .Set("name", "Lazy background")
- .Set("version", "1")
- .Set("manifest_version", 2)
- .Set("background", DictionaryBuilder()
- .Set("page", "background.html")
- .SetBoolean("persistent", false)
- .Build())
- .Build())
+ ExtensionBuilder("Lazy background")
+ .SetBackgroundPage(ExtensionBuilder::BackgroundPage::EVENT)
.SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
.Build();
ExtensionRegistry::Get(browser_context())->AddEnabled(extension);
@@ -115,6 +102,15 @@ class LazyBackgroundTaskQueueTest : public ExtensionsTest {
void SetUp() override {
ExtensionsTest::SetUp();
user_prefs::UserPrefs::Set(browser_context(), &testing_pref_service_);
+
+ process_manager_ = static_cast<TestProcessManager*>(
+ ProcessManagerFactory::GetInstance()->SetTestingFactoryAndUse(
+ browser_context(), CreateTestProcessManager));
+ }
+
+ void TearDown() override {
+ process_manager_ = nullptr;
+ ExtensionsTest::TearDown();
}
private:
@@ -122,6 +118,7 @@ class LazyBackgroundTaskQueueTest : public ExtensionsTest {
// The total number of pending tasks that have been executed.
int task_run_count_;
+ TestProcessManager* process_manager_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest);
};
@@ -143,11 +140,6 @@ TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) {
// Tests that adding tasks actually increases the pending task count, and that
// multiple extensions can have pending tasks.
TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) {
- // Get our TestProcessManager.
- TestProcessManager* process_manager = static_cast<TestProcessManager*>(
- ProcessManagerFactory::GetInstance()->SetTestingFactoryAndUse(
- browser_context(), CreateTestProcessManager));
-
LazyBackgroundTaskQueue queue(browser_context());
// Build a simple extension with no background page.
@@ -178,9 +170,9 @@ TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) {
lazy_background->id(),
base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
base::Unretained(this)));
- EXPECT_EQ(2u, queue.pending_tasks_.size());
+ EXPECT_EQ(1u, queue.pending_tasks_.size());
// The process manager tried to create a background host.
- EXPECT_EQ(1, process_manager->create_count());
+ EXPECT_EQ(1, process_manager()->create_count());
// The task ran immediately because the creation failed.
EXPECT_EQ(1, task_run_count());
}
@@ -215,4 +207,41 @@ TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) {
EXPECT_EQ(0u, queue.pending_tasks_.size());
}
+// Tests that if a pending task was added before the extension with a lazy
+// background page is loaded, then we will create the lazy background page when
+// the extension is loaded.
+TEST_F(LazyBackgroundTaskQueueTest, CreateLazyBackgroundPageOnExtensionLoaded) {
+ LazyBackgroundTaskQueue queue(browser_context());
+
+ scoped_refptr<Extension> lazy_background =
+ ExtensionBuilder("Lazy background")
+ .SetBackgroundPage(ExtensionBuilder::BackgroundPage::EVENT)
+ .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
+ .Build();
+
+ queue.OnExtensionLoaded(browser_context(), lazy_background.get());
+ // Did not try to create a background host because there are no queued tasks.
+ EXPECT_EQ(0, process_manager()->create_count());
+
+ queue.AddPendingTask(browser_context(), lazy_background->id(),
+ base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
+ base::Unretained(this)));
+ EXPECT_EQ(1u, queue.pending_tasks_.size());
+ // Did not try to create a background host because extension is not yet
+ // loaded.
+ EXPECT_EQ(0, process_manager()->create_count());
+ // The task is queued.
+ EXPECT_EQ(0, task_run_count());
+
+ ExtensionRegistry::Get(browser_context())->AddEnabled(lazy_background);
+ queue.OnExtensionLoaded(browser_context(), lazy_background.get());
+
+ // The process manager tried to create a background host because there is a
+ // queued task.
+ EXPECT_EQ(1, process_manager()->create_count());
+ // The queued task ran because the creation failed.
+ EXPECT_EQ(1, task_run_count());
+ EXPECT_EQ(0u, queue.pending_tasks_.size());
+}
+
} // namespace extensions
diff --git a/chromium/extensions/browser/management_policy.cc b/chromium/extensions/browser/management_policy.cc
index 4eef61b085a..b6e70cf704c 100644
--- a/chromium/extensions/browser/management_policy.cc
+++ b/chromium/extensions/browser/management_policy.cc
@@ -34,6 +34,13 @@ bool ManagementPolicy::Provider::UserMayModifySettings(
return true;
}
+bool ManagementPolicy::Provider::ExtensionMayModifySettings(
+ const Extension* source_extension,
+ const Extension* extension,
+ base::string16* error) const {
+ return true;
+}
+
bool ManagementPolicy::Provider::MustRemainEnabled(const Extension* extension,
base::string16* error)
const {
@@ -79,6 +86,24 @@ bool ManagementPolicy::UserMayModifySettings(const Extension* extension,
&Provider::UserMayModifySettings, "Modification", true, extension, error);
}
+bool ManagementPolicy::ExtensionMayModifySettings(
+ const Extension* source_extension,
+ const Extension* extension,
+ base::string16* error) const {
+ for (const Provider* provider : providers_) {
+ if (!provider->ExtensionMayModifySettings(source_extension, extension,
+ error)) {
+ std::string id;
+ std::string name;
+ GetExtensionNameAndId(extension, &name, &id);
+ DVLOG(1) << "Modification of extension " << name << " (" << id << ")"
+ << " prohibited by " << provider->GetDebugPolicyProviderName();
+ return false;
+ }
+ }
+ return true;
+}
+
bool ManagementPolicy::MustRemainEnabled(const Extension* extension,
base::string16* error) const {
return ApplyToProviderList(
@@ -121,9 +146,7 @@ bool ManagementPolicy::ApplyToProviderList(ProviderFunction function,
bool normal_result,
const Extension* extension,
base::string16* error) const {
- for (ProviderList::const_iterator it = providers_.begin();
- it != providers_.end(); ++it) {
- const Provider* provider = *it;
+ for (const Provider* provider : providers_) {
bool result = (provider->*function)(extension, error);
if (result != normal_result) {
std::string id;
diff --git a/chromium/extensions/browser/management_policy.h b/chromium/extensions/browser/management_policy.h
index 9dd3c27413b..e6f1f8521cb 100644
--- a/chromium/extensions/browser/management_policy.h
+++ b/chromium/extensions/browser/management_policy.h
@@ -5,6 +5,7 @@
#ifndef EXTENSIONS_BROWSER_MANAGEMENT_POLICY_H_
#define EXTENSIONS_BROWSER_MANAGEMENT_POLICY_H_
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -68,6 +69,12 @@ class ManagementPolicy {
virtual bool UserMayModifySettings(const Extension* extension,
base::string16* error) const;
+ // Providers should return false if the originating extension
+ // |source_extension| cannot disable the |extension|.
+ virtual bool ExtensionMayModifySettings(const Extension* source_extension,
+ const Extension* extension,
+ base::string16* error) const;
+
// Providers should return true if the |extension| must always remain
// enabled. This is distinct from UserMayModifySettings() in that the latter
// also prohibits enabling the extension if it is currently disabled.
@@ -118,6 +125,12 @@ class ManagementPolicy {
bool UserMayModifySettings(const Extension* extension,
base::string16* error) const;
+ // Returns true if the originating extension is permitted to disable the
+ // given extension. If not, |error| may be set to an appropriate message.
+ bool ExtensionMayModifySettings(const Extension* source_extension,
+ const Extension* extension,
+ base::string16* error) const;
+
// Returns true if the extension must remain enabled at all times (e.g. a
// component extension). In that case, |error| may be set to an appropriate
// message.
diff --git a/chromium/extensions/browser/media_capture_util.cc b/chromium/extensions/browser/media_capture_util.cc
new file mode 100644
index 00000000000..e4c29b52daa
--- /dev/null
+++ b/chromium/extensions/browser/media_capture_util.cc
@@ -0,0 +1,110 @@
+// 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 "extensions/browser/media_capture_util.h"
+
+#include <algorithm>
+#include <string>
+#include <utility>
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "content/public/browser/media_capture_devices.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/permissions/permissions_data.h"
+
+using content::MediaCaptureDevices;
+using content::MediaStreamDevice;
+using content::MediaStreamDevices;
+using content::MediaStreamUI;
+
+namespace extensions {
+
+namespace {
+
+const MediaStreamDevice* GetRequestedDeviceOrDefault(
+ const MediaStreamDevices& devices,
+ const std::string& requested_device_id) {
+ if (!requested_device_id.empty()) {
+ auto it = std::find_if(
+ devices.begin(), devices.end(),
+ [requested_device_id](const content::MediaStreamDevice& device) {
+ return device.id == requested_device_id;
+ });
+ return it != devices.end() ? &(*it) : nullptr;
+ }
+
+ if (!devices.empty())
+ return &devices[0];
+
+ return nullptr;
+}
+
+} // namespace
+
+namespace media_capture_util {
+
+// See also Chrome's MediaCaptureDevicesDispatcher.
+void GrantMediaStreamRequest(content::WebContents* web_contents,
+ const content::MediaStreamRequest& request,
+ const content::MediaResponseCallback& callback,
+ const Extension* extension) {
+ // app_shell only supports audio and video capture, not tab or screen capture.
+ DCHECK(request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
+ request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
+
+ MediaStreamDevices devices;
+
+ if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
+ VerifyMediaAccessPermission(request.audio_type, extension);
+ const MediaStreamDevice* device = GetRequestedDeviceOrDefault(
+ MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices(),
+ request.requested_audio_device_id);
+ if (device)
+ devices.push_back(*device);
+ }
+
+ if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
+ VerifyMediaAccessPermission(request.video_type, extension);
+ const MediaStreamDevice* device = GetRequestedDeviceOrDefault(
+ MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices(),
+ request.requested_video_device_id);
+ if (device)
+ devices.push_back(*device);
+ }
+
+ // TODO(jamescook): Should we show a recording icon somewhere? If so, where?
+ std::unique_ptr<MediaStreamUI> ui;
+ callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE
+ : content::MEDIA_DEVICE_OK,
+ std::move(ui));
+}
+
+void VerifyMediaAccessPermission(content::MediaStreamType type,
+ const Extension* extension) {
+ const PermissionsData* permissions_data = extension->permissions_data();
+ if (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
+ // app_shell has no UI surface to show an error, and on an embedded device
+ // it's better to crash than to have a feature not work.
+ CHECK(permissions_data->HasAPIPermission(APIPermission::kAudioCapture))
+ << "Audio capture request but no audioCapture permission in manifest.";
+ } else {
+ DCHECK(type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
+ CHECK(permissions_data->HasAPIPermission(APIPermission::kVideoCapture))
+ << "Video capture request but no videoCapture permission in manifest.";
+ }
+}
+
+bool CheckMediaAccessPermission(content::MediaStreamType type,
+ const Extension* extension) {
+ const PermissionsData* permissions_data = extension->permissions_data();
+ if (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
+ return permissions_data->HasAPIPermission(APIPermission::kAudioCapture);
+ }
+ DCHECK(type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
+ return permissions_data->HasAPIPermission(APIPermission::kVideoCapture);
+}
+
+} // namespace media_capture_util
+} // namespace extensions
diff --git a/chromium/extensions/browser/media_capture_util.h b/chromium/extensions/browser/media_capture_util.h
new file mode 100644
index 00000000000..df26857da33
--- /dev/null
+++ b/chromium/extensions/browser/media_capture_util.h
@@ -0,0 +1,42 @@
+// 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 EXTENSIONS_BROWSER_MEDIA_CAPTURE_UTIL_H_
+#define EXTENSIONS_BROWSER_MEDIA_CAPTURE_UTIL_H_
+
+#include "base/macros.h"
+#include "content/public/common/media_stream_request.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace extensions {
+
+class Extension;
+
+namespace media_capture_util {
+
+// Grants access to audio and video capture devices.
+// * If the caller requests specific device ids, grants access to those.
+// * If the caller does not request specific ids, grants access to the first
+// available device.
+// Usually used as a helper for media capture ProcessMediaAccessRequest().
+void GrantMediaStreamRequest(content::WebContents* web_contents,
+ const content::MediaStreamRequest& request,
+ const content::MediaResponseCallback& callback,
+ const Extension* extension);
+
+// Verifies that the extension has permission for |type|. If not, crash.
+void VerifyMediaAccessPermission(content::MediaStreamType type,
+ const Extension* extension);
+
+// Check if the extension has permission for |type|.
+bool CheckMediaAccessPermission(content::MediaStreamType type,
+ const Extension* extension);
+
+} // namespace media_capture_util
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_MEDIA_CAPTURE_UTIL_H_
diff --git a/chromium/extensions/browser/mock_external_provider.cc b/chromium/extensions/browser/mock_external_provider.cc
index 988bdb288b6..52820e71378 100644
--- a/chromium/extensions/browser/mock_external_provider.cc
+++ b/chromium/extensions/browser/mock_external_provider.cc
@@ -24,40 +24,57 @@ void MockExternalProvider::UpdateOrAddExtension(const ExtensionId& id,
auto info = std::make_unique<ExternalInstallInfoFile>(
id, base::Version(version_str), path, location_, Extension::NO_FLAGS,
false, false);
- extension_map_[id] = std::move(info);
+ UpdateOrAddExtension(std::move(info));
}
void MockExternalProvider::UpdateOrAddExtension(
std::unique_ptr<ExternalInstallInfoFile> info) {
- std::string id = info->extension_id;
- extension_map_[id] = std::move(info);
+ const std::string& id = info->extension_id;
+ CHECK(url_extension_map_.find(id) == url_extension_map_.end());
+ file_extension_map_[id] = std::move(info);
+}
+
+void MockExternalProvider::UpdateOrAddExtension(
+ std::unique_ptr<ExternalInstallInfoUpdateUrl> info) {
+ const std::string& id = info->extension_id;
+ CHECK(file_extension_map_.find(id) == file_extension_map_.end());
+ url_extension_map_[id] = std::move(info);
}
void MockExternalProvider::RemoveExtension(const ExtensionId& id) {
- extension_map_.erase(id);
+ file_extension_map_.erase(id);
+ url_extension_map_.erase(id);
}
void MockExternalProvider::VisitRegisteredExtension() {
visit_count_++;
- for (const auto& extension_kv : extension_map_)
+ for (const auto& extension_kv : file_extension_map_)
visitor_->OnExternalExtensionFileFound(*extension_kv.second);
+ for (const auto& extension_kv : url_extension_map_)
+ visitor_->OnExternalExtensionUpdateUrlFound(*extension_kv.second,
+ true /* is_initial_load */);
visitor_->OnExternalProviderReady(this);
}
bool MockExternalProvider::HasExtension(const std::string& id) const {
- return extension_map_.find(id) != extension_map_.end();
+ return file_extension_map_.find(id) != file_extension_map_.end() ||
+ url_extension_map_.find(id) != url_extension_map_.end();
}
bool MockExternalProvider::GetExtensionDetails(
const std::string& id,
Manifest::Location* location,
std::unique_ptr<base::Version>* version) const {
- DataMap::const_iterator it = extension_map_.find(id);
- if (it == extension_map_.end())
+ FileDataMap::const_iterator it1 = file_extension_map_.find(id);
+ UrlDataMap::const_iterator it2 = url_extension_map_.find(id);
+
+ // |id| can't be on both |file_extension_map_| and |url_extension_map_|.
+ if (it1 == file_extension_map_.end() && it2 == url_extension_map_.end())
return false;
- if (version)
- version->reset(new base::Version(it->second->version));
+ // Only ExternalInstallInfoFile has version.
+ if (version && it1 != file_extension_map_.end())
+ version->reset(new base::Version(it1->second->version));
if (location)
*location = location_;
diff --git a/chromium/extensions/browser/mock_external_provider.h b/chromium/extensions/browser/mock_external_provider.h
index bc94c4bac94..0069a4d5f39 100644
--- a/chromium/extensions/browser/mock_external_provider.h
+++ b/chromium/extensions/browser/mock_external_provider.h
@@ -31,6 +31,7 @@ class MockExternalProvider : public ExternalProviderInterface {
const std::string& version,
const base::FilePath& path);
void UpdateOrAddExtension(std::unique_ptr<ExternalInstallInfoFile> info);
+ void UpdateOrAddExtension(std::unique_ptr<ExternalInstallInfoUpdateUrl> info);
void RemoveExtension(const ExtensionId& id);
// ExternalProviderInterface implementation:
@@ -47,9 +48,12 @@ class MockExternalProvider : public ExternalProviderInterface {
void set_visit_count(int visit_count) { visit_count_ = visit_count; }
private:
- using DataMap =
+ using FileDataMap =
std::map<ExtensionId, std::unique_ptr<ExternalInstallInfoFile>>;
- DataMap extension_map_;
+ using UrlDataMap =
+ std::map<ExtensionId, std::unique_ptr<ExternalInstallInfoUpdateUrl>>;
+ FileDataMap file_extension_map_;
+ UrlDataMap url_extension_map_;
Manifest::Location location_;
VisitorInterface* visitor_;
diff --git a/chromium/extensions/browser/path_util.cc b/chromium/extensions/browser/path_util.cc
index 88a714eadc1..24f288a3bea 100644
--- a/chromium/extensions/browser/path_util.cc
+++ b/chromium/extensions/browser/path_util.cc
@@ -65,8 +65,10 @@ void OnDirectorySizeCalculated(
base::FilePath PrettifyPath(const base::FilePath& source_path) {
base::FilePath home_path;
- if (source_path.empty() || !PathService::Get(base::DIR_HOME, &home_path))
+ if (source_path.empty() ||
+ !base::PathService::Get(base::DIR_HOME, &home_path)) {
return source_path;
+ }
base::FilePath display_path = base::FilePath(kHomeShortcut);
if (source_path == home_path)
@@ -127,7 +129,7 @@ base::FilePath ResolveHomeDirectory(const base::FilePath& path) {
return path;
}
base::FilePath result;
- PathService::Get(base::DIR_HOME, &result);
+ base::PathService::Get(base::DIR_HOME, &result);
// The user could specify "~" or "~/", so be safe.
if (value.length() > 2) {
result = result.Append(value.substr(2));
diff --git a/chromium/extensions/browser/path_util_unittest.cc b/chromium/extensions/browser/path_util_unittest.cc
index a57d9cca3b7..bdac4ffe4d9 100644
--- a/chromium/extensions/browser/path_util_unittest.cc
+++ b/chromium/extensions/browser/path_util_unittest.cc
@@ -48,7 +48,7 @@ TEST(ExtensionPathUtilTest, BasicPrettifyPathTest) {
TEST(ExtensionPathUtilTest, ResolveHomeDirTest) {
FilePath home_dir;
- ASSERT_TRUE(PathService::Get(base::DIR_HOME, &home_dir));
+ ASSERT_TRUE(base::PathService::Get(base::DIR_HOME, &home_dir));
const FilePath abs_path(FILE_PATH_LITERAL("/foo/bar/baz"));
const FilePath rel_path(FILE_PATH_LITERAL("foo/bar/baz"));
const FilePath rel_path_with_tilde(FILE_PATH_LITERAL("~/foo/bar"));
diff --git a/chromium/extensions/browser/runtime_data_unittest.cc b/chromium/extensions/browser/runtime_data_unittest.cc
index 14b4387c436..f52583a5d21 100644
--- a/chromium/extensions/browser/runtime_data_unittest.cc
+++ b/chromium/extensions/browser/runtime_data_unittest.cc
@@ -20,11 +20,7 @@ namespace {
// Creates a very simple extension with a background page.
scoped_refptr<Extension> CreateExtensionWithBackgroundPage() {
return ExtensionBuilder("test")
- .MergeManifest(
- DictionaryBuilder()
- .Set("background",
- DictionaryBuilder().Set("page", "bg.html").Build())
- .Build())
+ .SetBackgroundPage(ExtensionBuilder::BackgroundPage::PERSISTENT)
.SetID("id2")
.Build();
}
diff --git a/chromium/extensions/browser/sandboxed_unpacker.cc b/chromium/extensions/browser/sandboxed_unpacker.cc
index c4bb27232fc..31cc189b745 100644
--- a/chromium/extensions/browser/sandboxed_unpacker.cc
+++ b/chromium/extensions/browser/sandboxed_unpacker.cc
@@ -29,6 +29,8 @@
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/declarative_net_request/utils.h"
#include "extensions/browser/extension_file_task_runner.h"
+#include "extensions/browser/install/crx_install_error.h"
+#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
#include "extensions/browser/zipfile_installer.h"
#include "extensions/common/api/declarative_net_request/dnr_manifest_data.h"
#include "extensions/common/constants.h"
@@ -174,7 +176,7 @@ bool FindWritableTempLocation(const base::FilePath& extensions_dir,
// directory to provide additional security/privacy and speed up the rest of
// the extension install process.
#if !defined(OS_CHROMEOS)
- PathService::Get(base::DIR_TEMP, temp_dir);
+ base::PathService::Get(base::DIR_TEMP, temp_dir);
if (VerifyJunctionFreeLocation(temp_dir))
return true;
#endif
@@ -249,7 +251,7 @@ bool SandboxedUnpacker::CreateTempDirectory() {
base::FilePath temp_dir;
if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) {
- ReportFailure(COULD_NOT_GET_TEMP_DIRECTORY,
+ ReportFailure(SandboxedUnpackerFailureReason::COULD_NOT_GET_TEMP_DIRECTORY,
l10n_util::GetStringFUTF16(
IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY")));
@@ -257,10 +259,11 @@ bool SandboxedUnpacker::CreateTempDirectory() {
}
if (!temp_dir_.CreateUniqueTempDirUnderPath(temp_dir)) {
- ReportFailure(COULD_NOT_CREATE_TEMP_DIRECTORY,
- l10n_util::GetStringFUTF16(
- IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
- ASCIIToUTF16("COULD_NOT_CREATE_TEMP_DIRECTORY")));
+ ReportFailure(
+ SandboxedUnpackerFailureReason::COULD_NOT_CREATE_TEMP_DIRECTORY,
+ l10n_util::GetStringFUTF16(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("COULD_NOT_CREATE_TEMP_DIRECTORY")));
return false;
}
@@ -303,7 +306,8 @@ void SandboxedUnpacker::StartWithCrx(const CRXFileInfo& crx_info) {
if (!base::CopyFile(crx_info.path, temp_crx_path)) {
// Failed to copy extension file to temporary directory.
ReportFailure(
- FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY,
+ SandboxedUnpackerFailureReason::
+ FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY,
l10n_util::GetStringFUTF16(
IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY")));
@@ -319,8 +323,9 @@ void SandboxedUnpacker::StartWithCrx(const CRXFileInfo& crx_info) {
if (!base::NormalizeFilePath(temp_crx_path, &link_free_crx_path)) {
LOG(ERROR) << "Could not get the normalized path of "
<< temp_crx_path.value();
- ReportFailure(COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
- l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED));
+ ReportFailure(
+ SandboxedUnpackerFailureReason::COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
+ l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED));
return;
}
@@ -335,7 +340,7 @@ void SandboxedUnpacker::StartWithCrx(const CRXFileInfo& crx_info) {
if (!base::CreateDirectoryAndGetError(unzipped_dir, &error)) {
LOG(ERROR) << "Failed to created directory " << unzipped_dir.value()
<< " with error " << error;
- ReportFailure(UNZIP_FAILED,
+ ReportFailure(SandboxedUnpackerFailureReason::UNZIP_FAILED,
l10n_util::GetStringUTF16(IDS_EXTENSION_PACKAGE_UNZIP_ERROR));
return;
}
@@ -357,7 +362,7 @@ void SandboxedUnpacker::StartWithDirectory(const std::string& extension_id,
LOG(ERROR) << "Could not move " << directory.value() << " to "
<< extension_root_.value();
ReportFailure(
- DIRECTORY_MOVE_FAILED,
+ SandboxedUnpackerFailureReason::DIRECTORY_MOVE_FAILED,
l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("DIRECTORY_MOVE_FAILED")));
return;
@@ -406,10 +411,10 @@ void SandboxedUnpacker::UnzipDone(const base::FilePath& zip_file,
if (!error.empty()) {
unpacker_io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &SandboxedUnpacker::ReportFailure, this, UNZIP_FAILED,
- l10n_util::GetStringUTF16(IDS_EXTENSION_PACKAGE_UNZIP_ERROR)));
+ FROM_HERE, base::BindOnce(&SandboxedUnpacker::ReportFailure, this,
+ SandboxedUnpackerFailureReason::UNZIP_FAILED,
+ l10n_util::GetStringUTF16(
+ IDS_EXTENSION_PACKAGE_UNZIP_ERROR)));
return;
}
@@ -428,7 +433,7 @@ void SandboxedUnpacker::Unpack(const base::FilePath& directory) {
}
void SandboxedUnpacker::ReadManifestDone(
- std::unique_ptr<base::Value> manifest,
+ base::Optional<base::Value> manifest,
const base::Optional<std::string>& error) {
DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
if (error) {
@@ -441,7 +446,8 @@ void SandboxedUnpacker::ReadManifestDone(
}
std::unique_ptr<base::DictionaryValue> manifest_dict =
- base::DictionaryValue::From(std::move(manifest));
+ base::DictionaryValue::From(
+ base::Value::ToUniquePtrValue(std::move(manifest.value())));
std::string error_msg;
scoped_refptr<Extension> extension(
@@ -484,7 +490,7 @@ void SandboxedUnpacker::UnpackExtensionSucceeded(
if (!extension_l10n_util::LocalizeExtension(
extension_root_, final_manifest.get(), &utf8_error)) {
ReportFailure(
- COULD_NOT_LOCALIZE_EXTENSION,
+ SandboxedUnpackerFailureReason::COULD_NOT_LOCALIZE_EXTENSION,
l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE,
base::UTF8ToUTF16(utf8_error)));
return;
@@ -495,7 +501,7 @@ void SandboxedUnpacker::UnpackExtensionSucceeded(
Extension::REQUIRE_KEY | creation_flags_, &utf8_error);
if (!extension_.get()) {
- ReportFailure(INVALID_MANIFEST,
+ ReportFailure(SandboxedUnpackerFailureReason::INVALID_MANIFEST,
ASCIIToUTF16("Manifest is invalid: " + utf8_error));
return;
}
@@ -511,10 +517,11 @@ void SandboxedUnpacker::UnpackExtensionSucceeded(
base::FilePath::FromUTF8Unsafe(original_install_icon_path),
&install_icon_path_)) {
// Invalid path for browser image.
- ReportFailure(INVALID_PATH_FOR_BROWSER_IMAGE,
- l10n_util::GetStringFUTF16(
- IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
- ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE")));
+ ReportFailure(
+ SandboxedUnpackerFailureReason::INVALID_PATH_FOR_BROWSER_IMAGE,
+ l10n_util::GetStringFUTF16(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE")));
return;
}
@@ -544,11 +551,13 @@ void SandboxedUnpacker::ImageSanitizationDone(
return;
}
- FailureReason failure_reason = UNPACKER_CLIENT_FAILED;
+ SandboxedUnpackerFailureReason failure_reason =
+ SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED;
base::string16 error;
switch (status) {
case ImageSanitizer::Status::kImagePathError:
- failure_reason = INVALID_PATH_FOR_BROWSER_IMAGE;
+ failure_reason =
+ SandboxedUnpackerFailureReason::INVALID_PATH_FOR_BROWSER_IMAGE;
error = l10n_util::GetStringFUTF16(
IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE"));
@@ -561,25 +570,28 @@ void SandboxedUnpacker::ImageSanitizationDone(
file_path_for_error.BaseName().LossyDisplayName()));
break;
case ImageSanitizer::Status::kFileDeleteError:
- failure_reason = ERROR_REMOVING_OLD_IMAGE_FILE;
+ failure_reason =
+ SandboxedUnpackerFailureReason::ERROR_REMOVING_OLD_IMAGE_FILE;
error = l10n_util::GetStringFUTF16(
IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE"));
break;
case ImageSanitizer::Status::kEncodingError:
- failure_reason = ERROR_RE_ENCODING_THEME_IMAGE;
+ failure_reason =
+ SandboxedUnpackerFailureReason::ERROR_RE_ENCODING_THEME_IMAGE;
error = l10n_util::GetStringFUTF16(
IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE"));
break;
case ImageSanitizer::Status::kFileWriteError:
- failure_reason = ERROR_SAVING_THEME_IMAGE;
+ failure_reason = SandboxedUnpackerFailureReason::ERROR_SAVING_THEME_IMAGE;
error =
l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"));
break;
case ImageSanitizer::Status::kServiceError:
- failure_reason = UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL;
+ failure_reason = SandboxedUnpackerFailureReason::
+ UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL;
error = l10n_util::GetStringFUTF16(
IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("ERROR_UTILITY_PROCESS_CRASH"));
@@ -633,24 +645,26 @@ void SandboxedUnpacker::MessageCatalogsSanitized(
return;
}
- FailureReason failure_reason = UNPACKER_CLIENT_FAILED;
+ SandboxedUnpackerFailureReason failure_reason =
+ SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED;
base::string16 error;
switch (status) {
case JsonFileSanitizer::Status::kFileReadError:
case JsonFileSanitizer::Status::kDecodingError:
- failure_reason = INVALID_CATALOG_DATA;
+ failure_reason = SandboxedUnpackerFailureReason::INVALID_CATALOG_DATA;
error = l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("INVALID_CATALOG_DATA"));
break;
case JsonFileSanitizer::Status::kSerializingError:
- failure_reason = ERROR_SERIALIZING_CATALOG;
+ failure_reason =
+ SandboxedUnpackerFailureReason::ERROR_SERIALIZING_CATALOG;
error =
l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("ERROR_SERIALIZING_CATALOG"));
break;
case JsonFileSanitizer::Status::kFileDeleteError:
case JsonFileSanitizer::Status::kFileWriteError:
- failure_reason = ERROR_SAVING_CATALOG;
+ failure_reason = SandboxedUnpackerFailureReason::ERROR_SAVING_CATALOG;
error = l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("ERROR_SAVING_CATALOG"));
break;
@@ -671,7 +685,8 @@ void SandboxedUnpacker::ReadJSONRulesetIfNeeded(
extension_.get());
if (!resource) {
ReadJSONRulesetDone(std::move(manifest),
- /*json_ruleset=*/nullptr, /*error=*/base::nullopt);
+ /*json_ruleset=*/base::nullopt,
+ /*error=*/base::nullopt);
return;
}
@@ -682,7 +697,7 @@ void SandboxedUnpacker::ReadJSONRulesetIfNeeded(
void SandboxedUnpacker::ReadJSONRulesetDone(
std::unique_ptr<base::DictionaryValue> manifest,
- std::unique_ptr<base::Value> json_ruleset,
+ base::Optional<base::Value> json_ruleset,
const base::Optional<std::string>& error) {
DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
@@ -698,8 +713,13 @@ void SandboxedUnpacker::ReadJSONRulesetDone(
// Index and persist ruleset for the Declarative Net Request API.
base::Optional<int> dnr_ruleset_checksum;
+ std::unique_ptr<base::Value> json_ruleset_ptr =
+ json_ruleset
+ ? base::Value::ToUniquePtrValue(std::move(json_ruleset.value()))
+ : nullptr;
+
if (!IndexAndPersistRulesIfNeeded(
- base::ListValue::From(std::move(json_ruleset)),
+ base::ListValue::From(std::move(json_ruleset_ptr)),
&dnr_ruleset_checksum)) {
return; // Failure was already reported.
}
@@ -728,7 +748,7 @@ bool SandboxedUnpacker::IndexAndPersistRulesIfNeeded(
if (!declarative_net_request::IndexAndPersistRules(
*json_ruleset, *extension_, &error, &warnings, &ruleset_checksum)) {
ReportFailure(
- ERROR_INDEXING_DNR_RULESET,
+ SandboxedUnpackerFailureReason::ERROR_INDEXING_DNR_RULESET,
l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE,
base::UTF8ToUTF16(error)));
return false;
@@ -745,7 +765,8 @@ data_decoder::mojom::JsonParser* SandboxedUnpacker::GetJsonParserPtr() {
connector_->BindInterface(data_decoder_identity_, &json_parser_ptr_);
json_parser_ptr_.set_connection_error_handler(base::BindOnce(
&SandboxedUnpacker::ReportFailure, this,
- UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
+ SandboxedUnpackerFailureReason::
+ UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
l10n_util::GetStringFUTF16(
IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) +
@@ -764,102 +785,106 @@ void SandboxedUnpacker::ReportUnpackingError(base::StringPiece error) {
void SandboxedUnpacker::UnpackExtensionFailed(const base::string16& error) {
DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
ReportFailure(
- UNPACKER_CLIENT_FAILED,
+ SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED,
l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error));
}
base::string16 SandboxedUnpacker::FailureReasonToString16(
- FailureReason reason) {
+ const SandboxedUnpackerFailureReason reason) {
switch (reason) {
- case COULD_NOT_GET_TEMP_DIRECTORY:
+ case SandboxedUnpackerFailureReason::COULD_NOT_GET_TEMP_DIRECTORY:
return ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY");
- case COULD_NOT_CREATE_TEMP_DIRECTORY:
+ case SandboxedUnpackerFailureReason::COULD_NOT_CREATE_TEMP_DIRECTORY:
return ASCIIToUTF16("COULD_NOT_CREATE_TEMP_DIRECTORY");
- case FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY:
+ case SandboxedUnpackerFailureReason::
+ FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY:
return ASCIIToUTF16("FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY");
- case COULD_NOT_GET_SANDBOX_FRIENDLY_PATH:
+ case SandboxedUnpackerFailureReason::COULD_NOT_GET_SANDBOX_FRIENDLY_PATH:
return ASCIIToUTF16("COULD_NOT_GET_SANDBOX_FRIENDLY_PATH");
- case COULD_NOT_LOCALIZE_EXTENSION:
+ case SandboxedUnpackerFailureReason::COULD_NOT_LOCALIZE_EXTENSION:
return ASCIIToUTF16("COULD_NOT_LOCALIZE_EXTENSION");
- case INVALID_MANIFEST:
+ case SandboxedUnpackerFailureReason::INVALID_MANIFEST:
return ASCIIToUTF16("INVALID_MANIFEST");
- case UNPACKER_CLIENT_FAILED:
+ case SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED:
return ASCIIToUTF16("UNPACKER_CLIENT_FAILED");
- case UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL:
+ case SandboxedUnpackerFailureReason::
+ UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL:
return ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL");
- case CRX_FILE_NOT_READABLE:
+ case SandboxedUnpackerFailureReason::CRX_FILE_NOT_READABLE:
return ASCIIToUTF16("CRX_FILE_NOT_READABLE");
- case CRX_HEADER_INVALID:
+ case SandboxedUnpackerFailureReason::CRX_HEADER_INVALID:
return ASCIIToUTF16("CRX_HEADER_INVALID");
- case CRX_MAGIC_NUMBER_INVALID:
+ case SandboxedUnpackerFailureReason::CRX_MAGIC_NUMBER_INVALID:
return ASCIIToUTF16("CRX_MAGIC_NUMBER_INVALID");
- case CRX_VERSION_NUMBER_INVALID:
+ case SandboxedUnpackerFailureReason::CRX_VERSION_NUMBER_INVALID:
return ASCIIToUTF16("CRX_VERSION_NUMBER_INVALID");
- case CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE:
+ case SandboxedUnpackerFailureReason::CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE:
return ASCIIToUTF16("CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE");
- case CRX_ZERO_KEY_LENGTH:
+ case SandboxedUnpackerFailureReason::CRX_ZERO_KEY_LENGTH:
return ASCIIToUTF16("CRX_ZERO_KEY_LENGTH");
- case CRX_ZERO_SIGNATURE_LENGTH:
+ case SandboxedUnpackerFailureReason::CRX_ZERO_SIGNATURE_LENGTH:
return ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH");
- case CRX_PUBLIC_KEY_INVALID:
+ case SandboxedUnpackerFailureReason::CRX_PUBLIC_KEY_INVALID:
return ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID");
- case CRX_SIGNATURE_INVALID:
+ case SandboxedUnpackerFailureReason::CRX_SIGNATURE_INVALID:
return ASCIIToUTF16("CRX_SIGNATURE_INVALID");
- case CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED:
+ case SandboxedUnpackerFailureReason::
+ CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED:
return ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED");
- case CRX_SIGNATURE_VERIFICATION_FAILED:
+ case SandboxedUnpackerFailureReason::CRX_SIGNATURE_VERIFICATION_FAILED:
return ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED");
- case CRX_FILE_IS_DELTA_UPDATE:
+ case SandboxedUnpackerFailureReason::CRX_FILE_IS_DELTA_UPDATE:
return ASCIIToUTF16("CRX_FILE_IS_DELTA_UPDATE");
- case CRX_EXPECTED_HASH_INVALID:
+ case SandboxedUnpackerFailureReason::CRX_EXPECTED_HASH_INVALID:
return ASCIIToUTF16("CRX_EXPECTED_HASH_INVALID");
- case ERROR_SERIALIZING_MANIFEST_JSON:
+ case SandboxedUnpackerFailureReason::ERROR_SERIALIZING_MANIFEST_JSON:
return ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON");
- case ERROR_SAVING_MANIFEST_JSON:
+ case SandboxedUnpackerFailureReason::ERROR_SAVING_MANIFEST_JSON:
return ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON");
- case INVALID_PATH_FOR_BROWSER_IMAGE:
+ case SandboxedUnpackerFailureReason::INVALID_PATH_FOR_BROWSER_IMAGE:
return ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE");
- case ERROR_REMOVING_OLD_IMAGE_FILE:
+ case SandboxedUnpackerFailureReason::ERROR_REMOVING_OLD_IMAGE_FILE:
return ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE");
- case INVALID_PATH_FOR_BITMAP_IMAGE:
+ case SandboxedUnpackerFailureReason::INVALID_PATH_FOR_BITMAP_IMAGE:
return ASCIIToUTF16("INVALID_PATH_FOR_BITMAP_IMAGE");
- case ERROR_RE_ENCODING_THEME_IMAGE:
+ case SandboxedUnpackerFailureReason::ERROR_RE_ENCODING_THEME_IMAGE:
return ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE");
- case ERROR_SAVING_THEME_IMAGE:
+ case SandboxedUnpackerFailureReason::ERROR_SAVING_THEME_IMAGE:
return ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE");
- case INVALID_CATALOG_DATA:
+ case SandboxedUnpackerFailureReason::INVALID_CATALOG_DATA:
return ASCIIToUTF16("INVALID_CATALOG_DATA");
- case ERROR_SERIALIZING_CATALOG:
+ case SandboxedUnpackerFailureReason::ERROR_SERIALIZING_CATALOG:
return ASCIIToUTF16("ERROR_SERIALIZING_CATALOG");
- case ERROR_SAVING_CATALOG:
+ case SandboxedUnpackerFailureReason::ERROR_SAVING_CATALOG:
return ASCIIToUTF16("ERROR_SAVING_CATALOG");
- case CRX_HASH_VERIFICATION_FAILED:
+ case SandboxedUnpackerFailureReason::CRX_HASH_VERIFICATION_FAILED:
return ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED");
- case UNZIP_FAILED:
+ case SandboxedUnpackerFailureReason::UNZIP_FAILED:
return ASCIIToUTF16("UNZIP_FAILED");
- case DIRECTORY_MOVE_FAILED:
+ case SandboxedUnpackerFailureReason::DIRECTORY_MOVE_FAILED:
return ASCIIToUTF16("DIRECTORY_MOVE_FAILED");
- case ERROR_PARSING_DNR_RULESET:
+ case SandboxedUnpackerFailureReason::ERROR_PARSING_DNR_RULESET:
return ASCIIToUTF16("ERROR_PARSING_DNR_RULESET");
- case ERROR_INDEXING_DNR_RULESET:
+ case SandboxedUnpackerFailureReason::ERROR_INDEXING_DNR_RULESET:
return ASCIIToUTF16("ERROR_INDEXING_DNR_RULESET");
- case DEPRECATED_ABORTED_DUE_TO_SHUTDOWN:
- case NUM_FAILURE_REASONS:
+ case SandboxedUnpackerFailureReason::DEPRECATED_ABORTED_DUE_TO_SHUTDOWN:
+ case SandboxedUnpackerFailureReason::NUM_FAILURE_REASONS:
default:
NOTREACHED();
return base::string16();
}
}
-void SandboxedUnpacker::FailWithPackageError(FailureReason reason) {
+void SandboxedUnpacker::FailWithPackageError(
+ const SandboxedUnpackerFailureReason reason) {
ReportFailure(reason,
l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE,
FailureReasonToString16(reason)));
@@ -870,7 +895,8 @@ bool SandboxedUnpacker::ValidateSignature(const base::FilePath& crx_path,
std::vector<uint8_t> hash;
if (!expected_hash.empty()) {
if (!base::HexStringToBytes(expected_hash, &hash)) {
- FailWithPackageError(CRX_EXPECTED_HASH_INVALID);
+ FailWithPackageError(
+ SandboxedUnpackerFailureReason::CRX_EXPECTED_HASH_INVALID);
return false;
}
}
@@ -885,22 +911,28 @@ bool SandboxedUnpacker::ValidateSignature(const base::FilePath& crx_path,
return true;
}
case crx_file::VerifierResult::OK_DELTA:
- FailWithPackageError(CRX_FILE_IS_DELTA_UPDATE);
+ FailWithPackageError(
+ SandboxedUnpackerFailureReason::CRX_FILE_IS_DELTA_UPDATE);
break;
case crx_file::VerifierResult::ERROR_FILE_NOT_READABLE:
- FailWithPackageError(CRX_FILE_NOT_READABLE);
+ FailWithPackageError(
+ SandboxedUnpackerFailureReason::CRX_FILE_NOT_READABLE);
break;
case crx_file::VerifierResult::ERROR_HEADER_INVALID:
- FailWithPackageError(CRX_HEADER_INVALID);
+ FailWithPackageError(SandboxedUnpackerFailureReason::CRX_HEADER_INVALID);
break;
case crx_file::VerifierResult::ERROR_SIGNATURE_INITIALIZATION_FAILED:
- FailWithPackageError(CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED);
+ FailWithPackageError(
+ SandboxedUnpackerFailureReason::
+ CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED);
break;
case crx_file::VerifierResult::ERROR_SIGNATURE_VERIFICATION_FAILED:
- FailWithPackageError(CRX_SIGNATURE_VERIFICATION_FAILED);
+ FailWithPackageError(
+ SandboxedUnpackerFailureReason::CRX_SIGNATURE_VERIFICATION_FAILED);
break;
case crx_file::VerifierResult::ERROR_EXPECTED_HASH_INVALID:
- FailWithPackageError(CRX_EXPECTED_HASH_INVALID);
+ FailWithPackageError(
+ SandboxedUnpackerFailureReason::CRX_EXPECTED_HASH_INVALID);
break;
case crx_file::VerifierResult::ERROR_REQUIRED_PROOF_MISSING:
// We should never get this result, as we do not call
@@ -912,30 +944,28 @@ bool SandboxedUnpacker::ValidateSignature(const base::FilePath& crx_path,
// verification of the crx file's hash.
CHECK(!expected_hash.empty());
UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", false);
- FailWithPackageError(CRX_HASH_VERIFICATION_FAILED);
+ FailWithPackageError(
+ SandboxedUnpackerFailureReason::CRX_HASH_VERIFICATION_FAILED);
break;
}
return false;
}
-void SandboxedUnpacker::ReportFailure(FailureReason reason,
- const base::string16& error) {
+void SandboxedUnpacker::ReportFailure(
+ const SandboxedUnpackerFailureReason reason,
+ const base::string16& error) {
DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
- UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", reason,
- NUM_FAILURE_REASONS);
+ UMA_HISTOGRAM_ENUMERATION(
+ "Extensions.SandboxUnpackFailureReason", reason,
+ SandboxedUnpackerFailureReason::NUM_FAILURE_REASONS);
if (!crx_unpack_start_time_.is_null())
UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime",
base::TimeTicks::Now() - crx_unpack_start_time_);
Cleanup();
- CrxInstallError error_info(reason == CRX_HASH_VERIFICATION_FAILED
- ? CrxInstallError::ERROR_HASH_MISMATCH
- : CrxInstallError::ERROR_OTHER,
- error);
-
- client_->OnUnpackFailure(error_info);
+ client_->OnUnpackFailure(CrxInstallError(reason, error));
}
void SandboxedUnpacker::ReportSuccess(
@@ -974,10 +1004,11 @@ base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile(
serializer.set_pretty_print(true);
if (!serializer.Serialize(*final_manifest)) {
// Error serializing manifest.json.
- ReportFailure(ERROR_SERIALIZING_MANIFEST_JSON,
- l10n_util::GetStringFUTF16(
- IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
- ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON")));
+ ReportFailure(
+ SandboxedUnpackerFailureReason::ERROR_SERIALIZING_MANIFEST_JSON,
+ l10n_util::GetStringFUTF16(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON")));
return NULL;
}
@@ -986,7 +1017,7 @@ base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile(
if (base::WriteFile(manifest_path, manifest_json.data(), size) != size) {
// Error saving manifest.json.
ReportFailure(
- ERROR_SAVING_MANIFEST_JSON,
+ SandboxedUnpackerFailureReason::ERROR_SAVING_MANIFEST_JSON,
l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON")));
return NULL;
@@ -1014,7 +1045,7 @@ void SandboxedUnpacker::ParseJsonFile(
std::string contents;
if (!base::ReadFileToString(path, &contents)) {
std::move(callback).Run(
- /*value=*/nullptr,
+ /*value=*/base::nullopt,
/*error=*/base::Optional<std::string>("File doesn't exist."));
return;
}
diff --git a/chromium/extensions/browser/sandboxed_unpacker.h b/chromium/extensions/browser/sandboxed_unpacker.h
index 24ea37f80b7..3178b125f1f 100644
--- a/chromium/extensions/browser/sandboxed_unpacker.h
+++ b/chromium/extensions/browser/sandboxed_unpacker.h
@@ -16,6 +16,7 @@
#include "base/optional.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
+#include "base/values.h"
#include "extensions/browser/crx_file_info.h"
#include "extensions/browser/image_sanitizer.h"
#include "extensions/browser/install/crx_install_error.h"
@@ -27,8 +28,6 @@
class SkBitmap;
namespace base {
-class DictionaryValue;
-class ListValue;
class SequencedTaskRunner;
}
@@ -38,6 +37,7 @@ class Connector;
namespace extensions {
class Extension;
+enum class SandboxedUnpackerFailureReason;
class SandboxedUnpackerClient
: public base::RefCountedDeleteOnSequence<SandboxedUnpackerClient> {
@@ -99,7 +99,7 @@ class SandboxedUnpackerClient
//
class SandboxedUnpacker : public base::RefCountedThreadSafe<SandboxedUnpacker> {
public:
- // Creates a SanboxedUnpacker that will do work to unpack an extension,
+ // Creates a SandboxedUnpacker that will do work to unpack an extension,
// passing the |location| and |creation_flags| to Extension::Create. The
// |extensions_dir| parameter should specify the directory under which we'll
// create a subdirectory to write the unpacked extension contents.
@@ -133,79 +133,6 @@ class SandboxedUnpacker : public base::RefCountedThreadSafe<SandboxedUnpacker> {
private:
friend class base::RefCountedThreadSafe<SandboxedUnpacker>;
- // Enumerate all the ways unpacking can fail. Calls to ReportFailure()
- // take a failure reason as an argument, and put it in histogram
- // Extensions.SandboxUnpackFailureReason.
- enum FailureReason {
- // SandboxedUnpacker::CreateTempDirectory()
- COULD_NOT_GET_TEMP_DIRECTORY,
- COULD_NOT_CREATE_TEMP_DIRECTORY,
-
- // SandboxedUnpacker::Start()
- FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY,
- COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
-
- // SandboxedUnpacker::UnpackExtensionSucceeded()
- COULD_NOT_LOCALIZE_EXTENSION,
- INVALID_MANIFEST,
-
- // SandboxedUnpacker::UnpackExtensionFailed()
- UNPACKER_CLIENT_FAILED,
-
- // SandboxedUnpacker::UtilityProcessCrashed()
- UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
-
- // SandboxedUnpacker::ValidateSignature()
- CRX_FILE_NOT_READABLE,
- CRX_HEADER_INVALID,
- CRX_MAGIC_NUMBER_INVALID,
- CRX_VERSION_NUMBER_INVALID,
- CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE,
- CRX_ZERO_KEY_LENGTH,
- CRX_ZERO_SIGNATURE_LENGTH,
- CRX_PUBLIC_KEY_INVALID,
- CRX_SIGNATURE_INVALID,
- CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED,
- CRX_SIGNATURE_VERIFICATION_FAILED,
-
- // SandboxedUnpacker::RewriteManifestFile()
- ERROR_SERIALIZING_MANIFEST_JSON,
- ERROR_SAVING_MANIFEST_JSON,
-
- // SandboxedUnpacker::RewriteImageFiles()
- COULD_NOT_READ_IMAGE_DATA_FROM_DISK_UNUSED,
- DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST_UNUSED,
- INVALID_PATH_FOR_BROWSER_IMAGE,
- ERROR_REMOVING_OLD_IMAGE_FILE,
- INVALID_PATH_FOR_BITMAP_IMAGE,
- ERROR_RE_ENCODING_THEME_IMAGE,
- ERROR_SAVING_THEME_IMAGE,
- DEPRECATED_ABORTED_DUE_TO_SHUTDOWN, // No longer used; kept for UMA.
-
- // SandboxedUnpacker::RewriteCatalogFiles()
- COULD_NOT_READ_CATALOG_DATA_FROM_DISK_UNUSED,
- INVALID_CATALOG_DATA,
- INVALID_PATH_FOR_CATALOG_UNUSED,
- ERROR_SERIALIZING_CATALOG,
- ERROR_SAVING_CATALOG,
-
- // SandboxedUnpacker::ValidateSignature()
- CRX_HASH_VERIFICATION_FAILED,
-
- UNZIP_FAILED,
- DIRECTORY_MOVE_FAILED,
-
- // SandboxedUnpacker::ValidateSignature()
- CRX_FILE_IS_DELTA_UPDATE,
- CRX_EXPECTED_HASH_INVALID,
-
- // SandboxedUnpacker::IndexAndPersistRulesIfNeeded()
- ERROR_PARSING_DNR_RULESET,
- ERROR_INDEXING_DNR_RULESET,
-
- NUM_FAILURE_REASONS
- };
-
friend class SandboxedUnpackerTest;
~SandboxedUnpacker();
@@ -214,8 +141,9 @@ class SandboxedUnpacker : public base::RefCountedThreadSafe<SandboxedUnpacker> {
bool CreateTempDirectory();
// Helper functions to simplify calling ReportFailure.
- base::string16 FailureReasonToString16(FailureReason reason);
- void FailWithPackageError(FailureReason reason);
+ base::string16 FailureReasonToString16(
+ const SandboxedUnpackerFailureReason reason);
+ void FailWithPackageError(const SandboxedUnpackerFailureReason reason);
// Validates the signature of the extension and extract the key to
// |public_key_|. True if the signature validates, false otherwise.
@@ -231,7 +159,7 @@ class SandboxedUnpacker : public base::RefCountedThreadSafe<SandboxedUnpacker> {
// Unpacks the extension in directory and returns the manifest.
void Unpack(const base::FilePath& directory);
- void ReadManifestDone(std::unique_ptr<base::Value> manifest,
+ void ReadManifestDone(base::Optional<base::Value> manifest,
const base::Optional<std::string>& error);
void UnpackExtensionSucceeded(
std::unique_ptr<base::DictionaryValue> manifest);
@@ -256,13 +184,17 @@ class SandboxedUnpacker : public base::RefCountedThreadSafe<SandboxedUnpacker> {
void ReadJSONRulesetIfNeeded(std::unique_ptr<base::DictionaryValue> manifest);
void ReadJSONRulesetDone(std::unique_ptr<base::DictionaryValue> manifest,
- std::unique_ptr<base::Value> json_ruleset,
+ base::Optional<base::Value> json_ruleset,
const base::Optional<std::string>& error);
// Reports unpack success or failure, or unzip failure.
void ReportSuccess(std::unique_ptr<base::DictionaryValue> original_manifest,
const base::Optional<int>& dnr_ruleset_checksum);
- void ReportFailure(FailureReason reason, const base::string16& error);
+
+ // Puts a sanboxed unpacker failure in histogram
+ // Extensions.SandboxUnpackFailureReason.
+ void ReportFailure(const SandboxedUnpackerFailureReason reason,
+ const base::string16& error);
// Overwrites original manifest with safe result from utility process.
// Returns NULL on error. Caller owns the returned object.
diff --git a/chromium/extensions/browser/sandboxed_unpacker_unittest.cc b/chromium/extensions/browser/sandboxed_unpacker_unittest.cc
index a5967b9d886..8f611efe616 100644
--- a/chromium/extensions/browser/sandboxed_unpacker_unittest.cc
+++ b/chromium/extensions/browser/sandboxed_unpacker_unittest.cc
@@ -23,6 +23,8 @@
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extensions_test.h"
+#include "extensions/browser/install/crx_install_error.h"
+#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_paths.h"
@@ -34,6 +36,7 @@
#include "services/data_decoder/public/cpp/test_data_decoder_service.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/test/test_connector_factory.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/zlib/google/zip.h"
@@ -81,7 +84,24 @@ class MockSandboxedUnpackerClient : public SandboxedUnpackerClient {
}
base::FilePath temp_dir() const { return temp_dir_; }
- base::string16 unpack_err() const { return error_; }
+ base::string16 unpack_error_message() const {
+ if (error_)
+ return error_->message();
+ return base::string16();
+ }
+ CrxInstallErrorType unpack_error_type() const {
+ if (error_)
+ return error_->type();
+ return CrxInstallErrorType::NONE;
+ }
+ int unpack_error_detail() const {
+ if (error_) {
+ return error_->type() == CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE
+ ? static_cast<int>(error_->sandbox_failure_detail())
+ : static_cast<int>(error_->detail());
+ }
+ return 0;
+ }
void set_deleted_tracker(bool* deleted_tracker) {
deleted_tracker_ = deleted_tracker;
@@ -105,11 +125,11 @@ class MockSandboxedUnpackerClient : public SandboxedUnpackerClient {
}
void OnUnpackFailure(const CrxInstallError& error) override {
- error_ = error.message();
+ error_ = error;
quit_closure_.Run();
}
- base::string16 error_;
+ base::Optional<CrxInstallError> error_;
base::Closure quit_closure_;
base::FilePath temp_dir_;
bool* deleted_tracker_ = nullptr;
@@ -124,9 +144,6 @@ class SandboxedUnpackerTest : public ExtensionsTest {
: ExtensionsTest(options) {}
void SetUp() override {
- // TODO(devlin): Remove this. See https://crbug.com/816679.
- allow_legacy_extensions_ = Extension::allow_legacy_extensions_for_testing();
-
ExtensionsTest::SetUp();
ASSERT_TRUE(extensions_dir_.CreateUniqueTempDir());
in_process_utility_thread_helper_.reset(
@@ -167,12 +184,11 @@ class SandboxedUnpackerTest : public ExtensionsTest {
base::RunLoop().RunUntilIdle();
ExtensionsTest::TearDown();
in_process_utility_thread_helper_.reset();
- allow_legacy_extensions_.reset();
}
base::FilePath GetCrxFullPath(const std::string& crx_name) {
base::FilePath full_path;
- EXPECT_TRUE(PathService::Get(extensions::DIR_TEST_DATA, &full_path));
+ EXPECT_TRUE(base::PathService::Get(extensions::DIR_TEST_DATA, &full_path));
full_path = full_path.AppendASCII("unpacker").AppendASCII(crx_name);
EXPECT_TRUE(base::PathExists(full_path)) << full_path.value();
return full_path;
@@ -211,10 +227,18 @@ class SandboxedUnpackerTest : public ExtensionsTest {
return client_->temp_dir().AppendASCII(kTempExtensionName);
}
- base::string16 GetInstallError() const { return client_->unpack_err(); }
+ base::string16 GetInstallErrorMessage() const {
+ return client_->unpack_error_message();
+ }
+
+ CrxInstallErrorType GetInstallErrorType() const {
+ return client_->unpack_error_type();
+ }
+
+ int GetInstallErrorDetail() const { return client_->unpack_error_detail(); }
void ExpectInstallErrorContains(const std::string& error) {
- std::string full_error = base::UTF16ToUTF8(client_->unpack_err());
+ std::string full_error = base::UTF16ToUTF8(client_->unpack_error_message());
EXPECT_TRUE(full_error.find(error) != std::string::npos)
<< "Error message " << full_error << " does not contain " << error;
}
@@ -226,7 +250,7 @@ class SandboxedUnpackerTest : public ExtensionsTest {
bool client_deleted = false;
client_->set_deleted_tracker(&client_deleted);
SetupUnpacker(package_name, "");
- EXPECT_EQ(GetInstallError().empty(), expect_success);
+ EXPECT_EQ(GetInstallErrorMessage().empty(), expect_success);
// Remove our reference to |sandboxed_unpacker_|, it should get deleted
// since/ it's the last reference.
sandboxed_unpacker_ = nullptr;
@@ -243,57 +267,97 @@ class SandboxedUnpackerTest : public ExtensionsTest {
std::unique_ptr<service_manager::TestConnectorFactory>
test_connector_factory_;
std::unique_ptr<service_manager::Connector> connector_;
- Extension::ScopedAllowLegacyExtensions allow_legacy_extensions_;
};
TEST_F(SandboxedUnpackerTest, EmptyDefaultLocale) {
SetupUnpacker("empty_default_locale.crx", "");
ExpectInstallErrorContains(manifest_errors::kInvalidDefaultLocale);
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, HasDefaultLocaleMissingLocalesFolder) {
SetupUnpacker("has_default_missing_locales.crx", "");
ExpectInstallErrorContains(manifest_errors::kLocalesTreeMissing);
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, InvalidDefaultLocale) {
SetupUnpacker("invalid_default_locale.crx", "");
ExpectInstallErrorContains(manifest_errors::kInvalidDefaultLocale);
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, MissingDefaultData) {
SetupUnpacker("missing_default_data.crx", "");
ExpectInstallErrorContains(manifest_errors::kLocalesNoDefaultMessages);
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, MissingDefaultLocaleHasLocalesFolder) {
SetupUnpacker("missing_default_has_locales.crx", "");
ExpectInstallErrorContains(l10n_util::GetStringUTF8(
IDS_EXTENSION_LOCALES_NO_DEFAULT_LOCALE_SPECIFIED));
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, MissingMessagesFile) {
SetupUnpacker("missing_messages_file.crx", "");
EXPECT_TRUE(base::MatchPattern(
- GetInstallError(),
+ GetInstallErrorMessage(),
base::ASCIIToUTF16("*") +
base::ASCIIToUTF16(manifest_errors::kLocalesMessagesFileMissing) +
base::ASCIIToUTF16("*_locales?en_US?messages.json'.")))
- << GetInstallError();
+ << GetInstallErrorMessage();
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, NoLocaleData) {
SetupUnpacker("no_locale_data.crx", "");
ExpectInstallErrorContains(manifest_errors::kLocalesNoDefaultMessages);
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, ImageDecodingError) {
const char kExpected[] = "Could not decode image: ";
SetupUnpacker("bad_image.crx", "");
- EXPECT_TRUE(base::StartsWith(GetInstallError(), base::ASCIIToUTF16(kExpected),
+ EXPECT_TRUE(base::StartsWith(GetInstallErrorMessage(),
+ base::ASCIIToUTF16(kExpected),
base::CompareCase::INSENSITIVE_ASCII))
<< "Expected prefix: \"" << kExpected << "\", actual error: \""
- << GetInstallError() << "\"";
+ << GetInstallErrorMessage() << "\"";
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, BadPathError) {
@@ -302,7 +366,12 @@ TEST_F(SandboxedUnpackerTest, BadPathError) {
SetupUnpacker("good_package.crx", "");
// Install should have failed with an error.
EXPECT_FALSE(InstallSucceeded());
- EXPECT_FALSE(GetInstallError().empty());
+ EXPECT_FALSE(GetInstallErrorMessage().empty());
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(static_cast<int>(
+ SandboxedUnpackerFailureReason::INVALID_PATH_FOR_BROWSER_IMAGE),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, NoCatalogsSuccess) {
@@ -310,6 +379,7 @@ TEST_F(SandboxedUnpackerTest, NoCatalogsSuccess) {
// Check that there is no _locales folder.
base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
EXPECT_FALSE(base::PathExists(install_path));
+ EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
}
TEST_F(SandboxedUnpackerTest, FromDirNoCatalogsSuccess) {
@@ -317,6 +387,7 @@ TEST_F(SandboxedUnpackerTest, FromDirNoCatalogsSuccess) {
// Check that there is no _locales folder.
base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
EXPECT_FALSE(base::PathExists(install_path));
+ EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
}
TEST_F(SandboxedUnpackerTest, WithCatalogsSuccess) {
@@ -324,6 +395,7 @@ TEST_F(SandboxedUnpackerTest, WithCatalogsSuccess) {
// Check that there is _locales folder.
base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
EXPECT_TRUE(base::PathExists(install_path));
+ EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
}
TEST_F(SandboxedUnpackerTest, FromDirWithCatalogsSuccess) {
@@ -331,6 +403,7 @@ TEST_F(SandboxedUnpackerTest, FromDirWithCatalogsSuccess) {
// Check that there is _locales folder.
base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
EXPECT_TRUE(base::PathExists(install_path));
+ EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
}
TEST_F(SandboxedUnpackerTest, FailHashCheck) {
@@ -338,7 +411,12 @@ TEST_F(SandboxedUnpackerTest, FailHashCheck) {
extensions::switches::kEnableCrxHashCheck);
SetupUnpacker("good_l10n.crx", std::string(64, '0'));
// Check that there is an error message.
- EXPECT_NE(base::string16(), GetInstallError());
+ EXPECT_FALSE(GetInstallErrorMessage().empty());
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(static_cast<int>(
+ SandboxedUnpackerFailureReason::CRX_HASH_VERIFICATION_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, InvalidMessagesFile) {
@@ -347,10 +425,15 @@ TEST_F(SandboxedUnpackerTest, InvalidMessagesFile) {
base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
EXPECT_FALSE(base::PathExists(install_path));
EXPECT_TRUE(base::MatchPattern(
- GetInstallError(),
+ GetInstallErrorMessage(),
base::ASCIIToUTF16("*_locales?en_US?messages.json': Line: 2, column: 10,"
" Syntax error.'.")))
- << GetInstallError();
+ << GetInstallErrorMessage();
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(static_cast<int>(
+ SandboxedUnpackerFailureReason::COULD_NOT_LOCALIZE_EXTENSION),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, PassHashCheck) {
@@ -358,15 +441,17 @@ TEST_F(SandboxedUnpackerTest, PassHashCheck) {
extensions::switches::kEnableCrxHashCheck);
SetupUnpacker(
"good_l10n.crx",
- "6fa171c726373785aa4fcd2df448c3db0420a95d5044fbee831f089b979c4068");
+ "614AE3D608F4C2185E9173293AB3F93EE7C7C79C9A2C3CF71F633386A3296A6C");
// Check that there is no error message.
- EXPECT_EQ(base::string16(), GetInstallError());
+ EXPECT_THAT(GetInstallErrorMessage(), testing::IsEmpty());
+ EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
}
TEST_F(SandboxedUnpackerTest, SkipHashCheck) {
SetupUnpacker("good_l10n.crx", "badhash");
// Check that there is no error message.
- EXPECT_EQ(base::string16(), GetInstallError());
+ EXPECT_THAT(GetInstallErrorMessage(), testing::IsEmpty());
+ EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
}
// The following tests simulate the utility services failling.
@@ -376,7 +461,11 @@ TEST_F(SandboxedUnpackerTest, UnzipperServiceFails) {
std::make_unique<unzip::CrashyUnzipService>());
SetupUnpacker("good_package.crx", "");
EXPECT_FALSE(InstallSucceeded());
- EXPECT_FALSE(GetInstallError().empty());
+ EXPECT_FALSE(GetInstallErrorMessage().empty());
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(static_cast<int>(SandboxedUnpackerFailureReason::UNZIP_FAILED),
+ GetInstallErrorDetail());
}
TEST_F(SandboxedUnpackerTest, JsonParserFails) {
@@ -385,7 +474,9 @@ TEST_F(SandboxedUnpackerTest, JsonParserFails) {
/*unzip_service=*/nullptr);
SetupUnpacker("good_package.crx", "");
EXPECT_FALSE(InstallSucceeded());
- EXPECT_FALSE(GetInstallError().empty());
+ EXPECT_FALSE(GetInstallErrorMessage().empty());
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
}
TEST_F(SandboxedUnpackerTest, ImageDecoderFails) {
@@ -394,7 +485,13 @@ TEST_F(SandboxedUnpackerTest, ImageDecoderFails) {
/*unzip_service=*/nullptr);
SetupUnpacker("good_package.crx", "");
EXPECT_FALSE(InstallSucceeded());
- EXPECT_FALSE(GetInstallError().empty());
+ EXPECT_FALSE(GetInstallErrorMessage().empty());
+ ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
+ GetInstallErrorType());
+ EXPECT_EQ(
+ static_cast<int>(SandboxedUnpackerFailureReason::
+ UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL),
+ GetInstallErrorDetail());
}
// SandboxedUnpacker is ref counted and is reference by callbacks and
diff --git a/chromium/extensions/browser/test_management_policy.cc b/chromium/extensions/browser/test_management_policy.cc
index 42a2f1c5c4b..76b870b89a6 100644
--- a/chromium/extensions/browser/test_management_policy.cc
+++ b/chromium/extensions/browser/test_management_policy.cc
@@ -56,6 +56,15 @@ bool TestManagementPolicyProvider::UserMayModifySettings(
return may_modify_status_;
}
+bool TestManagementPolicyProvider::ExtensionMayModifySettings(
+ const Extension* source_extension,
+ const Extension* extension,
+ base::string16* error) const {
+ if (error && !may_modify_status_)
+ *error = error_message_;
+ return may_modify_status_;
+}
+
bool TestManagementPolicyProvider::MustRemainEnabled(const Extension* extension,
base::string16* error)
const {
diff --git a/chromium/extensions/browser/test_management_policy.h b/chromium/extensions/browser/test_management_policy.h
index 92fe597467e..9f051cbba5d 100644
--- a/chromium/extensions/browser/test_management_policy.h
+++ b/chromium/extensions/browser/test_management_policy.h
@@ -43,6 +43,10 @@ class TestManagementPolicyProvider : public ManagementPolicy::Provider {
bool UserMayModifySettings(const Extension* extension,
base::string16* error) const override;
+ bool ExtensionMayModifySettings(const Extension* source_extension,
+ const Extension* extension,
+ base::string16* error) const override;
+
bool MustRemainEnabled(const Extension* extension,
base::string16* error) const override;
diff --git a/chromium/extensions/browser/updater/extension_downloader.cc b/chromium/extensions/browser/updater/extension_downloader.cc
index d4cd9741964..d2c303f4a10 100644
--- a/chromium/extensions/browser/updater/extension_downloader.cc
+++ b/chromium/extensions/browser/updater/extension_downloader.cc
@@ -34,7 +34,6 @@
#include "extensions/common/extension_updater_uma.h"
#include "extensions/common/extension_urls.h"
#include "extensions/common/manifest_url_handlers.h"
-#include "google_apis/gaia/identity_provider.h"
#include "net/base/backoff_entry.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
@@ -204,13 +203,16 @@ ExtensionDownloader::ExtensionDownloader(
delegate_(delegate),
request_context_(request_context),
connector_(connector),
- manifests_queue_(&kDefaultBackoffPolicy,
- base::Bind(&ExtensionDownloader::CreateManifestFetcher,
- base::Unretained(this))),
- extensions_queue_(&kDefaultBackoffPolicy,
- base::Bind(&ExtensionDownloader::CreateExtensionFetcher,
- base::Unretained(this))),
- extension_cache_(NULL),
+ manifests_queue_(
+ &kDefaultBackoffPolicy,
+ base::BindRepeating(&ExtensionDownloader::CreateManifestFetcher,
+ base::Unretained(this))),
+ extensions_queue_(
+ &kDefaultBackoffPolicy,
+ base::BindRepeating(&ExtensionDownloader::CreateExtensionFetcher,
+ base::Unretained(this))),
+ extension_cache_(nullptr),
+ token_service_(nullptr),
weak_ptr_factory_(this) {
DCHECK(delegate_);
DCHECK(request_context_.get());
@@ -307,9 +309,11 @@ void ExtensionDownloader::StartBlacklistUpdate(
StartUpdateCheck(std::move(blacklist_fetch));
}
-void ExtensionDownloader::SetWebstoreIdentityProvider(
- std::unique_ptr<IdentityProvider> identity_provider) {
- identity_provider_.swap(identity_provider);
+void ExtensionDownloader::SetWebstoreAuthenticationCapabilities(
+ const GetWebstoreAccountCallback& webstore_account_callback,
+ OAuth2TokenService* token_service) {
+ webstore_account_callback_ = webstore_account_callback;
+ token_service_ = token_service;
}
// static
@@ -806,9 +810,9 @@ void ExtensionDownloader::NotifyDelegateDownloadFinished(
delegate_->OnExtensionDownloadFinished(
CRXFileInfo(id, crx_path, package_hash), file_ownership_passed, url,
version, ping_results_[id], request_ids,
- from_cache ? base::Bind(&ExtensionDownloader::CacheInstallDone,
- weak_ptr_factory_.GetWeakPtr(),
- base::Passed(&fetch_data))
+ from_cache ? base::BindRepeating(&ExtensionDownloader::CacheInstallDone,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(&fetch_data))
: ExtensionDownloaderDelegate::InstallCallback());
if (!from_cache)
ping_results_.erase(id);
@@ -882,12 +886,12 @@ void ExtensionDownloader::CreateExtensionFetcher() {
// We should try OAuth2, but we have no token cached. This
// ExtensionFetcher will be started once the token fetch is complete,
// in either OnTokenFetchSuccess or OnTokenFetchFailure.
- DCHECK(identity_provider_.get());
+ DCHECK(token_service_);
+ DCHECK(!webstore_account_callback_.is_null());
OAuth2TokenService::ScopeSet webstore_scopes;
webstore_scopes.insert(kWebstoreOAuth2Scope);
- access_token_request_ =
- identity_provider_->GetTokenService()->StartRequest(
- identity_provider_->GetActiveAccountId(), webstore_scopes, this);
+ access_token_request_ = token_service_->StartRequest(
+ webstore_account_callback_.Run(), webstore_scopes, this);
return;
}
extension_fetcher_->AddExtraRequestHeader(
@@ -923,9 +927,10 @@ void ExtensionDownloader::OnCRXFetchComplete(
const std::string& expected_hash = fetch_data->package_hash;
extension_cache_->PutExtension(
id, expected_hash, crx_path, version,
- base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&fetch_data),
- false));
+ base::BindRepeating(
+ &ExtensionDownloader::NotifyDelegateDownloadFinished,
+ weak_ptr_factory_.GetWeakPtr(), base::Passed(&fetch_data),
+ false));
} else {
NotifyDelegateDownloadFinished(std::move(fetch_data), false, crx_path,
true);
@@ -999,7 +1004,7 @@ bool ExtensionDownloader::IterateFetchCredentialsAfterFailure(
// fetch.
switch (fetch->credentials) {
case ExtensionFetch::CREDENTIALS_NONE:
- if (fetch->url.DomainIs(kGoogleDotCom) && identity_provider_) {
+ if (fetch->url.DomainIs(kGoogleDotCom) && token_service_) {
fetch->credentials = ExtensionFetch::CREDENTIALS_OAUTH2_TOKEN;
} else {
fetch->credentials = ExtensionFetch::CREDENTIALS_COOKIES;
@@ -1011,12 +1016,12 @@ bool ExtensionDownloader::IterateFetchCredentialsAfterFailure(
// should invalidate the token and try again.
if (response_code == net::HTTP_UNAUTHORIZED &&
fetch->oauth2_attempt_count <= kMaxOAuth2Attempts) {
- DCHECK(identity_provider_.get());
+ DCHECK(token_service_);
+ DCHECK(!webstore_account_callback_.is_null());
OAuth2TokenService::ScopeSet webstore_scopes;
webstore_scopes.insert(kWebstoreOAuth2Scope);
- identity_provider_->GetTokenService()->InvalidateAccessToken(
- identity_provider_->GetActiveAccountId(), webstore_scopes,
- access_token_);
+ token_service_->InvalidateAccessToken(webstore_account_callback_.Run(),
+ webstore_scopes, access_token_);
access_token_.clear();
return true;
}
diff --git a/chromium/extensions/browser/updater/extension_downloader.h b/chromium/extensions/browser/updater/extension_downloader.h
index ce8f52a3688..80d3d541df2 100644
--- a/chromium/extensions/browser/updater/extension_downloader.h
+++ b/chromium/extensions/browser/updater/extension_downloader.h
@@ -25,8 +25,6 @@
#include "net/url_request/url_fetcher_delegate.h"
#include "url/gurl.h"
-class IdentityProvider;
-
namespace net {
class URLFetcher;
class URLRequestContextGetter;
@@ -60,9 +58,13 @@ class ExtensionDownloader : public net::URLFetcherDelegate,
public:
// A closure which constructs a new ExtensionDownloader to be owned by the
// caller.
- typedef base::Callback<std::unique_ptr<ExtensionDownloader>(
- ExtensionDownloaderDelegate* delegate)>
- Factory;
+ using Factory = base::RepeatingCallback<std::unique_ptr<ExtensionDownloader>(
+ ExtensionDownloaderDelegate* delegate)>;
+
+ // A closure that returns the account to use for authentication to the
+ // webstore.
+ using GetWebstoreAccountCallback =
+ base::RepeatingCallback<const std::string&()>;
// |delegate| is stored as a raw pointer and must outlive the
// ExtensionDownloader.
@@ -109,10 +111,12 @@ class ExtensionDownloader : public net::URLFetcherDelegate,
const ManifestFetchData::PingData& ping_data,
int request_id);
- // Sets an IdentityProvider to be used for OAuth2 authentication on protected
- // Webstore downloads.
- void SetWebstoreIdentityProvider(
- std::unique_ptr<IdentityProvider> identity_provider);
+ // Sets GetWebstoreAccountCallback and TokenService instances to be used for
+ // OAuth2 authentication on protected Webstore downloads. Both objects must be
+ // valid to use for the lifetime of this object.
+ void SetWebstoreAuthenticationCapabilities(
+ const GetWebstoreAccountCallback& webstore_account_callback,
+ OAuth2TokenService* token_service);
void set_brand_code(const std::string& brand_code) {
brand_code_ = brand_code;
@@ -348,9 +352,13 @@ class ExtensionDownloader : public net::URLFetcherDelegate,
// Cache for .crx files.
ExtensionCache* extension_cache_;
- // An IdentityProvider which may be used for authentication on protected
- // download requests. May be NULL.
- std::unique_ptr<IdentityProvider> identity_provider_;
+ // Gets the account to use for protected download requests. May be null. If
+ // non-null, valid to call for the lifetime of this object.
+ GetWebstoreAccountCallback webstore_account_callback_;
+
+ // May be used to fetch access tokens for protected download requests. May be
+ // null. If non-null, guaranteed to outlive this object.
+ OAuth2TokenService* token_service_;
// A Webstore download-scoped access token for the |identity_provider_|'s
// active account, if any.
diff --git a/chromium/extensions/browser/updater/request_queue_impl.h b/chromium/extensions/browser/updater/request_queue_impl.h
index 5eb5148a959..7e1442edb36 100644
--- a/chromium/extensions/browser/updater/request_queue_impl.h
+++ b/chromium/extensions/browser/updater/request_queue_impl.h
@@ -13,7 +13,6 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
-#include "base/message_loop/message_loop.h"
#include "extensions/browser/updater/request_queue.h"
namespace extensions {
diff --git a/chromium/extensions/browser/updater/update_data_provider.cc b/chromium/extensions/browser/updater/update_data_provider.cc
index b7421dc61b0..161f072815b 100644
--- a/chromium/extensions/browser/updater/update_data_provider.cc
+++ b/chromium/extensions/browser/updater/update_data_provider.cc
@@ -4,13 +4,16 @@
#include "extensions/browser/updater/update_data_provider.h"
+#include <utility>
+
#include "base/base64.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/optional.h"
#include "base/strings/string_util.h"
#include "base/task_scheduler/post_task.h"
-#include "components/update_client/update_client.h"
+#include "components/update_client/utils.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/sha2.h"
#include "extensions/browser/content_verifier.h"
@@ -18,6 +21,8 @@
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extensions_browser_client.h"
+#include "extensions/browser/install/crx_install_error.h"
+#include "extensions/browser/updater/manifest_fetch_data.h"
#include "extensions/common/extension.h"
namespace extensions {
@@ -31,17 +36,26 @@ void InstallUpdateCallback(content::BrowserContext* context,
const std::string& public_key,
const base::FilePath& unpacked_dir,
UpdateClientCallback update_client_callback) {
- using InstallError = update_client::InstallError;
- using Result = update_client::CrxInstaller::Result;
-
+ // Note that error codes are converted into custom error codes, which are all
+ // based on a constant (see ToInstallerResult). This means that custom codes
+ // from different embedders may collide. However, for any given extension ID,
+ // there should be only one embedder, so this should be OK from Omaha.
ExtensionSystem::Get(context)->InstallUpdate(
extension_id, public_key, unpacked_dir,
base::BindOnce(
- [](UpdateClientCallback update_client_callback, bool success) {
+ [](UpdateClientCallback callback,
+ const base::Optional<CrxInstallError>& error) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- std::move(update_client_callback)
- .Run(Result(success ? InstallError::NONE
- : InstallError::GENERIC_ERROR));
+ update_client::CrxInstaller::Result result(0);
+ if (error.has_value()) {
+ int detail =
+ error->type() ==
+ CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE
+ ? static_cast<int>(error->sandbox_failure_detail())
+ : static_cast<int>(error->detail());
+ result = update_client::ToInstallerResult(error->type(), detail);
+ }
+ std::move(callback).Run(result);
},
std::move(update_client_callback)));
}
@@ -57,33 +71,34 @@ void UpdateDataProvider::Shutdown() {
browser_context_ = nullptr;
}
-void UpdateDataProvider::GetData(
- const ExtensionUpdateDataMap& update_info,
- const std::vector<std::string>& ids,
- std::vector<update_client::CrxComponent>* data) {
+std::vector<std::unique_ptr<update_client::CrxComponent>>
+UpdateDataProvider::GetData(const ExtensionUpdateDataMap& update_crx_component,
+ const std::vector<std::string>& ids) {
+ std::vector<std::unique_ptr<update_client::CrxComponent>> data;
if (!browser_context_)
- return;
+ return data;
const ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
const ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser_context_);
for (const auto& id : ids) {
const Extension* extension = registry->GetInstalledExtension(id);
+ data.push_back(extension ? std::make_unique<update_client::CrxComponent>()
+ : nullptr);
if (!extension)
continue;
- DCHECK_GT(update_info.count(id), 0ULL);
- const ExtensionUpdateData& extension_data = update_info.at(id);
- data->push_back(update_client::CrxComponent());
- update_client::CrxComponent* info = &data->back();
+ DCHECK_NE(0u, update_crx_component.count(id));
+ const ExtensionUpdateData& extension_data = update_crx_component.at(id);
+ update_client::CrxComponent* crx_component = data.back().get();
std::string pubkey_bytes;
base::Base64Decode(extension->public_key(), &pubkey_bytes);
- info->pk_hash.resize(crypto::kSHA256Length, 0);
- crypto::SHA256HashString(pubkey_bytes, info->pk_hash.data(),
- info->pk_hash.size());
- info->version = extension_data.is_corrupt_reinstall
- ? base::Version("0.0.0.0")
- : extension->version();
- info->allows_background_download = false;
- info->requires_network_encryption = true;
- info->installer = base::MakeRefCounted<ExtensionInstaller>(
+ crx_component->pk_hash.resize(crypto::kSHA256Length, 0);
+ crypto::SHA256HashString(pubkey_bytes, crx_component->pk_hash.data(),
+ crx_component->pk_hash.size());
+ crx_component->version = extension_data.is_corrupt_reinstall
+ ? base::Version("0.0.0.0")
+ : extension->version();
+ crx_component->allows_background_download = false;
+ crx_component->requires_network_encryption = true;
+ crx_component->installer = base::MakeRefCounted<ExtensionInstaller>(
id, extension->path(),
base::BindOnce(&UpdateDataProvider::RunInstallCallback, this));
if (!ExtensionsBrowserClient::Get()->IsExtensionEnabled(id,
@@ -91,17 +106,20 @@ void UpdateDataProvider::GetData(
int disabled_reasons = extension_prefs->GetDisableReasons(id);
if (disabled_reasons == extensions::disable_reason::DISABLE_NONE ||
disabled_reasons >= extensions::disable_reason::DISABLE_REASON_LAST) {
- info->disabled_reasons.push_back(0);
+ crx_component->disabled_reasons.push_back(0);
}
for (int enum_value = 1;
enum_value < extensions::disable_reason::DISABLE_REASON_LAST;
enum_value <<= 1) {
if (disabled_reasons & enum_value)
- info->disabled_reasons.push_back(enum_value);
+ crx_component->disabled_reasons.push_back(enum_value);
}
}
- info->install_source = extension_data.install_source;
+ crx_component->install_source = extension_data.install_source;
+ crx_component->install_location =
+ ManifestFetchData::GetSimpleLocationString(extension->location());
}
+ return data;
}
void UpdateDataProvider::RunInstallCallback(
diff --git a/chromium/extensions/browser/updater/update_data_provider.h b/chromium/extensions/browser/updater/update_data_provider.h
index 83b04bf0cfe..61a212b0810 100644
--- a/chromium/extensions/browser/updater/update_data_provider.h
+++ b/chromium/extensions/browser/updater/update_data_provider.h
@@ -6,6 +6,7 @@
#define EXTENSIONS_BROWSER_UPDATER_UPDATE_DATA_PROVIDER_H_
#include <map>
+#include <memory>
#include <string>
#include <vector>
@@ -47,9 +48,9 @@ class UpdateDataProvider : public base::RefCounted<UpdateDataProvider> {
void Shutdown();
// Matches update_client::UpdateClient::CrxDataCallback
- void GetData(const ExtensionUpdateDataMap& update_info,
- const std::vector<std::string>& ids,
- std::vector<update_client::CrxComponent>* data);
+ std::vector<std::unique_ptr<update_client::CrxComponent>> GetData(
+ const ExtensionUpdateDataMap& update_info,
+ const std::vector<std::string>& ids);
private:
friend class base::RefCounted<UpdateDataProvider>;
diff --git a/chromium/extensions/browser/updater/update_data_provider_unittest.cc b/chromium/extensions/browser/updater/update_data_provider_unittest.cc
index 2ae8bc14250..3e3749e0525 100644
--- a/chromium/extensions/browser/updater/update_data_provider_unittest.cc
+++ b/chromium/extensions/browser/updater/update_data_provider_unittest.cc
@@ -89,7 +89,8 @@ class UpdateDataProviderTest : public ExtensionsTest {
void AddExtension(const std::string& extension_id,
const std::string& version,
bool enabled,
- int disable_reasons) {
+ int disable_reasons,
+ Manifest::Location location) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
ASSERT_TRUE(base::PathExists(temp_dir.GetPath()));
@@ -109,6 +110,7 @@ class UpdateDataProviderTest : public ExtensionsTest {
.Build());
builder.SetID(extension_id);
builder.SetPath(temp_dir.GetPath());
+ builder.SetLocation(location);
auto* test_browser_client =
static_cast<UpdateDataProviderExtensionsBrowserClient*>(
@@ -136,9 +138,8 @@ TEST_F(UpdateDataProviderTest, GetData_NoDataAdded) {
scoped_refptr<UpdateDataProvider> data_provider =
base::MakeRefCounted<UpdateDataProvider>(nullptr);
- std::vector<std::string> ids({kExtensionId1});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(ExtensionUpdateDataMap(), ids, &data);
+ const auto data =
+ data_provider->GetData(ExtensionUpdateDataMap(), {kExtensionId1});
EXPECT_EQ(0UL, data.size());
}
@@ -148,19 +149,19 @@ TEST_F(UpdateDataProviderTest, GetData_EnabledExtension) {
const std::string version = "0.1.2.3";
AddExtension(kExtensionId1, version, true,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE, Manifest::INTERNAL);
ExtensionUpdateDataMap update_data;
update_data[kExtensionId1] = {};
std::vector<std::string> ids({kExtensionId1});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data = data_provider->GetData(update_data, ids);
ASSERT_EQ(1UL, data.size());
- EXPECT_EQ(version, data[0].version.GetString());
- EXPECT_NE(nullptr, data[0].installer.get());
- EXPECT_EQ(0UL, data[0].disabled_reasons.size());
+ EXPECT_EQ(version, data[0]->version.GetString());
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ EXPECT_EQ(0UL, data[0]->disabled_reasons.size());
+ EXPECT_EQ("internal", data[0]->install_location);
}
TEST_F(UpdateDataProviderTest, GetData_EnabledExtensionWithData) {
@@ -169,22 +170,22 @@ TEST_F(UpdateDataProviderTest, GetData_EnabledExtensionWithData) {
const std::string version = "0.1.2.3";
AddExtension(kExtensionId1, version, true,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE,
+ Manifest::EXTERNAL_PREF);
ExtensionUpdateDataMap update_data;
auto& info = update_data[kExtensionId1];
info.is_corrupt_reinstall = true;
info.install_source = "webstore";
- std::vector<std::string> ids({kExtensionId1});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data = data_provider->GetData(update_data, {kExtensionId1});
ASSERT_EQ(1UL, data.size());
- EXPECT_EQ("0.0.0.0", data[0].version.GetString());
- EXPECT_EQ("webstore", data[0].install_source);
- EXPECT_NE(nullptr, data[0].installer.get());
- EXPECT_EQ(0UL, data[0].disabled_reasons.size());
+ EXPECT_EQ("0.0.0.0", data[0]->version.GetString());
+ EXPECT_EQ("webstore", data[0]->install_source);
+ EXPECT_EQ("external", data[0]->install_location);
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ EXPECT_EQ(0UL, data[0]->disabled_reasons.size());
}
TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_WithNoReason) {
@@ -193,21 +194,21 @@ TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_WithNoReason) {
const std::string version = "0.1.2.3";
AddExtension(kExtensionId1, version, false,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE,
+ Manifest::EXTERNAL_REGISTRY);
ExtensionUpdateDataMap update_data;
update_data[kExtensionId1] = {};
- std::vector<std::string> ids({kExtensionId1});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data = data_provider->GetData(update_data, {kExtensionId1});
ASSERT_EQ(1UL, data.size());
- EXPECT_EQ(version, data[0].version.GetString());
- EXPECT_NE(nullptr, data[0].installer.get());
- ASSERT_EQ(1UL, data[0].disabled_reasons.size());
+ EXPECT_EQ(version, data[0]->version.GetString());
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ ASSERT_EQ(1UL, data[0]->disabled_reasons.size());
EXPECT_EQ(disable_reason::DisableReason::DISABLE_NONE,
- data[0].disabled_reasons[0]);
+ data[0]->disabled_reasons[0]);
+ EXPECT_EQ("external", data[0]->install_location);
}
TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_UnknownReason) {
@@ -216,21 +217,21 @@ TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_UnknownReason) {
const std::string version = "0.1.2.3";
AddExtension(kExtensionId1, version, false,
- disable_reason::DisableReason::DISABLE_REASON_LAST);
+ disable_reason::DisableReason::DISABLE_REASON_LAST,
+ Manifest::COMMAND_LINE);
ExtensionUpdateDataMap update_data;
update_data[kExtensionId1] = {};
- std::vector<std::string> ids({kExtensionId1});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data = data_provider->GetData(update_data, {kExtensionId1});
ASSERT_EQ(1UL, data.size());
- EXPECT_EQ(version, data[0].version.GetString());
- EXPECT_NE(nullptr, data[0].installer.get());
- ASSERT_EQ(1UL, data[0].disabled_reasons.size());
+ EXPECT_EQ(version, data[0]->version.GetString());
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ ASSERT_EQ(1UL, data[0]->disabled_reasons.size());
EXPECT_EQ(disable_reason::DisableReason::DISABLE_NONE,
- data[0].disabled_reasons[0]);
+ data[0]->disabled_reasons[0]);
+ EXPECT_EQ("other", data[0]->install_location);
}
TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_WithReasons) {
@@ -240,23 +241,23 @@ TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_WithReasons) {
const std::string version = "0.1.2.3";
AddExtension(kExtensionId1, version, false,
disable_reason::DisableReason::DISABLE_USER_ACTION |
- disable_reason::DisableReason::DISABLE_CORRUPTED);
+ disable_reason::DisableReason::DISABLE_CORRUPTED,
+ Manifest::EXTERNAL_POLICY_DOWNLOAD);
ExtensionUpdateDataMap update_data;
update_data[kExtensionId1] = {};
- std::vector<std::string> ids({kExtensionId1});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data = data_provider->GetData(update_data, {kExtensionId1});
ASSERT_EQ(1UL, data.size());
- EXPECT_EQ(version, data[0].version.GetString());
- EXPECT_NE(nullptr, data[0].installer.get());
- ASSERT_EQ(2UL, data[0].disabled_reasons.size());
+ EXPECT_EQ(version, data[0]->version.GetString());
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ ASSERT_EQ(2UL, data[0]->disabled_reasons.size());
EXPECT_EQ(disable_reason::DisableReason::DISABLE_USER_ACTION,
- data[0].disabled_reasons[0]);
+ data[0]->disabled_reasons[0]);
EXPECT_EQ(disable_reason::DisableReason::DISABLE_CORRUPTED,
- data[0].disabled_reasons[1]);
+ data[0]->disabled_reasons[1]);
+ EXPECT_EQ("policy", data[0]->install_location);
}
TEST_F(UpdateDataProviderTest,
@@ -268,25 +269,25 @@ TEST_F(UpdateDataProviderTest,
AddExtension(kExtensionId1, version, false,
disable_reason::DisableReason::DISABLE_USER_ACTION |
disable_reason::DisableReason::DISABLE_CORRUPTED |
- disable_reason::DisableReason::DISABLE_REASON_LAST);
+ disable_reason::DisableReason::DISABLE_REASON_LAST,
+ Manifest::EXTERNAL_PREF_DOWNLOAD);
ExtensionUpdateDataMap update_data;
update_data[kExtensionId1] = {};
- std::vector<std::string> ids({kExtensionId1});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data = data_provider->GetData(update_data, {kExtensionId1});
ASSERT_EQ(1UL, data.size());
- EXPECT_EQ(version, data[0].version.GetString());
- EXPECT_NE(nullptr, data[0].installer.get());
- ASSERT_EQ(3UL, data[0].disabled_reasons.size());
+ EXPECT_EQ(version, data[0]->version.GetString());
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ ASSERT_EQ(3UL, data[0]->disabled_reasons.size());
EXPECT_EQ(disable_reason::DisableReason::DISABLE_NONE,
- data[0].disabled_reasons[0]);
+ data[0]->disabled_reasons[0]);
EXPECT_EQ(disable_reason::DisableReason::DISABLE_USER_ACTION,
- data[0].disabled_reasons[1]);
+ data[0]->disabled_reasons[1]);
EXPECT_EQ(disable_reason::DisableReason::DISABLE_CORRUPTED,
- data[0].disabled_reasons[2]);
+ data[0]->disabled_reasons[2]);
+ EXPECT_EQ("external", data[0]->install_location);
}
TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions) {
@@ -297,25 +298,27 @@ TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions) {
const std::string version1 = "0.1.2.3";
const std::string version2 = "9.8.7.6";
AddExtension(kExtensionId1, version1, true,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE,
+ Manifest::EXTERNAL_REGISTRY);
AddExtension(kExtensionId2, version2, true,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE, Manifest::UNPACKED);
ExtensionUpdateDataMap update_data;
update_data[kExtensionId1] = {};
update_data[kExtensionId2] = {};
- std::vector<std::string> ids({kExtensionId1, kExtensionId2});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data =
+ data_provider->GetData(update_data, {kExtensionId1, kExtensionId2});
ASSERT_EQ(2UL, data.size());
- EXPECT_EQ(version1, data[0].version.GetString());
- EXPECT_NE(nullptr, data[0].installer.get());
- EXPECT_EQ(0UL, data[0].disabled_reasons.size());
- EXPECT_EQ(version2, data[1].version.GetString());
- EXPECT_NE(nullptr, data[1].installer.get());
- EXPECT_EQ(0UL, data[1].disabled_reasons.size());
+ EXPECT_EQ(version1, data[0]->version.GetString());
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ EXPECT_EQ(0UL, data[0]->disabled_reasons.size());
+ EXPECT_EQ("external", data[0]->install_location);
+ EXPECT_EQ(version2, data[1]->version.GetString());
+ EXPECT_NE(nullptr, data[1]->installer.get());
+ EXPECT_EQ(0UL, data[1]->disabled_reasons.size());
+ EXPECT_EQ("other", data[1]->install_location);
}
TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_DisabledExtension) {
@@ -326,28 +329,31 @@ TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_DisabledExtension) {
const std::string version1 = "0.1.2.3";
const std::string version2 = "9.8.7.6";
AddExtension(kExtensionId1, version1, false,
- disable_reason::DisableReason::DISABLE_CORRUPTED);
+ disable_reason::DisableReason::DISABLE_CORRUPTED,
+ Manifest::INTERNAL);
AddExtension(kExtensionId2, version2, true,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE,
+ Manifest::EXTERNAL_PREF_DOWNLOAD);
ExtensionUpdateDataMap update_data;
update_data[kExtensionId1] = {};
update_data[kExtensionId2] = {};
- std::vector<std::string> ids({kExtensionId1, kExtensionId2});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data =
+ data_provider->GetData(update_data, {kExtensionId1, kExtensionId2});
ASSERT_EQ(2UL, data.size());
- EXPECT_EQ(version1, data[0].version.GetString());
- EXPECT_NE(nullptr, data[0].installer.get());
- ASSERT_EQ(1UL, data[0].disabled_reasons.size());
+ EXPECT_EQ(version1, data[0]->version.GetString());
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ ASSERT_EQ(1UL, data[0]->disabled_reasons.size());
EXPECT_EQ(disable_reason::DisableReason::DISABLE_CORRUPTED,
- data[0].disabled_reasons[0]);
+ data[0]->disabled_reasons[0]);
+ EXPECT_EQ("internal", data[0]->install_location);
- EXPECT_EQ(version2, data[1].version.GetString());
- EXPECT_NE(nullptr, data[1].installer.get());
- EXPECT_EQ(0UL, data[1].disabled_reasons.size());
+ EXPECT_EQ(version2, data[1]->version.GetString());
+ EXPECT_NE(nullptr, data[1]->installer.get());
+ EXPECT_EQ(0UL, data[1]->disabled_reasons.size());
+ EXPECT_EQ("external", data[1]->install_location);
}
TEST_F(UpdateDataProviderTest,
@@ -358,20 +364,24 @@ TEST_F(UpdateDataProviderTest,
const std::string version = "0.1.2.3";
AddExtension(kExtensionId1, version, true,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE,
+ Manifest::COMPONENT);
ExtensionUpdateDataMap update_data;
update_data[kExtensionId1] = {};
update_data[kExtensionId2] = {};
- std::vector<std::string> ids({kExtensionId1, kExtensionId2});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data =
+ data_provider->GetData(update_data, {kExtensionId1, kExtensionId2});
- ASSERT_EQ(1UL, data.size());
- EXPECT_EQ(version, data[0].version.GetString());
- EXPECT_NE(nullptr, data[0].installer.get());
- EXPECT_EQ(0UL, data[0].disabled_reasons.size());
+ ASSERT_EQ(2UL, data.size());
+ ASSERT_NE(nullptr, data[0]);
+ EXPECT_EQ(version, data[0]->version.GetString());
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ EXPECT_EQ(0UL, data[0]->disabled_reasons.size());
+ EXPECT_EQ("other", data[0]->install_location);
+
+ EXPECT_EQ(nullptr, data[1]);
}
TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_CorruptExtension) {
@@ -384,9 +394,11 @@ TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_CorruptExtension) {
const std::string version2 = "9.8.7.6";
const std::string initial_version = "0.0.0.0";
AddExtension(kExtensionId1, version1, true,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE,
+ Manifest::EXTERNAL_COMPONENT);
AddExtension(kExtensionId2, version2, true,
- disable_reason::DisableReason::DISABLE_NONE);
+ disable_reason::DisableReason::DISABLE_NONE,
+ Manifest::EXTERNAL_POLICY);
ExtensionUpdateDataMap update_data;
auto& info1 = update_data[kExtensionId1];
@@ -396,19 +408,20 @@ TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_CorruptExtension) {
info2.is_corrupt_reinstall = true;
info2.install_source = "sideload";
- std::vector<std::string> ids({kExtensionId1, kExtensionId2});
- std::vector<update_client::CrxComponent> data;
- data_provider->GetData(update_data, ids, &data);
+ const auto data =
+ data_provider->GetData(update_data, {kExtensionId1, kExtensionId2});
ASSERT_EQ(2UL, data.size());
- EXPECT_EQ(version1, data[0].version.GetString());
- EXPECT_EQ("webstore", data[0].install_source);
- EXPECT_NE(nullptr, data[0].installer.get());
- EXPECT_EQ(0UL, data[0].disabled_reasons.size());
- EXPECT_EQ(initial_version, data[1].version.GetString());
- EXPECT_EQ("sideload", data[1].install_source);
- EXPECT_NE(nullptr, data[1].installer.get());
- EXPECT_EQ(0UL, data[1].disabled_reasons.size());
+ EXPECT_EQ(version1, data[0]->version.GetString());
+ EXPECT_EQ("webstore", data[0]->install_source);
+ EXPECT_EQ("other", data[0]->install_location);
+ EXPECT_NE(nullptr, data[0]->installer.get());
+ EXPECT_EQ(0UL, data[0]->disabled_reasons.size());
+ EXPECT_EQ(initial_version, data[1]->version.GetString());
+ EXPECT_EQ("sideload", data[1]->install_source);
+ EXPECT_EQ("policy", data[1]->install_location);
+ EXPECT_NE(nullptr, data[1]->installer.get());
+ EXPECT_EQ(0UL, data[1]->disabled_reasons.size());
}
} // namespace
diff --git a/chromium/extensions/browser/updater/update_service.cc b/chromium/extensions/browser/updater/update_service.cc
index fd513ac785a..7c495aab218 100644
--- a/chromium/extensions/browser/updater/update_service.cc
+++ b/chromium/extensions/browser/updater/update_service.cc
@@ -30,6 +30,10 @@ namespace extensions {
namespace {
+// 98% of update checks have 20 or less extensions
+// (see Extensions.UpdateCheckExtension histogram).
+constexpr size_t kMaxExtensionsPerUpdate = 20;
+
void SendUninstallPingCompleteCallback(update_client::Error error) {}
} // namespace
@@ -54,7 +58,7 @@ void UpdateService::Shutdown() {
update_data_provider_->Shutdown();
update_data_provider_ = nullptr;
}
- update_client_->RemoveObserver(this);
+ RemoveUpdateClientObserver(this);
update_client_ = nullptr;
browser_context_ = nullptr;
}
@@ -102,10 +106,40 @@ void UpdateService::OnEvent(Events event, const std::string& extension_id) {
break;
case Events::COMPONENT_UPDATE_ERROR:
complete_event = true;
- UMA_HISTOGRAM_ENUMERATION(
- "Extensions.ExtensionUpdaterUpdateResults",
- ExtensionUpdaterUpdateResult::UPDATE_ERROR,
- ExtensionUpdaterUpdateResult::UPDATE_RESULT_COUNT);
+ {
+ update_client::CrxUpdateItem update_item;
+ if (!update_client_->GetCrxUpdateState(extension_id, &update_item)) {
+ NOTREACHED();
+ }
+ switch (update_item.error_category) {
+ case update_client::ErrorCategory::kUpdateCheck:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Extensions.ExtensionUpdaterUpdateResults",
+ ExtensionUpdaterUpdateResult::UPDATE_CHECK_ERROR,
+ ExtensionUpdaterUpdateResult::UPDATE_RESULT_COUNT);
+ break;
+ case update_client::ErrorCategory::kDownload:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Extensions.ExtensionUpdaterUpdateResults",
+ ExtensionUpdaterUpdateResult::UPDATE_DOWNLOAD_ERROR,
+ ExtensionUpdaterUpdateResult::UPDATE_RESULT_COUNT);
+ break;
+ case update_client::ErrorCategory::kUnpack:
+ case update_client::ErrorCategory::kInstall:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Extensions.ExtensionUpdaterUpdateResults",
+ ExtensionUpdaterUpdateResult::UPDATE_INSTALL_ERROR,
+ ExtensionUpdaterUpdateResult::UPDATE_RESULT_COUNT);
+ break;
+ case update_client::ErrorCategory::kNone:
+ case update_client::ErrorCategory::kService:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Extensions.ExtensionUpdaterUpdateResults",
+ ExtensionUpdaterUpdateResult::UPDATE_SERVICE_ERROR,
+ ExtensionUpdaterUpdateResult::UPDATE_RESULT_COUNT);
+ break;
+ }
+ }
break;
case Events::COMPONENT_NOT_UPDATED:
complete_event = true;
@@ -123,15 +157,18 @@ void UpdateService::OnEvent(Events event, const std::string& extension_id) {
case Events::COMPONENT_UPDATE_FOUND: {
UMA_HISTOGRAM_COUNTS_100("Extensions.ExtensionUpdaterUpdateFoundCount",
1);
- update_client::CrxUpdateItem update_item;
- if (update_client_->GetCrxUpdateState(extension_id, &update_item)) {
- VLOG(3) << "UpdateService::OnEvent COMPONENT_UPDATE_FOUND: "
- << extension_id << " " << update_item.next_version.GetString();
- UpdateDetails update_info(extension_id, update_item.next_version);
- content::NotificationService::current()->Notify(
- extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
- content::NotificationService::AllBrowserContextsAndSources(),
- content::Details<UpdateDetails>(&update_info));
+ {
+ update_client::CrxUpdateItem update_item;
+ if (update_client_->GetCrxUpdateState(extension_id, &update_item)) {
+ VLOG(3) << "UpdateService::OnEvent COMPONENT_UPDATE_FOUND: "
+ << extension_id << " "
+ << update_item.next_version.GetString();
+ UpdateDetails update_info(extension_id, update_item.next_version);
+ content::NotificationService::current()->Notify(
+ extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
+ content::NotificationService::AllBrowserContextsAndSources(),
+ content::Details<UpdateDetails>(&update_info));
+ }
}
break;
}
@@ -162,7 +199,7 @@ UpdateService::UpdateService(
DCHECK(update_client_);
update_data_provider_ =
base::MakeRefCounted<UpdateDataProvider>(browser_context_);
- update_client->AddObserver(this);
+ AddUpdateClientObserver(this);
}
UpdateService::~UpdateService() {
@@ -189,10 +226,9 @@ void UpdateService::StartUpdateCheck(
in_progress_updates_.push_back(InProgressUpdate(std::move(callback)));
InProgressUpdate& update = in_progress_updates_.back();
+ // |update_data| only store update info of extensions that are not being
+ // updated at the moment.
ExtensionUpdateDataMap update_data;
- // |extension_ids_to_update| stores the extension IDs from the new update
- // check request that are not being updated at the moment.
- std::vector<std::string> extension_ids_to_update;
for (const auto& update_info : update_params.update_info) {
const std::string& extension_id = update_info.first;
@@ -201,7 +237,6 @@ void UpdateService::StartUpdateCheck(
continue;
updating_extension_ids_.insert(extension_id);
- extension_ids_to_update.push_back(extension_id);
ExtensionUpdateData data = update_info.second;
if (data.is_corrupt_reinstall) {
@@ -215,20 +250,31 @@ void UpdateService::StartUpdateCheck(
}
UMA_HISTOGRAM_COUNTS_100("Extensions.ExtensionUpdaterUpdateCalls",
- extension_ids_to_update.size());
-
- // If all extension IDs are being updated by previous update check requests,
- // there's no need to update these extensions again.
- if (extension_ids_to_update.empty())
- return;
+ update_data.size());
+
+ // Divide extensions into batches to reduce the size of update check
+ // requests generated by the update client.
+ for (auto it = update_data.begin(); it != update_data.end();) {
+ ExtensionUpdateDataMap batch_data;
+ size_t batch_size =
+ std::min(kMaxExtensionsPerUpdate,
+ static_cast<size_t>(std::distance(it, update_data.end())));
+
+ std::vector<std::string> batch_ids;
+ batch_ids.reserve(batch_size);
+ for (size_t i = 0; i < batch_size; ++i, ++it) {
+ batch_ids.push_back(it->first);
+ batch_data.emplace(it->first, std::move(it->second));
+ }
- update_client_->Update(
- extension_ids_to_update,
- base::BindOnce(&UpdateDataProvider::GetData, update_data_provider_,
- std::move(update_data)),
- update_params.priority == ExtensionUpdateCheckParams::FOREGROUND,
- base::BindOnce(&UpdateService::UpdateCheckComplete,
- weak_ptr_factory_.GetWeakPtr()));
+ update_client_->Update(
+ batch_ids,
+ base::BindOnce(&UpdateDataProvider::GetData, update_data_provider_,
+ std::move(batch_data)),
+ update_params.priority == ExtensionUpdateCheckParams::FOREGROUND,
+ base::BindOnce(&UpdateService::UpdateCheckComplete,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
}
void UpdateService::UpdateCheckComplete(update_client::Error error) {
@@ -238,8 +284,11 @@ void UpdateService::UpdateCheckComplete(update_client::Error error) {
// There must be at least one in-progress update (the one that just
// finished).
DCHECK(!in_progress_updates_.empty());
- // And that the first update should have all of its pendings finished.
- DCHECK(in_progress_updates_[0].pending_extension_ids.empty());
+
+ if (!in_progress_updates_[0].pending_extension_ids.empty()) {
+ // This can happen when the update check request is batched.
+ return;
+ }
// Find all updates that have finished and remove them from the list.
in_progress_updates_.erase(
@@ -255,4 +304,16 @@ void UpdateService::UpdateCheckComplete(update_client::Error error) {
in_progress_updates_.end());
}
+void UpdateService::AddUpdateClientObserver(
+ update_client::UpdateClient::Observer* observer) {
+ if (update_client_)
+ update_client_->AddObserver(observer);
+}
+
+void UpdateService::RemoveUpdateClientObserver(
+ update_client::UpdateClient::Observer* observer) {
+ if (update_client_)
+ update_client_->RemoveObserver(observer);
+}
+
} // namespace extensions
diff --git a/chromium/extensions/browser/updater/update_service.h b/chromium/extensions/browser/updater/update_service.h
index 957d54470ec..08a32e8859f 100644
--- a/chromium/extensions/browser/updater/update_service.h
+++ b/chromium/extensions/browser/updater/update_service.h
@@ -33,9 +33,10 @@ class UpdateClient;
namespace extensions {
+class ExtensionUpdateClientBaseTest;
+struct ExtensionUpdateCheckParams;
class UpdateDataProvider;
class UpdateServiceFactory;
-struct ExtensionUpdateCheckParams;
// This service manages the autoupdate of extensions. It should eventually
// replace ExtensionUpdater in Chrome.
@@ -62,10 +63,11 @@ class UpdateService : public KeyedService,
// |extension_id|.
bool CanUpdate(const std::string& extension_id) const;
- // Overriden from update_client::UpdateClient::Observer.
+ // Overriden from |update_client::UpdateClient::Observer|.
void OnEvent(Events event, const std::string& id) override;
private:
+ friend class ExtensionUpdateClientBaseTest;
friend class UpdateServiceFactory;
friend std::unique_ptr<UpdateService>::deleter_type;
@@ -91,6 +93,13 @@ class UpdateService : public KeyedService,
std::set<std::string> pending_extension_ids;
};
+ // Adds/Removes observer to/from |update_client::UpdateClient|.
+ // Mainly used for browser tests.
+ void AddUpdateClientObserver(update_client::UpdateClient::Observer* observer);
+ void RemoveUpdateClientObserver(
+ update_client::UpdateClient::Observer* observer);
+
+ private:
content::BrowserContext* browser_context_;
scoped_refptr<update_client::UpdateClient> update_client_;
diff --git a/chromium/extensions/browser/updater/update_service_unittest.cc b/chromium/extensions/browser/updater/update_service_unittest.cc
index ad80d16c0f9..ecfae44fba7 100644
--- a/chromium/extensions/browser/updater/update_service_unittest.cc
+++ b/chromium/extensions/browser/updater/update_service_unittest.cc
@@ -48,7 +48,9 @@ class FakeUpdateClient : public update_client::UpdateClient {
// Returns the data we've gotten from the CrxDataCallback for ids passed to
// the Update function.
- std::vector<update_client::CrxComponent>* data() { return &data_; }
+ std::vector<std::unique_ptr<update_client::CrxComponent>>* data() {
+ return &data_;
+ }
// Used for tests that uninstall pings get requested properly.
struct UninstallPing {
@@ -120,7 +122,7 @@ class FakeUpdateClient : public update_client::UpdateClient {
friend class base::RefCounted<FakeUpdateClient>;
~FakeUpdateClient() override {}
- std::vector<update_client::CrxComponent> data_;
+ std::vector<std::unique_ptr<update_client::CrxComponent>> data_;
std::vector<UninstallPing> uninstall_pings_;
std::vector<Observer*> observers_;
@@ -137,7 +139,7 @@ void FakeUpdateClient::Update(const std::vector<std::string>& ids,
CrxDataCallback crx_data_callback,
bool is_foreground,
update_client::Callback callback) {
- std::move(crx_data_callback).Run(ids, &data_);
+ data_ = std::move(crx_data_callback).Run(ids);
if (delay_update()) {
delayed_requests_.push_back({ids, std::move(callback)});
@@ -235,7 +237,7 @@ class FakeExtensionSystem : public MockExtensionSystem {
if (!next_install_callback_.is_null()) {
std::move(next_install_callback_).Run();
}
- std::move(install_update_callback).Run(true);
+ std::move(install_update_callback).Run(base::nullopt);
}
private:
@@ -329,12 +331,12 @@ TEST_F(UpdateServiceTest, BasicUpdateOperations) {
update_check_params,
base::BindOnce([](bool* executed) { *executed = true; }, &executed));
ASSERT_TRUE(executed);
- std::vector<update_client::CrxComponent>* data = update_client()->data();
+ const auto* data = update_client()->data();
ASSERT_NE(nullptr, data);
ASSERT_EQ(1u, data->size());
- ASSERT_EQ(data->at(0).version, extension1->version());
- update_client::CrxInstaller* installer = data->at(0).installer.get();
+ ASSERT_EQ(data->at(0)->version, extension1->version());
+ update_client::CrxInstaller* installer = data->at(0)->installer.get();
ASSERT_NE(installer, nullptr);
// The GetInstalledFile method is used when processing differential updates
@@ -393,17 +395,11 @@ TEST_F(UpdateServiceTest, UninstallPings) {
// Build 3 extensions.
scoped_refptr<Extension> extension1 =
- ExtensionBuilder("1")
- .MergeManifest(DictionaryBuilder().Set("version", "1.2").Build())
- .Build();
+ ExtensionBuilder("1").SetManifestKey("version", "1.2").Build();
scoped_refptr<Extension> extension2 =
- ExtensionBuilder("2")
- .MergeManifest(DictionaryBuilder().Set("version", "2.3").Build())
- .Build();
+ ExtensionBuilder("2").SetManifestKey("version", "2.3").Build();
scoped_refptr<Extension> extension3 =
- ExtensionBuilder("3")
- .MergeManifest(DictionaryBuilder().Set("version", "3.4").Build())
- .Build();
+ ExtensionBuilder("3").SetManifestKey("version", "3.4").Build();
EXPECT_TRUE(extension1->id() != extension2->id() &&
extension1->id() != extension3->id() &&
extension2->id() != extension3->id());
@@ -480,7 +476,7 @@ TEST_F(UpdateServiceTest, InProgressUpdate_Successful) {
base::BindOnce([](bool* executed) { *executed = true; }, &executed));
EXPECT_FALSE(executed);
- auto& request = update_client()->update_request(0);
+ const auto& request = update_client()->update_request(0);
EXPECT_THAT(request.extension_ids,
testing::ElementsAre("A", "B", "C", "D", "E"));
@@ -517,7 +513,7 @@ TEST_F(UpdateServiceTest, InProgressUpdate_Duplicate) {
ASSERT_EQ(1, update_client()->num_update_requests());
- auto& request = update_client()->update_request(0);
+ const auto& request = update_client()->update_request(0);
EXPECT_THAT(request.extension_ids,
testing::ElementsAre("A", "B", "C", "D", "E"));
@@ -551,8 +547,8 @@ TEST_F(UpdateServiceTest, InProgressUpdate_NonOverlapped) {
EXPECT_FALSE(executed2);
ASSERT_EQ(2, update_client()->num_update_requests());
- auto& request1 = update_client()->update_request(0);
- auto& request2 = update_client()->update_request(1);
+ const auto& request1 = update_client()->update_request(0);
+ const auto& request2 = update_client()->update_request(1);
EXPECT_THAT(request1.extension_ids, testing::ElementsAre("A", "B", "C"));
EXPECT_THAT(request2.extension_ids, testing::ElementsAre("D", "E"));
@@ -588,8 +584,8 @@ TEST_F(UpdateServiceTest, InProgressUpdate_Overlapped) {
base::BindOnce([](bool* executed) { *executed = true; }, &executed2));
EXPECT_FALSE(executed2);
- auto& request1 = update_client()->update_request(0);
- auto& request2 = update_client()->update_request(1);
+ const auto& request1 = update_client()->update_request(0);
+ const auto& request2 = update_client()->update_request(1);
EXPECT_THAT(request1.extension_ids, testing::ElementsAre("A", "B", "C"));
EXPECT_THAT(request2.extension_ids, testing::ElementsAre("D"));
@@ -641,8 +637,8 @@ TEST_F(UpdateServiceTest, InProgressUpdate_3Overlapped) {
EXPECT_FALSE(executed3);
ASSERT_EQ(2, update_client()->num_update_requests());
- auto& request1 = update_client()->update_request(0);
- auto& request2 = update_client()->update_request(1);
+ const auto& request1 = update_client()->update_request(0);
+ const auto& request2 = update_client()->update_request(1);
EXPECT_THAT(request1.extension_ids, testing::ElementsAre("A", "B", "C"));
EXPECT_THAT(request2.extension_ids, testing::ElementsAre("D", "E"));
@@ -707,9 +703,9 @@ TEST_F(UpdateServiceTest, InProgressUpdate_4Overlapped) {
EXPECT_FALSE(executed4);
ASSERT_EQ(3, update_client()->num_update_requests());
- auto& request1 = update_client()->update_request(0);
- auto& request2 = update_client()->update_request(1);
- auto& request3 = update_client()->update_request(2);
+ const auto& request1 = update_client()->update_request(0);
+ const auto& request2 = update_client()->update_request(1);
+ const auto& request3 = update_client()->update_request(2);
EXPECT_THAT(request1.extension_ids, testing::ElementsAre("A", "B", "C"));
EXPECT_THAT(request2.extension_ids, testing::ElementsAre("D", "E"));
@@ -730,6 +726,113 @@ TEST_F(UpdateServiceTest, InProgressUpdate_4Overlapped) {
ASSERT_TRUE(executed4);
}
+TEST_F(UpdateServiceTest, InProgressUpdate_Batch) {
+ // Verify that extensions are batched when the number of extensions exceeds
+ // 20.
+ update_client()->set_delay_update();
+ ExtensionUpdateCheckParams uc;
+
+ for (int i = 0; i < 50; ++i)
+ uc.update_info[base::StringPrintf("A%02d", i)] = ExtensionUpdateData();
+
+ bool executed = false;
+ update_service()->StartUpdateCheck(
+ uc, base::BindOnce([](bool* executed) { *executed = true; }, &executed));
+ EXPECT_FALSE(executed);
+
+ ASSERT_EQ(3, update_client()->num_update_requests());
+
+ const auto& request1 = update_client()->update_request(0);
+ const auto& request2 = update_client()->update_request(1);
+ const auto& request3 = update_client()->update_request(2);
+
+ EXPECT_THAT(
+ request1.extension_ids,
+ testing::ElementsAre("A00", "A01", "A02", "A03", "A04", "A05", "A06",
+ "A07", "A08", "A09", "A10", "A11", "A12", "A13",
+ "A14", "A15", "A16", "A17", "A18", "A19"));
+ EXPECT_THAT(
+ request2.extension_ids,
+ testing::ElementsAre("A20", "A21", "A22", "A23", "A24", "A25", "A26",
+ "A27", "A28", "A29", "A30", "A31", "A32", "A33",
+ "A34", "A35", "A36", "A37", "A38", "A39"));
+ EXPECT_THAT(request3.extension_ids,
+ testing::ElementsAre("A40", "A41", "A42", "A43", "A44", "A45",
+ "A46", "A47", "A48", "A49"));
+
+ update_client()->RunDelayedUpdate(0);
+ EXPECT_FALSE(executed);
+
+ update_client()->RunDelayedUpdate(1);
+ EXPECT_FALSE(executed);
+
+ update_client()->RunDelayedUpdate(2);
+ EXPECT_TRUE(executed);
+}
+
+TEST_F(UpdateServiceTest, InProgressUpdate_NoBatchAndBatch) {
+ update_client()->set_delay_update();
+ ExtensionUpdateCheckParams uc1;
+ ExtensionUpdateCheckParams uc2;
+
+ uc1.update_info["AA"] = ExtensionUpdateData();
+ uc1.update_info["BB"] = ExtensionUpdateData();
+ uc1.update_info["CC"] = ExtensionUpdateData();
+ uc1.update_info["DD"] = ExtensionUpdateData();
+
+ for (int i = 0; i < 50; ++i)
+ uc2.update_info[base::StringPrintf("A%02d", i)] = ExtensionUpdateData();
+
+ bool executed1 = false;
+ update_service()->StartUpdateCheck(
+ uc1,
+ base::BindOnce([](bool* executed) { *executed = true; }, &executed1));
+ EXPECT_FALSE(executed1);
+
+ bool executed2 = false;
+ update_service()->StartUpdateCheck(
+ uc2,
+ base::BindOnce([](bool* executed) { *executed = true; }, &executed2));
+ EXPECT_FALSE(executed2);
+
+ ASSERT_EQ(4, update_client()->num_update_requests());
+
+ const auto& request1 = update_client()->update_request(0);
+ const auto& request2 = update_client()->update_request(1);
+ const auto& request3 = update_client()->update_request(2);
+ const auto& request4 = update_client()->update_request(3);
+
+ EXPECT_THAT(request1.extension_ids,
+ testing::ElementsAre("AA", "BB", "CC", "DD"));
+
+ EXPECT_THAT(
+ request2.extension_ids,
+ testing::ElementsAre("A00", "A01", "A02", "A03", "A04", "A05", "A06",
+ "A07", "A08", "A09", "A10", "A11", "A12", "A13",
+ "A14", "A15", "A16", "A17", "A18", "A19"));
+ EXPECT_THAT(
+ request3.extension_ids,
+ testing::ElementsAre("A20", "A21", "A22", "A23", "A24", "A25", "A26",
+ "A27", "A28", "A29", "A30", "A31", "A32", "A33",
+ "A34", "A35", "A36", "A37", "A38", "A39"));
+ EXPECT_THAT(request4.extension_ids,
+ testing::ElementsAre("A40", "A41", "A42", "A43", "A44", "A45",
+ "A46", "A47", "A48", "A49"));
+
+ update_client()->RunDelayedUpdate(0);
+ EXPECT_TRUE(executed1);
+ EXPECT_FALSE(executed2);
+
+ update_client()->RunDelayedUpdate(1);
+ EXPECT_FALSE(executed2);
+
+ update_client()->RunDelayedUpdate(2);
+ EXPECT_FALSE(executed2);
+
+ update_client()->RunDelayedUpdate(3);
+ EXPECT_TRUE(executed2);
+}
+
class UpdateServiceCanUpdateTest : public UpdateServiceTest,
public ::testing::WithParamInterface<bool> {
public:
diff --git a/chromium/extensions/browser/user_script_loader.cc b/chromium/extensions/browser/user_script_loader.cc
index 143b3ddeae1..0c584cd87a6 100644
--- a/chromium/extensions/browser/user_script_loader.cc
+++ b/chromium/extensions/browser/user_script_loader.cc
@@ -417,7 +417,7 @@ void UserScriptLoader::SendUpdate(content::RenderProcessHost* process,
// If the process is being started asynchronously, early return. We'll end up
// calling InitUserScripts when it's created which will call this again.
- base::ProcessHandle handle = process->GetHandle();
+ base::ProcessHandle handle = process->GetProcess().Handle();
if (!handle)
return;
diff --git a/chromium/extensions/browser/value_store/leveldb_value_store_unittest.cc b/chromium/extensions/browser/value_store/leveldb_value_store_unittest.cc
index 53223c38fba..71f3f3da9c2 100644
--- a/chromium/extensions/browser/value_store/leveldb_value_store_unittest.cc
+++ b/chromium/extensions/browser/value_store/leveldb_value_store_unittest.cc
@@ -10,7 +10,6 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
#include "base/values.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/value_store/leveldb_value_store.h"
diff --git a/chromium/extensions/browser/value_store/value_store_frontend_unittest.cc b/chromium/extensions/browser/value_store/value_store_frontend_unittest.cc
index 612889ddc48..71764252219 100644
--- a/chromium/extensions/browser/value_store/value_store_frontend_unittest.cc
+++ b/chromium/extensions/browser/value_store/value_store_frontend_unittest.cc
@@ -24,7 +24,8 @@ class ValueStoreFrontendTest : public testing::Test {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath test_data_dir;
- ASSERT_TRUE(PathService::Get(extensions::DIR_TEST_DATA, &test_data_dir));
+ ASSERT_TRUE(
+ base::PathService::Get(extensions::DIR_TEST_DATA, &test_data_dir));
base::FilePath src_db(test_data_dir.AppendASCII("value_store_db"));
db_path_ = temp_dir_.GetPath().AppendASCII("temp_db");
base::CopyDirectory(src_db, db_path_, true);
diff --git a/chromium/extensions/browser/verified_contents.cc b/chromium/extensions/browser/verified_contents.cc
index bfe81ea90bd..ea6e9a49276 100644
--- a/chromium/extensions/browser/verified_contents.cc
+++ b/chromium/extensions/browser/verified_contents.cc
@@ -62,10 +62,8 @@ const DictionaryValue* FindDictionaryWithValue(const ListValue* list,
namespace extensions {
-VerifiedContents::VerifiedContents(const uint8_t* public_key,
- size_t public_key_size)
+VerifiedContents::VerifiedContents(base::span<const uint8_t> public_key)
: public_key_(public_key),
- public_key_size_(public_key_size),
valid_signature_(false), // Guilty until proven innocent.
block_size_(0) {}
@@ -301,22 +299,18 @@ bool VerifiedContents::VerifySignature(const std::string& protected_value,
crypto::SignatureVerifier signature_verifier;
if (!signature_verifier.VerifyInit(
crypto::SignatureVerifier::RSA_PKCS1_SHA256,
- reinterpret_cast<const uint8_t*>(signature_bytes.data()),
- signature_bytes.size(), public_key_, public_key_size_)) {
+ base::as_bytes(base::make_span(signature_bytes)), public_key_)) {
VLOG(1) << "Could not verify signature - VerifyInit failure";
return false;
}
signature_verifier.VerifyUpdate(
- reinterpret_cast<const uint8_t*>(protected_value.data()),
- protected_value.size());
+ base::as_bytes(base::make_span(protected_value)));
std::string dot(".");
- signature_verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(dot.data()),
- dot.size());
+ signature_verifier.VerifyUpdate(base::as_bytes(base::make_span(dot)));
- signature_verifier.VerifyUpdate(
- reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
+ signature_verifier.VerifyUpdate(base::as_bytes(base::make_span(payload)));
if (!signature_verifier.VerifyFinal()) {
VLOG(1) << "Could not verify signature - VerifyFinal failure";
diff --git a/chromium/extensions/browser/verified_contents.h b/chromium/extensions/browser/verified_contents.h
index 6a4497221b8..4dd9ddb096e 100644
--- a/chromium/extensions/browser/verified_contents.h
+++ b/chromium/extensions/browser/verified_contents.h
@@ -11,6 +11,7 @@
#include <string>
#include <vector>
+#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/version.h"
@@ -24,7 +25,7 @@ namespace extensions {
class VerifiedContents {
public:
// Note: the public_key must remain valid for the lifetime of this object.
- VerifiedContents(const uint8_t* public_key, size_t public_key_size);
+ explicit VerifiedContents(base::span<const uint8_t> public_key);
~VerifiedContents();
// Returns true if we successfully parsed the verified_contents.json file at
@@ -58,8 +59,7 @@ class VerifiedContents {
const std::string& signature_bytes);
// The public key we should use for signature verification.
- const uint8_t* public_key_;
- const size_t public_key_size_;
+ base::span<const uint8_t> public_key_;
// Indicates whether the signature was successfully validated or not.
bool valid_signature_;
diff --git a/chromium/extensions/browser/verified_contents_unittest.cc b/chromium/extensions/browser/verified_contents_unittest.cc
index ab8dfbbbe89..2995f1cefc6 100644
--- a/chromium/extensions/browser/verified_contents_unittest.cc
+++ b/chromium/extensions/browser/verified_contents_unittest.cc
@@ -47,14 +47,13 @@ bool GetPublicKey(const base::FilePath& path, std::string* public_key) {
TEST(VerifiedContents, Simple) {
// Figure out our test data directory.
base::FilePath path;
- PathService::Get(DIR_TEST_DATA, &path);
+ base::PathService::Get(DIR_TEST_DATA, &path);
path = path.AppendASCII(kContentVerifierDirectory);
// Initialize the VerifiedContents object.
std::string public_key;
ASSERT_TRUE(GetPublicKey(path.AppendASCII(kPublicKeyPem), &public_key));
- VerifiedContents contents(reinterpret_cast<const uint8_t*>(public_key.data()),
- public_key.size());
+ VerifiedContents contents(base::as_bytes(base::make_span(public_key)));
base::FilePath verified_contents_path =
path.AppendASCII("verified_contents.json");
@@ -141,14 +140,13 @@ TEST(VerifiedContents, FailsOnBase64) {
// will be considered to be invalid data. Verify that it gets rejected.
base::FilePath path;
- PathService::Get(DIR_TEST_DATA, &path);
+ base::PathService::Get(DIR_TEST_DATA, &path);
path = path.AppendASCII(kContentVerifierDirectory);
// Initialize the VerifiedContents object.
std::string public_key;
ASSERT_TRUE(GetPublicKey(path.AppendASCII(kPublicKeyPem), &public_key));
- VerifiedContents contents(reinterpret_cast<const uint8_t*>(public_key.data()),
- public_key.size());
+ VerifiedContents contents(base::as_bytes(base::make_span(public_key)));
base::FilePath verified_contents_path =
path.AppendASCII("verified_contents_base64.json");