diff --git a/DEPS b/DEPS index a9060d8..fd67a9a 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '7fa5c31c2c9af834bee66d5fcf476e250076c8d6', + 'skia_revision': 'df07ddd1f05bf8905b9edd41d309badc8f3a131b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '207d5c39e9c289fc91d8344f32f6b0820001f557', + 'v8_revision': '888f7dad7620bffd7929f257272a424a652ee5eb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other.
diff --git a/base/BUILD.gn b/base/BUILD.gn index 78953be..7714190 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -741,6 +741,7 @@ "strings/string_number_conversions.h", "strings/string_piece.cc", "strings/string_piece.h", + "strings/string_piece_forward.h", "strings/string_split.cc", "strings/string_split.h", "strings/string_tokenizer.h",
diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc index 36736cd..41adbf8 100644 --- a/base/allocator/allocator_shim.cc +++ b/base/allocator/allocator_shim.cc
@@ -58,9 +58,12 @@ #if defined(OS_WIN) return base::allocator::WinCallNewHandler(size); #else - // TODO(primiano): C++11 has introduced ::get_new_handler() which is supposed - // to be thread safe and would avoid the spinlock boilerplate here. However - // it doesn't seem to be available yet in the Linux chroot headers yet. + // TODO(primiano): C++11 has introduced std::get_new_handler() which is + // supposed to be thread safe and would avoid the spinlock boilerplate here. + // However, it is not available in the headers in the current Debian Jessie + // sysroot, which has libstdc++ 4.8. The function is available in libstdc++ + // 4.9 and newer, but it will be a few more years before a newer sysroot + // becomes available. std::new_handler nh; { while (subtle::Acquire_CompareAndSwap(&g_new_handler_lock, 0, 1))
diff --git a/base/logging.cc b/base/logging.cc index cea6edae..cce9c72 100644 --- a/base/logging.cc +++ b/base/logging.cc
@@ -7,12 +7,12 @@ #include <limits.h> #include <stdint.h> -#include "base/debug/activity_tracker.h" #include "base/macros.h" #include "build/build_config.h" #if defined(OS_WIN) #include <io.h> +#include <windows.h> typedef HANDLE FileHandle; typedef HANDLE MutexHandle; // Windows warns on using write(). It prefers _write(). @@ -51,13 +51,18 @@ #include <ctime> #include <iomanip> #include <ostream> +#include <stack> #include <string> +#include <utility> #include "base/base_switches.h" +#include "base/callback.h" #include "base/command_line.h" +#include "base/debug/activity_tracker.h" #include "base/debug/alias.h" #include "base/debug/debugger.h" #include "base/debug/stack_trace.h" +#include "base/lazy_instance.h" #include "base/posix/eintr_wrapper.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -121,8 +126,11 @@ bool show_error_dialogs = false; // An assert handler override specified by the client to be called instead of -// the debug message dialog and process termination. -LogAssertHandlerFunction log_assert_handler = nullptr; +// the debug message dialog and process termination. Assert handlers are stored +// in stack to allow overriding and restoring. +base::LazyInstance<std::stack<LogAssertHandlerFunction>>::Leaky + log_assert_handler_stack = LAZY_INSTANCE_INITIALIZER; + // A log message handler that gets notified of every log message we process. LogMessageHandlerFunction log_message_handler = nullptr; @@ -444,8 +452,13 @@ show_error_dialogs = enable_dialogs; } -void SetLogAssertHandler(LogAssertHandlerFunction handler) { - log_assert_handler = handler; +ScopedLogAssertHandler::ScopedLogAssertHandler( + LogAssertHandlerFunction handler) { + log_assert_handler_stack.Get().push(std::move(handler)); +} + +ScopedLogAssertHandler::~ScopedLogAssertHandler() { + log_assert_handler_stack.Get().pop(); } void SetLogMessageHandler(LogMessageHandlerFunction handler) { @@ -531,6 +544,7 @@ } LogMessage::~LogMessage() { + size_t stack_start = stream_.tellp(); #if !defined(OFFICIAL_BUILD) && !defined(OS_NACL) && !defined(__UCLIBC__) if (severity_ == LOG_FATAL && !base::debug::BeingDebugged()) { // Include a stack trace on a fatal, unless a debugger is attached. @@ -739,9 +753,18 @@ str_newline.copy(str_stack, arraysize(str_stack)); base::debug::Alias(str_stack); - if (log_assert_handler) { - // Make a copy of the string for the handler out of paranoia. - log_assert_handler(std::string(stream_.str())); + if (!(log_assert_handler_stack == nullptr) && + !log_assert_handler_stack.Get().empty()) { + LogAssertHandlerFunction log_assert_handler = + log_assert_handler_stack.Get().top(); + + if (log_assert_handler) { + log_assert_handler.Run( + file_, line_, + base::StringPiece(str_newline.c_str() + message_start_, + stack_start - message_start_), + base::StringPiece(str_newline.c_str() + stack_start)); + } } else { // Don't use the string with the newline, get a fresh version to send to // the debug message process. We also don't display assertions to the
diff --git a/base/logging.h b/base/logging.h index 1dcb0f71..bf41527 100644 --- a/base/logging.h +++ b/base/logging.h
@@ -15,9 +15,11 @@ #include <utility> #include "base/base_export.h" +#include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/debug/debugger.h" #include "base/macros.h" +#include "base/strings/string_piece_forward.h" #include "base/template_util.h" #include "build/build_config.h" @@ -274,11 +276,24 @@ BASE_EXPORT void SetShowErrorDialogs(bool enable_dialogs); // Sets the Log Assert Handler that will be used to notify of check failures. +// Resets Log Assert Handler on object destruction. // The default handler shows a dialog box and then terminate the process, // however clients can use this function to override with their own handling // (e.g. a silent one for Unit Tests) -typedef void (*LogAssertHandlerFunction)(const std::string& str); -BASE_EXPORT void SetLogAssertHandler(LogAssertHandlerFunction handler); +using LogAssertHandlerFunction = + base::Callback<void(const char* file, + int line, + const base::StringPiece message, + const base::StringPiece stack_trace)>; + +class BASE_EXPORT ScopedLogAssertHandler { + public: + explicit ScopedLogAssertHandler(LogAssertHandlerFunction handler); + ~ScopedLogAssertHandler(); + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedLogAssertHandler); +}; // Sets the Log Message Handler that gets passed every log message before // it's sent to other log destinations (if any).
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc index 62323972..6ae965f7 100644 --- a/base/logging_unittest.cc +++ b/base/logging_unittest.cc
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/compiler_specific.h" #include "base/logging.h" +#include "base/bind.h" +#include "base/callback.h" +#include "base/compiler_specific.h" #include "base/macros.h" +#include "base/strings/string_piece.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -29,12 +32,16 @@ namespace { using ::testing::Return; +using ::testing::_; // Needs to be global since log assert handlers can't maintain state. int log_sink_call_count = 0; #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG) -void LogSink(const std::string& str) { +void LogSink(const char* file, + int line, + const base::StringPiece message, + const base::StringPiece stack_trace) { ++log_sink_call_count; } #endif @@ -47,7 +54,6 @@ ~LogStateSaver() { SetMinLogLevel(old_min_log_level_); - SetLogAssertHandler(NULL); log_sink_call_count = 0; } @@ -67,6 +73,13 @@ MOCK_METHOD0(Log, const char*()); }; +class MockLogAssertHandler { + public: + MOCK_METHOD4( + HandleLogAssert, + void(const char*, int, const base::StringPiece, const base::StringPiece)); +}; + TEST_F(LoggingTest, BasicLogging) { MockLogSource mock_log_source; EXPECT_CALL(mock_log_source, Log()) @@ -197,7 +210,7 @@ WillRepeatedly(Return("check message")); EXPECT_CALL(uncalled_mock_log_source, Log()).Times(0); - SetLogAssertHandler(&LogSink); + ScopedLogAssertHandler scoped_assert_handler(base::Bind(LogSink)); CHECK(mock_log_source.Log()) << uncalled_mock_log_source.Log(); PCHECK(!mock_log_source.Log()) << mock_log_source.Log(); @@ -405,12 +418,12 @@ EXPECT_FALSE(DLOG_IS_ON(DCHECK)); #elif defined(NDEBUG) && defined(DCHECK_ALWAYS_ON) // Release build with real DCHECKS. - SetLogAssertHandler(&LogSink); + ScopedLogAssertHandler scoped_assert_handler(base::Bind(LogSink)); EXPECT_TRUE(DCHECK_IS_ON()); EXPECT_TRUE(DLOG_IS_ON(DCHECK)); #else // Debug build. - SetLogAssertHandler(&LogSink); + ScopedLogAssertHandler scoped_assert_handler(base::Bind(LogSink)); EXPECT_TRUE(DCHECK_IS_ON()); EXPECT_TRUE(DLOG_IS_ON(DCHECK)); #endif @@ -499,6 +512,44 @@ CHECK_EQ(false, true); // Unreached. } +TEST_F(LoggingTest, NestedLogAssertHandlers) { + ::testing::InSequence dummy; + ::testing::StrictMock<MockLogAssertHandler> handler_a, handler_b; + + EXPECT_CALL( + handler_a, + HandleLogAssert( + _, _, + base::StringPiece( + "Check failed: false. First assert must be catched by handler_a"), + _)); + EXPECT_CALL( + handler_b, + HandleLogAssert(_, _, + base::StringPiece("Check failed: false. Second assert " + "must be catched by handler_b"), + _)); + EXPECT_CALL( + handler_a, + HandleLogAssert(_, _, + base::StringPiece("Check failed: false. Last assert " + "must be catched by handler_a again"), + _)); + + logging::ScopedLogAssertHandler scoped_handler_a(base::Bind( + &MockLogAssertHandler::HandleLogAssert, base::Unretained(&handler_a))); + + CHECK(false) << "First assert must be catched by handler_a"; + + { + logging::ScopedLogAssertHandler scoped_handler_b(base::Bind( + &MockLogAssertHandler::HandleLogAssert, base::Unretained(&handler_b))); + CHECK(false) << "Second assert must be catched by handler_b"; + } + + CHECK(false) << "Last assert must be catched by handler_a again"; +} + // Test that defining an operator<< for a type in a namespace doesn't prevent // other code in that namespace from calling the operator<<(ostream, wstring) // defined by logging.h. This can fail if operator<<(ostream, wstring) can't be
diff --git a/base/metrics/statistics_recorder_unittest.cc b/base/metrics/statistics_recorder_unittest.cc index 48b6df3..c581f15 100644 --- a/base/metrics/statistics_recorder_unittest.cc +++ b/base/metrics/statistics_recorder_unittest.cc
@@ -29,7 +29,6 @@ ~LogStateSaver() { logging::SetMinLogLevel(old_min_log_level_); - logging::SetLogAssertHandler(nullptr); } private:
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h index 5333640f..08feb60 100644 --- a/base/strings/string_piece.h +++ b/base/strings/string_piece.h
@@ -30,13 +30,10 @@ #include "base/base_export.h" #include "base/logging.h" #include "base/strings/string16.h" +#include "base/strings/string_piece_forward.h" namespace base { -template <typename STRING_TYPE> class BasicStringPiece; -typedef BasicStringPiece<std::string> StringPiece; -typedef BasicStringPiece<string16> StringPiece16; - // internal -------------------------------------------------------------------- // Many of the StringPiece functions use different implementations for the
diff --git a/base/strings/string_piece_forward.h b/base/strings/string_piece_forward.h new file mode 100644 index 0000000..86c1d5fbd --- /dev/null +++ b/base/strings/string_piece_forward.h
@@ -0,0 +1,23 @@ +// Copyright 2017 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. + +// Forward declaration of StringPiece types from base/strings/string_piece.h + +#ifndef BASE_STRINGS_STRING_PIECE_FORWARD_H_ +#define BASE_STRINGS_STRING_PIECE_FORWARD_H_ + +#include <string> + +#include "base/strings/string16.h" + +namespace base { + +template <typename STRING_TYPE> +class BasicStringPiece; +typedef BasicStringPiece<std::string> StringPiece; +typedef BasicStringPiece<string16> StringPiece16; + +} // namespace base + +#endif // BASE_STRINGS_STRING_PIECE_FORWARD_H_
diff --git a/base/test/gtest_xml_unittest_result_printer.cc b/base/test/gtest_xml_unittest_result_printer.cc index 6ce4fde..31ac4ad 100644 --- a/base/test/gtest_xml_unittest_result_printer.cc +++ b/base/test/gtest_xml_unittest_result_printer.cc
@@ -35,6 +35,14 @@ return true; } +void XmlUnitTestResultPrinter::OnAssert(const char* file, + int line, + const std::string& summary, + const std::string& message) { + WriteTestPartResult(file, line, testing::TestPartResult::kFatalFailure, + summary, message); +} + void XmlUnitTestResultPrinter::OnTestCaseStart( const testing::TestCase& test_case) { fprintf(output_file_, " <testsuite>\n"); @@ -66,7 +74,10 @@ " <failure message=\"\" type=\"\"></failure>\n"); } for (int i = 0; i < test_info.result()->total_part_count(); ++i) { - WriteTestPartResult(test_info.result()->GetTestPartResult(i)); + const auto& test_part_result = test_info.result()->GetTestPartResult(i); + WriteTestPartResult(test_part_result.file_name(), + test_part_result.line_number(), test_part_result.type(), + test_part_result.summary(), test_part_result.message()); } fprintf(output_file_, " </testcase>\n"); fflush(output_file_); @@ -79,9 +90,13 @@ } void XmlUnitTestResultPrinter::WriteTestPartResult( - const testing::TestPartResult& test_part_result) { + const char* file, + int line, + testing::TestPartResult::Type result_type, + const std::string& summary, + const std::string& message) { const char* type = "unknown"; - switch (test_part_result.type()) { + switch (result_type) { case testing::TestPartResult::kSuccess: type = "success"; break; @@ -92,10 +107,8 @@ type = "fatal_failure"; break; } - std::string summary = test_part_result.summary(); std::string summary_encoded; Base64Encode(summary, &summary_encoded); - std::string message = test_part_result.message(); std::string message_encoded; Base64Encode(message, &message_encoded); fprintf(output_file_, @@ -103,8 +116,7 @@ " <summary>%s</summary>\n" " <message>%s</message>\n" " </x-test-result-part>\n", - type, test_part_result.file_name(), test_part_result.line_number(), - summary_encoded.c_str(), message_encoded.c_str()); + type, file, line, summary_encoded.c_str(), message_encoded.c_str()); fflush(output_file_); }
diff --git a/base/test/gtest_xml_unittest_result_printer.h b/base/test/gtest_xml_unittest_result_printer.h index c7fb88f3..cce5e880 100644 --- a/base/test/gtest_xml_unittest_result_printer.h +++ b/base/test/gtest_xml_unittest_result_printer.h
@@ -25,6 +25,12 @@ // Must be called before adding as a listener. Returns true on success. bool Initialize(const FilePath& output_file_path) WARN_UNUSED_RESULT; + // CHECK/DCHECK failed. Print file/line and message to the xml. + void OnAssert(const char* file, + int line, + const std::string& summary, + const std::string& message); + private: // testing::EmptyTestEventListener: void OnTestCaseStart(const testing::TestCase& test_case) override; @@ -32,7 +38,11 @@ void OnTestEnd(const testing::TestInfo& test_info) override; void OnTestCaseEnd(const testing::TestCase& test_case) override; - void WriteTestPartResult(const testing::TestPartResult& test_part_result); + void WriteTestPartResult(const char* file, + int line, + testing::TestPartResult::Type type, + const std::string& summary, + const std::string& message); FILE* output_file_;
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index 6f4cc37..c9bfe9e 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -238,11 +238,11 @@ return; } - XmlUnitTestResultPrinter* printer = new XmlUnitTestResultPrinter; - CHECK(printer->Initialize(output_path)); + printer_ = new XmlUnitTestResultPrinter; + CHECK(printer_->Initialize(output_path)); testing::TestEventListeners& listeners = testing::UnitTest::GetInstance()->listeners(); - listeners.Append(printer); + listeners.Append(printer_); } // Don't add additional code to this method. Instead add it to @@ -282,8 +282,10 @@ return result; } -// static -void TestSuite::UnitTestAssertHandler(const std::string& str) { +void TestSuite::UnitTestAssertHandler(const char* file, + int line, + const base::StringPiece summary, + const base::StringPiece stack_trace) { #if defined(OS_ANDROID) // Correlating test stdio with logcat can be difficult, so we emit this // helpful little hint about what was running. Only do this for Android @@ -298,6 +300,16 @@ } #endif // defined(OS_ANDROID) + // XmlUnitTestResultPrinter inherits gtest format, where assert has summary + // and message. In GTest, summary is just a logged text, and message is a + // logged text, concatenated with stack trace of assert. + // Concatenate summary and stack_trace here, to pass it as a message. + if (printer_) { + const std::string summary_str = summary.as_string(); + const std::string stack_trace_str = summary_str + stack_trace.as_string(); + printer_->OnAssert(file, line, summary_str, stack_trace_str); + } + // The logging system actually prints the message before calling the assert // handler. Just exit now to avoid printing too many stack traces. _exit(1); @@ -359,7 +371,8 @@ !CommandLine::ForCurrentProcess()->HasSwitch("show-error-dialogs")) { SuppressErrorDialogs(); debug::SetSuppressDebugUI(true); - logging::SetLogAssertHandler(UnitTestAssertHandler); + assert_handler_ = base::MakeUnique<logging::ScopedLogAssertHandler>( + base::Bind(&TestSuite::UnitTestAssertHandler, base::Unretained(this))); } base::test::InitializeICUForTesting();
diff --git a/base/test/test_suite.h b/base/test/test_suite.h index 590a18c..82c746e 100644 --- a/base/test/test_suite.h +++ b/base/test/test_suite.h
@@ -13,6 +13,7 @@ #include <string> #include "base/at_exit.h" +#include "base/logging.h" #include "base/macros.h" #include "base/test/trace_to_file.h" #include "build/build_config.h" @@ -23,6 +24,8 @@ namespace base { +class XmlUnitTestResultPrinter; + // Instantiates TestSuite, runs it and returns exit code. int RunUnitTestsUsingBaseTestSuite(int argc, char **argv); @@ -54,7 +57,10 @@ // By default fatal log messages (e.g. from DCHECKs) result in error dialogs // which gum up buildbots. Use a minimalistic assert handler which just // terminates the process. - static void UnitTestAssertHandler(const std::string& str); + void UnitTestAssertHandler(const char* file, + int line, + const base::StringPiece summary, + const base::StringPiece stack_trace); // Disable crash dialogs so that it doesn't gum up the buildbot virtual void SuppressErrorDialogs(); @@ -84,6 +90,10 @@ bool created_feature_list_; + XmlUnitTestResultPrinter* printer_ = nullptr; + + std::unique_ptr<logging::ScopedLogAssertHandler> assert_handler_; + DISALLOW_COPY_AND_ASSIGN(TestSuite); };
diff --git a/base/values.cc b/base/values.cc index 72f6185..f24646cb 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -32,17 +32,14 @@ // Make a deep copy of |node|, but don't include empty lists or dictionaries // in the copy. It's possible for this function to return NULL and it // expects |node| to always be non-NULL. -std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) { - std::unique_ptr<ListValue> copy; - for (const auto& entry : list) { +std::unique_ptr<Value> CopyListWithoutEmptyChildren(const Value& list) { + Value copy(Value::Type::LIST); + for (const auto& entry : list.GetList()) { std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(entry); - if (child_copy) { - if (!copy) - copy.reset(new ListValue); - copy->Append(std::move(child_copy)); - } + if (child_copy) + copy.GetList().push_back(std::move(*child_copy)); } - return copy; + return copy.GetList().empty() ? nullptr : MakeUnique<Value>(std::move(copy)); } std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren( @@ -170,6 +167,14 @@ dict_.Init(std::move(in_dict)); } +Value::Value(const ListStorage& in_list) : type_(Type::LIST) { + list_.Init(in_list); +} + +Value::Value(ListStorage&& in_list) noexcept : type_(Type::LIST) { + list_.Init(std::move(in_list)); +} + Value& Value::operator=(const Value& that) { if (type_ == that.type_) { InternalCopyAssignFromSameType(that); @@ -229,6 +234,16 @@ return *binary_value_; } +Value::ListStorage& Value::GetList() { + CHECK(is_list()); + return *list_; +} + +const Value::ListStorage& Value::GetList() const { + CHECK(is_list()); + return *list_; +} + size_t Value::GetSize() const { return GetBlob().size(); }
diff --git a/base/values.h b/base/values.h index badf118..2bab074 100644 --- a/base/values.h +++ b/base/values.h
@@ -98,6 +98,9 @@ explicit Value(DictStorage&& in_dict) noexcept; + explicit Value(const ListStorage& in_list); + explicit Value(ListStorage&& in_list) noexcept; + Value& operator=(const Value& that); Value& operator=(Value&& that) noexcept; @@ -131,6 +134,9 @@ const std::string& GetString() const; const BlobStorage& GetBlob() const; + ListStorage& GetList(); + const ListStorage& GetList() const; + size_t GetSize() const; // DEPRECATED, use GetBlob().size() instead. const char* GetBuffer() const; // DEPRECATED, use GetBlob().data() instead.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc index be1e4d8..7f871123 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc
@@ -30,6 +30,9 @@ static_assert( std::is_nothrow_constructible<Value, Value::BlobStorage&&>::value, "IsNothrowMoveConstructibleFromBlob"); + static_assert( + std::is_nothrow_constructible<Value, Value::ListStorage&&>::value, + "IsNothrowMoveConstructibleFromList"); static_assert(std::is_nothrow_move_assignable<Value>::value, "IsNothrowMoveAssignable"); } @@ -224,25 +227,14 @@ } TEST(ValuesTest, CopyList) { - // TODO(crbug.com/646113): Clean this up once ListValue switched to - // value semantics. - int copy; - ListValue value; - value.AppendInteger(123); + Value value(Value::ListStorage{Value(123)}); - ListValue copied_value(value); - copied_value.GetInteger(0, ©); + Value copied_value(value); + EXPECT_EQ(value, copied_value); - EXPECT_EQ(value.type(), copied_value.type()); - EXPECT_EQ(123, copy); - - auto blank = MakeUnique<Value>(); - - *blank = value; - EXPECT_EQ(Value::Type::LIST, blank->type()); - - static_cast<ListValue*>(blank.get())->GetInteger(0, ©); - EXPECT_EQ(123, copy); + Value blank; + blank = value; + EXPECT_EQ(value, blank); } // Group of tests for the move constructors and move-assigmnent. @@ -341,22 +333,17 @@ } TEST(ValuesTest, MoveList) { - // TODO(crbug.com/646113): Clean this up once ListValue switched to - // value semantics. - int move; - ListValue value; - value.AppendInteger(123); - - ListValue moved_value(std::move(value)); - moved_value.GetInteger(0, &move); - + const Value::ListStorage list = {Value(123)}; + Value value(list); + Value moved_value(std::move(value)); EXPECT_EQ(Value::Type::LIST, moved_value.type()); - EXPECT_EQ(123, move); + EXPECT_EQ(123, moved_value.GetList().back().GetInt()); Value blank; - blank = ListValue(); + blank = Value(list); EXPECT_EQ(Value::Type::LIST, blank.type()); + EXPECT_EQ(123, blank.GetList().back().GetInt()); } TEST(ValuesTest, Basic) {
diff --git a/cc/raster/staging_buffer_pool.cc b/cc/raster/staging_buffer_pool.cc index 526e864e..3cb4b14d 100644 --- a/cc/raster/staging_buffer_pool.cc +++ b/cc/raster/staging_buffer_pool.cc
@@ -114,8 +114,8 @@ const uint64_t tracing_process_id = base::trace_event::MemoryDumpManager::GetInstance() ->GetTracingProcessId(); - MemoryAllocatorDumpGuid shared_buffer_guid = - gfx::GetGpuMemoryBufferGUIDForTracing(tracing_process_id, buffer_id); + auto shared_buffer_guid = + gpu_memory_buffer->GetGUIDForTracing(tracing_process_id); pmd->CreateSharedGlobalAllocatorDump(shared_buffer_guid); // By creating an edge with a higher |importance| (w.r.t. browser-side dumps)
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 86fd5ae..8d5a3fc 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -2174,8 +2174,8 @@ base::trace_event::MemoryAllocatorDumpGuid guid; switch (resource.type) { case RESOURCE_TYPE_GPU_MEMORY_BUFFER: - guid = gfx::GetGpuMemoryBufferGUIDForTracing( - tracing_process_id, resource.gpu_memory_buffer->GetHandle().id); + guid = + resource.gpu_memory_buffer->GetGUIDForTracing(tracing_process_id); break; case RESOURCE_TYPE_GL_TEXTURE: DCHECK(resource.gl_id);
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 9cf35a8d..cfb412e 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -465,7 +465,6 @@ "//third_party/WebKit/public:mojo_bindings_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", - "//third_party/android_tools:android_support_annotations_java", "//third_party/android_tools:android_support_design_java", "//third_party/android_tools:android_support_transition_java", "//third_party/android_tools:android_support_v7_appcompat_java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java index 5c55ae4..4560a32 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.offlinepages; import android.content.Context; -import android.support.annotation.MainThread; import android.support.test.filters.MediumTest; import org.chromium.base.Callback; @@ -31,13 +30,11 @@ @CommandLineFlags.Add("enable-features=OfflineRecentPages") public class RecentTabsTest extends ChromeTabbedActivityTestBase { private static final String TEST_PAGE = "/chrome/test/data/android/about.html"; - private static final String TEST_PAGE_2 = "/chrome/test/data/android/simple.html"; private static final int TIMEOUT_MS = 5000; private OfflinePageBridge mOfflinePageBridge; private EmbeddedTestServer mTestServer; private String mTestPage; - private String mTestPage2; private void initializeBridgeForProfile(final boolean incognitoProfile) throws InterruptedException { @@ -87,7 +84,6 @@ mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext()); mTestPage = mTestServer.getURL(TEST_PAGE); - mTestPage2 = mTestServer.getURL(TEST_PAGE_2); } @Override @@ -113,9 +109,9 @@ // The tab should be foreground and so no snapshot should exist. assertNull(getPageByClientId(firstTabClientId)); - // Note: switching to a new tab must occur after the SnapshotController believes the page - // quality is good enough. With the debug flag, the delay after DomContentLoaded is 0 so we - // can definitely snapshot after onload (which is what |loadUrlInNewTab| waits for). + // Note, that switching to a new tab must occur after the SnapshotController believes the + // page quality is good enough. With the debug flag, the delay after DomContentLoaded is 0 + // so we can definitely snapshot after onload (which is what |loadUrlInNewTab| waits for). // Switch to a new tab to cause the WebContents hidden event. loadUrlInNewTab("about:blank"); @@ -124,10 +120,10 @@ } /** - * Note: this test relies on a sleeping period because some of the monitored actions are - * difficult to track deterministically. A sleep time of 100 ms was chosen based on local - * testing and is expected to be "safe". Nevertheless if flakiness is detected it might have to - * be further increased. + * Note: this test relies on a sleeping period because some of the taking actions are + * complicated to track otherwise, so there is the possibility of flakiness. I chose 100ms from + * local testing and I expect it to be "safe" but it flakiness is detected it might have to be + * further increased. */ @CommandLineFlags.Add("short-offline-page-snapshot-delay-for-test") @MediumTest @@ -182,83 +178,6 @@ waitForPageWithClientId(firstTabClientId); } - /** - * Verifies that a snapshot created by last_n is properly deleted when the tab is navigated to - * another page. The deletion of snapshots for pages that should not be available anymore is a - * privacy requirement for last_n. - */ - @CommandLineFlags.Add("short-offline-page-snapshot-delay-for-test") - @MediumTest - public void testLastNPageIsDeletedUponNavigation() throws Exception { - // The tab of interest. - final Tab tab = loadUrlInNewTab(mTestPage); - final TabModelSelector tabModelSelector = tab.getTabModelSelector(); - - final ClientId firstTabClientId = - new ClientId(OfflinePageBridge.LAST_N_NAMESPACE, Integer.toString(tab.getId())); - - // Switch to a new tab and wait for the snapshot to be created. - loadUrlInNewTab("about:blank"); - waitForPageWithClientId(firstTabClientId); - OfflinePageItem offlinePage = getPageByClientId(firstTabClientId); - assertFalse(tab.equals(tabModelSelector.getCurrentTab())); - - // Switch back to the initial tab and install the page deletion monitor for later usage. - final OfflinePageDeletionMonitor deletionMonitor = - new OfflinePageDeletionMonitor(offlinePage.getOfflineId()); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - TabModel tabModel = tabModelSelector.getModelForTabId(tab.getId()); - int tabIndex = TabModelUtils.getTabIndexById(tabModel, tab.getId()); - TabModelUtils.setIndex(tabModel, tabIndex); - deletionMonitor.installObserver(); - } - }); - assertEquals(tabModelSelector.getCurrentTab(), tab); - - // Navigate to a new page and confirm the previously created snapshot has been deleted. - loadUrl(mTestPage2); - deletionMonitor.assertDeleted(); - } - - /** - * Verifies that a snapshot created by last_n is properly deleted when the tab is closed. The - * deletion of snapshots for pages that should not be available anymore is a privacy requirement - * for last_n. - */ - @CommandLineFlags.Add("short-offline-page-snapshot-delay-for-test") - @MediumTest - public void testLastNPageIsDeletedUponClosure() throws Exception { - // The tab of interest. - final Tab tab = loadUrlInNewTab(mTestPage); - final TabModelSelector tabModelSelector = tab.getTabModelSelector(); - - final ClientId firstTabClientId = - new ClientId(OfflinePageBridge.LAST_N_NAMESPACE, Integer.toString(tab.getId())); - - // Switch to a new tab and wait for the snapshot to be created. - loadUrlInNewTab("about:blank"); - waitForPageWithClientId(firstTabClientId); - OfflinePageItem offlinePage = getPageByClientId(firstTabClientId); - - // Requests closing of the tab allowing for closure undo and checks it's actually closing. - final int tabId = tab.getId(); - final OfflinePageDeletionMonitor deletionMonitor = - new OfflinePageDeletionMonitor(offlinePage.getOfflineId()); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - deletionMonitor.installObserver(); - TabModel tabModel = tabModelSelector.getModelForTabId(tabId); - tabModel.closeTab(tab, false, false, true); - tabModel.commitTabClosure(tabId); - } - }); - assertNull(tabModelSelector.getTabById(tabId)); - deletionMonitor.assertDeleted(); - } - private void waitForPageWithClientId(final ClientId clientId) throws InterruptedException { if (getPageByClientId(clientId) != null) return; @@ -280,32 +199,6 @@ assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } - private class OfflinePageDeletionMonitor { - private final Semaphore mSemaphore = new Semaphore(0); - private final long mOfflineId; - - public OfflinePageDeletionMonitor(long offlineId) { - mOfflineId = offlineId; - } - - @MainThread - public void installObserver() { - mOfflinePageBridge.addObserver(new OfflinePageModelObserver() { - @Override - public void offlinePageDeleted(long offlineId, ClientId clientId) { - if (offlineId == mOfflineId) { - mOfflinePageBridge.removeObserver(this); - mSemaphore.release(); - } - } - }); - } - - public void assertDeleted() throws InterruptedException { - assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } - } - private OfflinePageItem getPageByClientId(ClientId clientId) throws InterruptedException { final OfflinePageItem[] result = {null}; final Semaphore semaphore = new Semaphore(0); @@ -330,24 +223,4 @@ assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); return result[0]; } - - private OfflinePageItem getPageByOfflineId(final long offlineId) throws InterruptedException { - final OfflinePageItem[] result = {null}; - final Semaphore semaphore = new Semaphore(0); - - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - mOfflinePageBridge.getPageByOfflineId(offlineId, new Callback<OfflinePageItem>() { - @Override - public void onResult(OfflinePageItem item) { - result[0] = item; - semaphore.release(); - } - }); - } - }); - assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - return result[0]; - } }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a387ef7..0918bf45 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -278,15 +278,6 @@ <message name="IDS_PAGE_INFO_PERMISSION_ASK" desc="The label used in the permissions dropdowns for the option that makes the browser asks for permission. "> ask </message> - <message name="IDS_PAGE_INFO_PERMISSION_SET_BY_POLICY" desc="The label used underneath a permission listed in the Website Settings popup if the permission was explicitly set by the user's enterprise policy."> - Controlled by enterprise policy - </message> - <message name="IDS_PAGE_INFO_PERMISSION_SET_BY_EXTENSION" desc="The label used underneath a permission listed in the Website Settings popup if the permission was explicitly set by one of the user's extensions."> - Controlled by an extension - </message> - <message name="IDS_PAGE_INFO_PERMISSION_AUTOMATICALLY_BLOCKED" desc="The label used underneath a permission listed in the Website Settings popup if the permission was blocked by Chrome on behalf of the user."> - Automatically blocked - </message> <message name="IDS_PAGE_INFO_TYPE_AUTOPLAY" desc="The label used for the autoplay permission controls in the Website Settings popup."> Autoplay </message>
diff --git a/chrome/browser/android/locale/special_locale_handler.cc b/chrome/browser/android/locale/special_locale_handler.cc index 0f3271f..e1f55b6 100644 --- a/chrome/browser/android/locale/special_locale_handler.cc +++ b/chrome/browser/android/locale/special_locale_handler.cc
@@ -65,8 +65,9 @@ return false; for (const auto& data_url : prepopulated_list) { - TemplateURL* existing = template_url_service_->GetTemplateURLForKeyword( - data_url.get()->keyword()); + const TemplateURL* existing = + template_url_service_->GetTemplateURLForKeyword( + data_url.get()->keyword()); // Do not add local engines if there is already one. if (existing) continue;
diff --git a/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc b/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc index db41ab6..cc3ce6a8 100644 --- a/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc +++ b/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
@@ -451,7 +451,9 @@ EXPECT_EQ(Offliner::RequestStatus::FOREGROUND_CANCELED, request_status()); } -TEST_F(PrerenderingOfflinerTest, ForegroundTransitionIgnoredOnHighEndDevice) { +// TODO(crbug.com/712941): Flaky test. +TEST_F(PrerenderingOfflinerTest, + DISABLED_ForegroundTransitionIgnoredOnHighEndDevice) { offliner()->SetLowEndDeviceForTesting(false); base::Time creation_time = base::Time::Now();
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper.cc b/chrome/browser/android/offline_pages/recent_tab_helper.cc index 308afd1..f248220 100644 --- a/chrome/browser/android/offline_pages/recent_tab_helper.cc +++ b/chrome/browser/android/offline_pages/recent_tab_helper.cc
@@ -212,27 +212,18 @@ downloads_ongoing_snapshot_info_.get(), false); } - // If the previous page was saved, delete it now. - if (last_n_latest_saved_snapshot_info_) { - std::vector<int64_t> id{last_n_latest_saved_snapshot_info_->request_id}; - page_model_->DeletePagesByOfflineId(id, DeletePageCallback()); - } - // Cancel any and all in flight snapshot tasks from the previous page. + DVLOG_IF(1, last_n_ongoing_snapshot_info_) + << " - Canceling ongoing last_n snapshot"; CancelInFlightSnapshots(); downloads_snapshot_on_hold_ = false; // Always reset so that posted tasks get canceled. snapshot_controller_->Reset(); - // Check for conditions that should stop last_n from creating snapshots of - // this page: - // - It is an error page. - // - The navigation is a POST as offline pages are never loaded for them. - // - The navigated URL is not supported. - // - The page being loaded is already an offline page. + // Check for conditions that would cause us not to snapshot. bool can_save = - !navigation_handle->IsErrorPage() && !navigation_handle->IsPost() && + !navigation_handle->IsErrorPage() && OfflinePageModel::CanSaveURL(web_contents()->GetLastCommittedURL()) && OfflinePageUtils::GetOfflinePageFromWebContents(web_contents()) == nullptr; @@ -428,12 +419,8 @@ void RecentTabHelper::SavePageCallback(SnapshotProgressInfo* snapshot_info, OfflinePageModel::SavePageResult result, int64_t offline_id) { - DCHECK((snapshot_info->IsForLastN() && - snapshot_info->request_id == OfflinePageModel::kInvalidOfflineId) || + DCHECK(snapshot_info->IsForLastN() || snapshot_info->request_id == offline_id); - // Store the assigned offline_id (for downloads case it will already contain - // the same value). - snapshot_info->request_id = offline_id; ReportSnapshotCompleted(snapshot_info, result == SavePageResult::SUCCESS); } @@ -447,12 +434,7 @@ << " for: " << web_contents()->GetLastCommittedURL().spec(); if (snapshot_info->IsForLastN()) { DCHECK_EQ(snapshot_info, last_n_ongoing_snapshot_info_.get()); - if (success) { - last_n_latest_saved_snapshot_info_ = - std::move(last_n_ongoing_snapshot_info_); - } else { - last_n_ongoing_snapshot_info_.reset(); - } + last_n_ongoing_snapshot_info_.reset(); return; } @@ -499,15 +481,10 @@ } void RecentTabHelper::CancelInFlightSnapshots() { - DVLOG_IF(1, last_n_ongoing_snapshot_info_) - << " - Canceling ongoing last_n snapshot"; - DVLOG_IF(1, downloads_ongoing_snapshot_info_) - << " - Canceling ongoing downloads snapshot"; weak_ptr_factory_.InvalidateWeakPtrs(); downloads_ongoing_snapshot_info_.reset(); downloads_latest_saved_snapshot_info_.reset(); last_n_ongoing_snapshot_info_.reset(); - last_n_latest_saved_snapshot_info_.reset(); } } // namespace offline_pages
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper.h b/chrome/browser/android/offline_pages/recent_tab_helper.h index c61fbd74..b547240 100644 --- a/chrome/browser/android/offline_pages/recent_tab_helper.h +++ b/chrome/browser/android/offline_pages/recent_tab_helper.h
@@ -128,18 +128,13 @@ bool downloads_snapshot_on_hold_ = false; // Snapshot information for the last successful snapshot requested by - // downloads. Null if no successful one has ever completed for the current - // page. + // downloads. Null if no successful one has ever completed. std::unique_ptr<SnapshotProgressInfo> downloads_latest_saved_snapshot_info_; // Snapshot progress information for a last_n triggered request. Null if // last_n is not currently capturing the current page. std::unique_ptr<SnapshotProgressInfo> last_n_ongoing_snapshot_info_; - // Snapshot information for the last successful snapshot requested by - // last_n. Null if no successful one has ever completed for the current page. - std::unique_ptr<SnapshotProgressInfo> last_n_latest_saved_snapshot_info_; - // If empty, the tab does not have AndroidId and can not capture pages. std::string tab_id_;
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc index 3e4c535..7f97d15f 100644 --- a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc +++ b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc
@@ -375,8 +375,8 @@ ASSERT_EQ(1U, GetAllPages().size()); } -// Checks that last_n will not save a snapshot while the tab is being presented -// as a custom tab. Download requests should be unaffected though. +// Checks that last_n will not save a snapshot if the tab while the tab is +// presented as a custom tab. Download requests should be unaffected though. TEST_F(RecentTabHelperTest, LastNWontSaveCustomTab) { // Simulates the tab running as a custom tab. default_test_delegate()->set_is_custom_tab(true); @@ -500,16 +500,15 @@ EXPECT_EQ(kTestPageUrl, GetAllPages()[0].url); int64_t first_offline_id = GetAllPages()[0].offline_id; - // Reload the same URL until the page is minimally loaded. The previous - // snapshot should have been removed. + // Navigate with the same URL until the page is minimally loaded then hide the + // tab. The previous snapshot should be removed and a new one taken. NavigateAndCommitTyped(kTestPageUrl); recent_tab_helper()->DocumentAvailableInMainFrame(); FastForwardSnapshotController(); EXPECT_EQ(1U, page_added_count()); - EXPECT_EQ(1U, model_removed_count()); - ASSERT_EQ(0U, GetAllPages().size()); + EXPECT_EQ(0U, model_removed_count()); + ASSERT_EQ(1U, GetAllPages().size()); - // Hide the tab and a new snapshot should be taken. recent_tab_helper()->WasHidden(); RunUntilIdle(); EXPECT_EQ(2U, page_added_count()); @@ -566,15 +565,15 @@ ASSERT_EQ(1U, GetAllPages().size()); EXPECT_EQ(kTestPageUrl, GetAllPages()[0].url); - // Fully load the second URL. The previous snapshot should have been deleted. + // Fully load the second URL then hide the tab and check for a single snapshot + // of the new page. NavigateAndCommitTyped(kTestPageUrlOther); recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(); FastForwardSnapshotController(); EXPECT_EQ(1U, page_added_count()); - EXPECT_EQ(1U, model_removed_count()); - ASSERT_EQ(0U, GetAllPages().size()); + EXPECT_EQ(0U, model_removed_count()); + ASSERT_EQ(1U, GetAllPages().size()); - // Then hide the tab and check for a single snapshot of the new page. recent_tab_helper()->WasHidden(); RunUntilIdle(); EXPECT_EQ(2U, page_added_count()); @@ -732,7 +731,7 @@ } // Simulates a download request to offline the current page made after loading -// is completed. Should end up with one offline page. +// is completed. Should end up with one offline pages. TEST_F(RecentTabHelperTest, DownloadRequestAfterFullyLoad) { NavigateAndCommit(kTestPageUrl); recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(); @@ -898,8 +897,7 @@ RunUntilIdle(); ASSERT_EQ(1U, GetAllPages().size()); - // Starts a reload and hides the tab before it minimally load. The previous - // snapshot should be removed. + // Starts a reload and hides the tab. No new snapshot should be saved. controller().Reload(content::ReloadType::NORMAL, false); content::WebContentsTester* web_contents_tester = content::WebContentsTester::For(web_contents()); @@ -907,8 +905,8 @@ recent_tab_helper()->WasHidden(); RunUntilIdle(); EXPECT_EQ(1U, page_added_count()); - EXPECT_EQ(1U, model_removed_count()); - ASSERT_EQ(0U, GetAllPages().size()); + EXPECT_EQ(0U, model_removed_count()); + ASSERT_EQ(1U, GetAllPages().size()); // Finish loading and hide the tab. A new snapshot should be created. recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
diff --git a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc index ff5bd80..68f9806e 100644 --- a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc +++ b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc
@@ -37,10 +37,11 @@ using device::UsbDevice; using device::UsbDeviceHandle; using device::UsbEndpointDescriptor; -using device::UsbEndpointDirection; using device::UsbInterfaceDescriptor; using device::UsbService; using device::UsbSynchronizationType; +using device::UsbTransferDirection; +using device::UsbTransferStatus; using device::UsbTransferType; using device::UsbUsageType; @@ -183,9 +184,9 @@ } // Async IO. Can be called on any thread. - void ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + void ControlTransfer(UsbTransferDirection direction, + device::UsbControlTransferType request_type, + device::UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -194,13 +195,13 @@ unsigned int timeout, const TransferCallback& callback) override {} - void GenericTransfer(UsbEndpointDirection direction, + void GenericTransfer(UsbTransferDirection direction, uint8_t endpoint, scoped_refptr<net::IOBuffer> buffer, size_t length, unsigned int timeout, const TransferCallback& callback) override { - if (direction == device::USB_DIRECTION_OUTBOUND) { + if (direction == device::UsbTransferDirection::OUTBOUND) { if (remaining_body_length_ == 0) { std::vector<uint32_t> header(6); memcpy(&header[0], buffer->data(), length); @@ -222,12 +223,13 @@ ProcessIncoming(); } - device::UsbTransferStatus status = - broken_ ? device::USB_TRANSFER_ERROR : device::USB_TRANSFER_COMPLETED; + device::UsbTransferStatus status = broken_ + ? UsbTransferStatus::TRANSFER_ERROR + : UsbTransferStatus::COMPLETED; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(callback, status, nullptr, 0)); ProcessQueries(); - } else if (direction == device::USB_DIRECTION_INBOUND) { + } else if (direction == device::UsbTransferDirection::INBOUND) { queries_.push(Query(callback, buffer, length)); ProcessQueries(); } @@ -337,8 +339,8 @@ Query query = queries_.front(); if (broken_) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(query.callback, device::USB_TRANSFER_ERROR, nullptr, 0)); + FROM_HERE, base::Bind(query.callback, + UsbTransferStatus::TRANSFER_ERROR, nullptr, 0)); } if (query.size > output_buffer_.size()) @@ -351,7 +353,7 @@ output_buffer_.erase(output_buffer_.begin(), output_buffer_.begin() + query.size); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(query.callback, device::USB_TRANSFER_COMPLETED, + FROM_HERE, base::Bind(query.callback, UsbTransferStatus::COMPLETED, query.buffer, query.size)); }
diff --git a/chrome/browser/devtools/device/usb/android_usb_device.cc b/chrome/browser/devtools/device/usb/android_usb_device.cc index 5b37f88..e8754bd2c 100644 --- a/chrome/browser/devtools/device/usb/android_usb_device.cc +++ b/chrome/browser/devtools/device/usb/android_usb_device.cc
@@ -36,7 +36,9 @@ using device::UsbInterfaceDescriptor; using device::UsbEndpointDescriptor; using device::UsbService; +using device::UsbTransferDirection; using device::UsbTransferStatus; +using device::UsbTransferType; namespace { @@ -227,9 +229,9 @@ int zero_mask = 0; for (const UsbEndpointDescriptor& endpoint : interface.endpoints) { - if (endpoint.transfer_type != device::USB_TRANSFER_BULK) + if (endpoint.transfer_type != UsbTransferType::BULK) continue; - if (endpoint.direction == device::USB_DIRECTION_INBOUND) + if (endpoint.direction == UsbTransferDirection::INBOUND) inbound_address = endpoint.address; else outbound_address = endpoint.address; @@ -446,7 +448,7 @@ DumpMessage(true, message->data(), message->size()); usb_handle_->GenericTransfer( - device::USB_DIRECTION_OUTBOUND, outbound_address_, message, + UsbTransferDirection::OUTBOUND, outbound_address_, message, message->size(), kUsbTimeout, base::Bind(&AndroidUsbDevice::OutgoingMessageSent, weak_factory_.GetWeakPtr())); @@ -455,7 +457,7 @@ void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, scoped_refptr<net::IOBuffer> buffer, size_t result) { - if (status != device::USB_TRANSFER_COMPLETED) { + if (status != UsbTransferStatus::COMPLETED) { return; } @@ -472,7 +474,7 @@ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize); usb_handle_->GenericTransfer( - device::USB_DIRECTION_INBOUND, inbound_address_, buffer, kHeaderSize, + UsbTransferDirection::INBOUND, inbound_address_, buffer, kHeaderSize, kUsbTimeout, base::Bind(&AndroidUsbDevice::ParseHeader, weak_factory_.GetWeakPtr())); } @@ -482,13 +484,13 @@ size_t result) { DCHECK(task_runner_->BelongsToCurrentThread()); - if (status == device::USB_TRANSFER_TIMEOUT) { + if (status == UsbTransferStatus::TIMEOUT) { task_runner_->PostTask(FROM_HERE, base::Bind(&AndroidUsbDevice::ReadHeader, this)); return; } - if (status != device::USB_TRANSFER_COMPLETED || result != kHeaderSize) { + if (status != UsbTransferStatus::COMPLETED || result != kHeaderSize) { TransferError(status); return; } @@ -502,7 +504,7 @@ uint32_t data_check = header[4]; uint32_t magic = header[5]; if ((message->command ^ 0xffffffff) != magic) { - TransferError(device::USB_TRANSFER_ERROR); + TransferError(UsbTransferStatus::TRANSFER_ERROR); return; } @@ -529,7 +531,7 @@ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(static_cast<size_t>(data_length)); usb_handle_->GenericTransfer( - device::USB_DIRECTION_INBOUND, inbound_address_, buffer, data_length, + UsbTransferDirection::INBOUND, inbound_address_, buffer, data_length, kUsbTimeout, base::Bind(&AndroidUsbDevice::ParseBody, weak_factory_.GetWeakPtr(), base::Passed(&message), data_length, data_check)); @@ -543,14 +545,14 @@ size_t result) { DCHECK(task_runner_->BelongsToCurrentThread()); - if (status == device::USB_TRANSFER_TIMEOUT) { + if (status == UsbTransferStatus::TIMEOUT) { task_runner_->PostTask( FROM_HERE, base::Bind(&AndroidUsbDevice::ReadBody, this, base::Passed(&message), data_length, data_check)); return; } - if (status != device::USB_TRANSFER_COMPLETED || + if (status != UsbTransferStatus::COMPLETED || static_cast<uint32_t>(result) != data_length) { TransferError(status); return; @@ -559,7 +561,7 @@ DumpMessage(false, buffer->data(), data_length); message->body = std::string(buffer->data(), result); if (Checksum(message->body) != data_check) { - TransferError(device::USB_TRANSFER_ERROR); + TransferError(UsbTransferStatus::TRANSFER_ERROR); return; }
diff --git a/chrome/browser/extensions/app_data_migrator_unittest.cc b/chrome/browser/extensions/app_data_migrator_unittest.cc index ac2610d..0bea1900 100644 --- a/chrome/browser/extensions/app_data_migrator_unittest.cc +++ b/chrome/browser/extensions/app_data_migrator_unittest.cc
@@ -17,7 +17,6 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/indexed_db_context.h" #include "content/public/browser/storage_partition.h" -#include "content/public/test/mock_blob_url_request_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" @@ -26,6 +25,7 @@ #include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_operation_runner.h" #include "storage/browser/fileapi/file_system_url.h" +#include "storage/browser/test/mock_blob_url_request_context.h" #include "testing/gtest/include/gtest/gtest.h" namespace {
diff --git a/chrome/browser/media/webrtc/webrtc_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_log_uploader.cc index 24a0642..83e3cb4 100644 --- a/chrome/browser/media/webrtc/webrtc_log_uploader.cc +++ b/chrome/browser/media/webrtc/webrtc_log_uploader.cc
@@ -23,6 +23,7 @@ #include "chrome/common/partial_circular_buffer.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" +#include "net/base/load_flags.h" #include "net/base/mime_util.h" #include "net/url_request/url_fetcher.h" #include "third_party/zlib/zlib.h" @@ -449,6 +450,8 @@ std::unique_ptr<net::URLFetcher> url_fetcher(net::URLFetcher::Create( GURL(chrome::kUploadURL), net::URLFetcher::POST, this)); url_fetcher->SetUploadData(content_type, *post_data); + url_fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | + net::LOAD_DO_NOT_SAVE_COOKIES); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(&WebRtcLogUploader::SetRequestContextOnUIThread, base::Unretained(this), base::Unretained(url_fetcher.release()),
diff --git a/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc b/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc index f7931d25..5f10376 100644 --- a/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc
@@ -344,11 +344,19 @@ IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest, MANUAL_TestVideoQualityVp8) { +// Disable these tests until crbug.com/711400 is addressed. +#if defined(OS_MACOSX) + return; +#endif // defined(OS_MACOSX) TestVideoQuality("VP8"); } IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest, MANUAL_TestVideoQualityVp9) { +// Disable these tests until crbug.com/711400 is addressed. +#if defined(OS_MACOSX) + return; +#endif // defined(OS_MACOSX) TestVideoQuality("VP9"); } @@ -356,6 +364,10 @@ IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest, MANUAL_TestVideoQualityH264) { +// Disable these tests until crbug.com/711400 is addressed. +#if defined(OS_MACOSX) + return; +#endif // defined(OS_MACOSX) // Only run test if run-time feature corresponding to |rtc_use_h264| is on. if (!base::FeatureList::IsEnabled(content::kWebRtcH264WithOpenH264FFmpeg)) { LOG(WARNING) << "Run-time feature WebRTC-H264WithOpenH264FFmpeg disabled. "
diff --git a/chrome/browser/resources/md_bookmarks/actions.js b/chrome/browser/resources/md_bookmarks/actions.js index 9f6a63d..11fd96e 100644 --- a/chrome/browser/resources/md_bookmarks/actions.js +++ b/chrome/browser/resources/md_bookmarks/actions.js
@@ -70,7 +70,7 @@ * @param {string} id * @param {string} parentId * @param {number} index - * @param {NodeList} nodes + * @param {NodeMap} nodes * @return {!Action} */ function removeBookmark(id, parentId, index, nodes) { @@ -85,7 +85,7 @@ } /** - * @param {NodeList} nodeMap + * @param {NodeMap} nodeMap * @return {!Action} */ function refreshNodes(nodeMap) {
diff --git a/chrome/browser/resources/md_bookmarks/app.js b/chrome/browser/resources/md_bookmarks/app.js index ed59f5e..c7a396a1 100644 --- a/chrome/browser/resources/md_bookmarks/app.js +++ b/chrome/browser/resources/md_bookmarks/app.js
@@ -43,10 +43,10 @@ }); chrome.bookmarks.getTree(function(results) { - var nodeList = bookmarks.util.normalizeNodes(results[0]); + var nodeMap = bookmarks.util.normalizeNodes(results[0]); var initialState = bookmarks.util.createEmptyState(); - initialState.nodes = nodeList; - initialState.selectedFolder = nodeList[ROOT_NODE_ID].children[0]; + initialState.nodes = nodeMap; + initialState.selectedFolder = nodeMap[ROOT_NODE_ID].children[0]; var closedFoldersString = window.localStorage[LOCAL_STORAGE_CLOSED_FOLDERS_KEY]; initialState.closedFolders = closedFoldersString ?
diff --git a/chrome/browser/resources/md_bookmarks/reducers.js b/chrome/browser/resources/md_bookmarks/reducers.js index b0d0a926..6ad7193 100644 --- a/chrome/browser/resources/md_bookmarks/reducers.js +++ b/chrome/browser/resources/md_bookmarks/reducers.js
@@ -153,10 +153,10 @@ var NodeState = {}; /** - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {string} id * @param {function(BookmarkNode):BookmarkNode} callback - * @return {NodeList} + * @return {NodeMap} */ NodeState.modifyNode_ = function(nodes, id, callback) { var nodeModification = {}; @@ -165,9 +165,9 @@ }; /** - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {Action} action - * @return {NodeList} + * @return {NodeMap} */ NodeState.createBookmark = function(nodes, action) { var nodeModifications = {}; @@ -184,9 +184,9 @@ }; /** - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {Action} action - * @return {NodeList} + * @return {NodeMap} */ NodeState.editBookmark = function(nodes, action) { // Do not allow folders to change URL (making them no longer folders). @@ -200,9 +200,9 @@ }; /** - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {Action} action - * @return {NodeList} + * @return {NodeMap} */ NodeState.moveBookmark = function(nodes, action) { var nodeModifications = {}; @@ -232,9 +232,9 @@ }; /** - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {Action} action - * @return {NodeList} + * @return {NodeMap} */ NodeState.removeBookmark = function(nodes, action) { var newState = @@ -249,9 +249,9 @@ }; /** - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {Action} action - * @return {NodeList} + * @return {NodeMap} */ NodeState.reorderChildren = function(nodes, action) { return NodeState.modifyNode_(nodes, action.id, function(node) { @@ -261,9 +261,9 @@ }; /** - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {Action} action - * @return {NodeList} + * @return {NodeMap} */ NodeState.updateNodes = function(nodes, action) { switch (action.name) { @@ -287,7 +287,7 @@ var SelectedFolderState = {}; /** - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {string} ancestorId * @param {string} childId * @return {boolean} @@ -306,7 +306,7 @@ /** * @param {string} selectedFolder * @param {Action} action - * @param {NodeList} nodes + * @param {NodeMap} nodes * @return {string} */ SelectedFolderState.updateSelectedFolder = function( @@ -341,7 +341,7 @@ /** * @param {ClosedFolderState} closedFolders * @param {string|undefined} id - * @param {NodeList} nodes + * @param {NodeMap} nodes * @return {ClosedFolderState} */ ClosedFolderState.openFolderAndAncestors = function( @@ -377,7 +377,7 @@ /** * @param {ClosedFolderState} closedFolders * @param {Action} action - * @param {NodeList} nodes + * @param {NodeMap} nodes * @return {ClosedFolderState} */ ClosedFolderState.updateClosedFolders = function(
diff --git a/chrome/browser/resources/md_bookmarks/types.js b/chrome/browser/resources/md_bookmarks/types.js index 8eb1a37..6043c006 100644 --- a/chrome/browser/resources/md_bookmarks/types.js +++ b/chrome/browser/resources/md_bookmarks/types.js
@@ -24,7 +24,7 @@ /** * @typedef {!Object<string, BookmarkNode>} */ -var NodeList; +var NodeMap; /** * @typedef {{ @@ -50,7 +50,7 @@ /** * @typedef {{ - * nodes: NodeList, + * nodes: NodeMap, * selectedFolder: string, * closedFolders: ClosedFolderState, * search: SearchState,
diff --git a/chrome/browser/resources/md_bookmarks/util.js b/chrome/browser/resources/md_bookmarks/util.js index c6e4c00..a660add7 100644 --- a/chrome/browser/resources/md_bookmarks/util.js +++ b/chrome/browser/resources/md_bookmarks/util.js
@@ -42,17 +42,17 @@ /** * @param {BookmarkTreeNode} rootNode - * @return {NodeList} + * @return {NodeMap} */ function normalizeNodes(rootNode) { - /** @type {NodeList} */ - var nodeList = {}; + /** @type {NodeMap} */ + var nodeMap = {}; var stack = []; stack.push(rootNode); while (stack.length > 0) { var node = stack.pop(); - nodeList[node.id] = normalizeNode(node); + nodeMap[node.id] = normalizeNode(node); if (!node.children) continue; @@ -61,7 +61,7 @@ }); } - return nodeList; + return nodeMap; } /** @return {!BookmarksPageState} */ @@ -92,7 +92,7 @@ /** * @param {string} id - * @param {NodeList} nodes + * @param {NodeMap} nodes * @return {boolean} */ function hasChildFolders(id, nodes) { @@ -106,7 +106,7 @@ /** * Get all descendants of a node, including the node itself. - * @param {NodeList} nodes + * @param {NodeMap} nodes * @param {string} baseId * @return {!Set<string>} */
diff --git a/chrome/browser/safe_browsing/client_side_model_loader.cc b/chrome/browser/safe_browsing/client_side_model_loader.cc index bd2418b..fd52174 100644 --- a/chrome/browser/safe_browsing/client_side_model_loader.cc +++ b/chrome/browser/safe_browsing/client_side_model_loader.cc
@@ -22,6 +22,7 @@ #include "components/safe_browsing/common/safebrowsing_switches.h" #include "components/safe_browsing/csd.pb.h" #include "components/variations/variations_associated_data.h" +#include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" #include "net/url_request/url_fetcher.h" @@ -121,6 +122,8 @@ data_use_measurement::DataUseUserData::AttachToFetcher( fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING); fetcher_->SetRequestContext(request_context_getter_); + fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | + net::LOAD_DO_NOT_SEND_COOKIES); fetcher_->Start(); }
diff --git a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc index 9b53439..e22924b 100644 --- a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc +++ b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/sync_file_system/local/local_file_sync_context.h" #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" #include "chrome/browser/sync_file_system/syncable_file_system_util.h" -#include "content/public/test/mock_blob_url_request_context.h" #include "storage/browser/blob/shareable_file_reference.h" #include "storage/browser/fileapi/external_mount_points.h" #include "storage/browser/fileapi/file_system_backend.h" @@ -33,6 +32,7 @@ #include "storage/browser/fileapi/file_system_operation_context.h" #include "storage/browser/fileapi/file_system_operation_runner.h" #include "storage/browser/quota/quota_manager.h" +#include "storage/browser/test/mock_blob_url_request_context.h" #include "storage/browser/test/mock_special_storage_policy.h" #include "storage/browser/test/test_file_system_options.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/sync_file_system/local/local_file_change_tracker_unittest.cc b/chrome/browser/sync_file_system/local/local_file_change_tracker_unittest.cc index 7ace915f..36044a0 100644 --- a/chrome/browser/sync_file_system/local/local_file_change_tracker_unittest.cc +++ b/chrome/browser/sync_file_system/local/local_file_change_tracker_unittest.cc
@@ -20,10 +20,10 @@ #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" #include "chrome/browser/sync_file_system/sync_status_code.h" #include "chrome/browser/sync_file_system/syncable_file_system_util.h" -#include "content/public/test/mock_blob_url_request_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/quota/quota_manager.h" +#include "storage/browser/test/mock_blob_url_request_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" #include "third_party/leveldatabase/src/include/leveldb/env.h"
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc b/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc index 1df82ae..1fc9024 100644 --- a/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc +++ b/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc
@@ -26,12 +26,12 @@ #include "chrome/browser/sync_file_system/sync_status_code.h" #include "chrome/browser/sync_file_system/syncable_file_system_util.h" #include "content/public/browser/browser_thread.h" -#include "content/public/test/mock_blob_url_request_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "storage/browser/blob/scoped_file.h" #include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_operation_runner.h" #include "storage/browser/fileapi/isolated_context.h" +#include "storage/browser/test/mock_blob_url_request_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" #include "third_party/leveldatabase/src/include/leveldb/env.h"
diff --git a/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc b/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc index 1193a9f..8e513f0 100644 --- a/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc +++ b/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc
@@ -24,10 +24,10 @@ #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" #include "chrome/browser/sync_file_system/local/syncable_file_system_operation.h" #include "chrome/browser/sync_file_system/syncable_file_system_util.h" -#include "content/public/test/mock_blob_url_request_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_operation_runner.h" +#include "storage/browser/test/mock_blob_url_request_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" #include "third_party/leveldatabase/src/include/leveldb/env.h"
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc index 6646e6b3..c6f224e 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc +++ b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc
@@ -223,7 +223,7 @@ } bool ChromeOmniboxClient::ProcessExtensionKeyword( - TemplateURL* template_url, + const TemplateURL* template_url, const AutocompleteMatch& match, WindowOpenDisposition disposition, OmniboxNavigationObserver* observer) {
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_client.h b/chrome/browser/ui/omnibox/chrome_omnibox_client.h index 3c23dfb4..ac7d14e 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_client.h +++ b/chrome/browser/ui/omnibox/chrome_omnibox_client.h
@@ -45,7 +45,7 @@ AutocompleteClassifier* GetAutocompleteClassifier() override; gfx::Image GetIconIfExtensionMatch( const AutocompleteMatch& match) const override; - bool ProcessExtensionKeyword(TemplateURL* template_url, + bool ProcessExtensionKeyword(const TemplateURL* template_url, const AutocompleteMatch& match, WindowOpenDisposition disposition, OmniboxNavigationObserver* observer) override;
diff --git a/chrome/browser/ui/page_info/page_info_ui.cc b/chrome/browser/ui/page_info/page_info_ui.cc index 34a289b..2ff9c63 100644 --- a/chrome/browser/ui/page_info/page_info_ui.cc +++ b/chrome/browser/ui/page_info/page_info_ui.cc
@@ -28,6 +28,33 @@ const int kInvalidResourceID = -1; // The resource IDs for the strings that are displayed on the permissions +// button if the permission setting is managed by policy. +const int kPermissionButtonTextIDPolicyManaged[] = { + kInvalidResourceID, + IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_POLICY, + IDS_PAGE_INFO_PERMISSION_BLOCKED_BY_POLICY, + IDS_PAGE_INFO_PERMISSION_ASK_BY_POLICY, + kInvalidResourceID, + kInvalidResourceID}; +static_assert(arraysize(kPermissionButtonTextIDPolicyManaged) == + CONTENT_SETTING_NUM_SETTINGS, + "kPermissionButtonTextIDPolicyManaged array size is incorrect"); + +// The resource IDs for the strings that are displayed on the permissions +// button if the permission setting is managed by an extension. +const int kPermissionButtonTextIDExtensionManaged[] = { + kInvalidResourceID, + IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_EXTENSION, + IDS_PAGE_INFO_PERMISSION_BLOCKED_BY_EXTENSION, + IDS_PAGE_INFO_PERMISSION_ASK_BY_EXTENSION, + kInvalidResourceID, + kInvalidResourceID}; +static_assert(arraysize(kPermissionButtonTextIDExtensionManaged) == + CONTENT_SETTING_NUM_SETTINGS, + "kPermissionButtonTextIDExtensionManaged array size is " + "incorrect"); + +// The resource IDs for the strings that are displayed on the permissions // button if the permission setting is managed by the user. const int kPermissionButtonTextIDUserManaged[] = { kInvalidResourceID, @@ -104,6 +131,34 @@ security_description->details = l10n_util::GetStringUTF16(details_id); return security_description; } + +// Gets the actual setting for a ContentSettingType, taking into account what +// the default setting value is and whether Html5ByDefault is enabled. +ContentSetting GetEffectiveSetting(Profile* profile, + ContentSettingsType type, + ContentSetting setting, + ContentSetting default_setting) { + ContentSetting effective_setting = setting; + if (effective_setting == CONTENT_SETTING_DEFAULT) + effective_setting = default_setting; + +#if BUILDFLAG(ENABLE_PLUGINS) + HostContentSettingsMap* host_content_settings_map = + HostContentSettingsMapFactory::GetForProfile(profile); + effective_setting = PluginsFieldTrial::EffectiveContentSetting( + host_content_settings_map, type, effective_setting); + + // Display the UI string for ASK instead of DETECT for HTML5 by Default. + // TODO(tommycli): Once HTML5 by Default is shipped and the feature flag + // is removed, just migrate the actual content setting to ASK. + if (PluginUtils::ShouldPreferHtmlOverPlugins(host_content_settings_map) && + effective_setting == CONTENT_SETTING_DETECT_IMPORTANT_CONTENT) { + effective_setting = CONTENT_SETTING_ASK; + } +#endif + return effective_setting; +} + } // namespace PageInfoUI::CookieInfo::CookieInfo() : allowed(-1), blocked(-1) {} @@ -215,25 +270,8 @@ ContentSetting setting, ContentSetting default_setting, content_settings::SettingSource source) { - ContentSetting effective_setting = setting; - if (effective_setting == CONTENT_SETTING_DEFAULT) - effective_setting = default_setting; - -#if BUILDFLAG(ENABLE_PLUGINS) - HostContentSettingsMap* host_content_settings_map = - HostContentSettingsMapFactory::GetForProfile(profile); - effective_setting = PluginsFieldTrial::EffectiveContentSetting( - host_content_settings_map, type, effective_setting); - - // Display the UI string for ASK instead of DETECT for HTML5 by Default. - // TODO(tommycli): Once HTML5 by Default is shipped and the feature flag - // is removed, just migrate the actual content setting to ASK. - if (PluginUtils::ShouldPreferHtmlOverPlugins(host_content_settings_map) && - effective_setting == CONTENT_SETTING_DETECT_IMPORTANT_CONTENT) { - effective_setting = CONTENT_SETTING_ASK; - } -#endif - + ContentSetting effective_setting = + GetEffectiveSetting(profile, type, setting, default_setting); const int* button_text_ids = NULL; switch (source) { case content_settings::SETTING_SOURCE_USER: @@ -274,13 +312,15 @@ Profile* profile, const PageInfoUI::PermissionInfo& permission, const GURL& url) { + ContentSetting effective_setting = GetEffectiveSetting( + profile, permission.type, permission.setting, permission.default_setting); int message_id = kInvalidResourceID; switch (permission.source) { case content_settings::SettingSource::SETTING_SOURCE_POLICY: - message_id = IDS_PAGE_INFO_PERMISSION_SET_BY_POLICY; + message_id = kPermissionButtonTextIDPolicyManaged[effective_setting]; break; case content_settings::SettingSource::SETTING_SOURCE_EXTENSION: - message_id = IDS_PAGE_INFO_PERMISSION_SET_BY_EXTENSION; + message_id = kPermissionButtonTextIDExtensionManaged[effective_setting]; break; default: break;
diff --git a/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc b/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc index 5d18b07..b731c917 100644 --- a/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc +++ b/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc
@@ -355,7 +355,7 @@ custom_search_type_match.keyword = ASCIIToUTF16("k"); custom_search_type_match.destination_url = GURL("https://www.dummyurl.com/search?q=fan&img=1"); - TemplateURL* template_url = + const TemplateURL* template_url = custom_search_type_match.GetTemplateURL(service, false); EXPECT_TRUE(template_url); EXPECT_TRUE(AutocompleteMatch::IsSearchType(custom_search_type_match.type));
diff --git a/chrome/browser/ui/search_engines/edit_search_engine_controller.cc b/chrome/browser/ui/search_engines/edit_search_engine_controller.cc index 9fa6623..d61e7e2 100644 --- a/chrome/browser/ui/search_engines/edit_search_engine_controller.cc +++ b/chrome/browser/ui/search_engines/edit_search_engine_controller.cc
@@ -88,7 +88,7 @@ TemplateURLService* template_url_service = TemplateURLServiceFactory::GetForProfile(profile_); - TemplateURL* existing = + const TemplateURL* existing = template_url_service->GetTemplateURLForKeyword(keyword_input); if (existing && (!edit_keyword_delegate_ || existing != template_url_)) { // An entry may have been added with the same keyword string while the
diff --git a/chrome/common/logging_chrome.cc b/chrome/common/logging_chrome.cc index e9e51b13..6a5d7f8 100644 --- a/chrome/common/logging_chrome.cc +++ b/chrome/common/logging_chrome.cc
@@ -69,6 +69,7 @@ // When true, this means that error dialogs should not be shown. bool dialogs_are_suppressed_ = false; +logging::ScopedLogAssertHandler* assert_handler_ = nullptr; // This should be true for exactly the period between the end of // InitChromeLogging() and the beginning of CleanupChromeLogging(). @@ -92,7 +93,10 @@ // silenced. To record a new error, pass the log string associated // with that error in the str parameter. MSVC_DISABLE_OPTIMIZE(); -void SilentRuntimeAssertHandler(const std::string& str) { +void SilentRuntimeAssertHandler(const char* file, + int line, + const base::StringPiece message, + const base::StringPiece stack_trace) { base::debug::BreakDebugger(); } MSVC_ENABLE_OPTIMIZE(); @@ -103,7 +107,8 @@ if (dialogs_are_suppressed_) return; - logging::SetLogAssertHandler(SilentRuntimeAssertHandler); + assert_handler_ = new logging::ScopedLogAssertHandler( + base::Bind(SilentRuntimeAssertHandler)); #if defined(OS_WIN) UINT new_flags = SEM_FAILCRITICALERRORS |
diff --git a/chrome/test/data/webui/md_bookmarks/reducers_test.js b/chrome/test/data/webui/md_bookmarks/reducers_test.js index fe66d9b3..1eb6e77 100644 --- a/chrome/test/data/webui/md_bookmarks/reducers_test.js +++ b/chrome/test/data/webui/md_bookmarks/reducers_test.js
@@ -89,7 +89,7 @@ }); test('deselects items when they are deleted', function() { - var nodeList = testTree(createFolder('0', [ + var nodeMap = testTree(createFolder('0', [ createFolder( '1', [ @@ -103,7 +103,7 @@ action = select(['2', '4', '5'], '4', false); selection = bookmarks.SelectionState.updateSelection(selection, action); - action = bookmarks.actions.removeBookmark('1', '0', 0, nodeList); + action = bookmarks.actions.removeBookmark('1', '0', 0, nodeMap); selection = bookmarks.SelectionState.updateSelection(selection, action); assertDeepEquals(['5'], normalizeSet(selection.items));
diff --git a/components/cdm/browser/media_drm_storage_impl.cc b/components/cdm/browser/media_drm_storage_impl.cc index bcebc5a..800c6275 100644 --- a/components/cdm/browser/media_drm_storage_impl.cc +++ b/components/cdm/browser/media_drm_storage_impl.cc
@@ -167,12 +167,18 @@ base::DictionaryValue* origin_dict = nullptr; // The origin string may contain dots. Do not use path expansion. storage_dict->GetDictionaryWithoutPathExpansion(origin_string_, &origin_dict); + + // This could happen if the profile is removed, but the device is still + // provisioned for the origin. In this case, just create a new entry. if (!origin_dict) { - DVLOG(1) << __func__ - << ": Failed to save persistent session data; entry for origin " - << origin_string_ << " does not exist."; - callback.Run(false); - return; + + DVLOG(1) << __func__ << ": Entry for origin " << origin_string_ + << " does not exist; create a new one."; + storage_dict->SetWithoutPathExpansion(origin_string_, + CreateOriginDictionary()); + storage_dict->GetDictionaryWithoutPathExpansion(origin_string_, + &origin_dict); + DCHECK(origin_dict); } base::DictionaryValue* sessions_dict = nullptr;
diff --git a/components/cdm/browser/media_drm_storage_impl_unittest.cc b/components/cdm/browser/media_drm_storage_impl_unittest.cc index 6a1610e..daf0c8f6 100644 --- a/components/cdm/browser/media_drm_storage_impl_unittest.cc +++ b/components/cdm/browser/media_drm_storage_impl_unittest.cc
@@ -143,7 +143,7 @@ } TEST_F(MediaDrmStorageImplTest, SaveSession_Unprovisioned) { - SavePersistentSession("session_id", {1, 0}, "mime/type", false); + SaveAndLoadPersistentSession("session_id", {1, 0}, "mime/type1"); base::RunLoop().RunUntilIdle(); }
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc b/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc index 4e5dcf9c..3bbfb38c 100644 --- a/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc +++ b/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
@@ -33,6 +33,7 @@ #include "net/proxy/proxy_info.h" #include "net/proxy/proxy_retry_info.h" #include "net/socket/socket_test_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_test_util.h" @@ -110,8 +111,9 @@ std::unique_ptr<net::URLRequest> CreateRequest( bool is_main_frame, content::PreviewsState previews_state) { - std::unique_ptr<net::URLRequest> request = context_.CreateRequest( - GURL("http://www.google.com/"), net::IDLE, &delegate_); + std::unique_ptr<net::URLRequest> request = + context_.CreateRequest(GURL("http://www.google.com/"), net::IDLE, + &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS); AllocateRequestInfoForTesting( request.get(), (is_main_frame ? content::RESOURCE_TYPE_MAIN_FRAME @@ -124,10 +126,10 @@ content::ResourceType resource_type, bool scheme_is_https, content::PreviewsState previews_state) { - std::unique_ptr<net::URLRequest> request = - context_.CreateRequest(GURL(scheme_is_https ? "https://www.google.com/" - : "http://www.google.com/"), - net::IDLE, &delegate_); + std::unique_ptr<net::URLRequest> request = context_.CreateRequest( + GURL(scheme_is_https ? "https://www.google.com/" + : "http://www.google.com/"), + net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS); AllocateRequestInfoForTesting(request.get(), resource_type, previews_state); return request; }
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc b/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc index e42be3d..52d6503 100644 --- a/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc +++ b/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc
@@ -20,6 +20,7 @@ #include "content/public/common/previews_state.h" #include "content/public/test/test_renderer_host.h" #include "net/socket/socket_test_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -66,8 +67,9 @@ EXPECT_TRUE( content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - std::unique_ptr<net::URLRequest> request = context.CreateRequest( - GURL("http://www.google.com/"), net::IDLE, delegate); + std::unique_ptr<net::URLRequest> request = + context.CreateRequest(GURL("http://www.google.com/"), net::IDLE, + delegate, TRAFFIC_ANNOTATION_FOR_TESTS); content::ResourceRequestInfo::AllocateForTesting( request.get(), content::RESOURCE_TYPE_SUB_FRAME, NULL,
diff --git a/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc b/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc index 099aab5..1c65f26 100644 --- a/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc +++ b/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc
@@ -19,6 +19,7 @@ #include "content/public/browser/resource_request_info.h" #include "content/public/common/previews_state.h" #include "net/socket/socket_test_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_test_util.h" @@ -109,8 +110,8 @@ std::unique_ptr<net::URLRequest> CreateRequestByType( const GURL& gurl, content::ResourceType resource_type) { - std::unique_ptr<net::URLRequest> request = - context_.CreateRequest(gurl, net::IDLE, &delegate_); + std::unique_ptr<net::URLRequest> request = context_.CreateRequest( + gurl, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS); AllocateRequestInfoForTesting(request.get(), resource_type); return request; }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc index e44a9c2..f083a5b 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
@@ -37,6 +37,7 @@ #include "net/proxy/proxy_server.h" #include "net/proxy/proxy_service.h" #include "net/socket/socket_test_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" @@ -237,7 +238,8 @@ network_delegate_->headers_received_count(); TestDelegate d; std::unique_ptr<URLRequest> r(context_->CreateRequest( - GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, &d)); + GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, &d, + TRAFFIC_ANNOTATION_FOR_TESTS)); r->set_method(method); r->SetLoadFlags(net::LOAD_NORMAL); @@ -340,7 +342,8 @@ }; for (size_t i = 0; i < arraysize(tests); ++i) { std::unique_ptr<net::URLRequest> request(context.CreateRequest( - GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, NULL)); + GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, NULL, + TRAFFIC_ANNOTATION_FOR_TESTS)); request->set_method(tests[i].method); EXPECT_EQ(tests[i].expected_result, util::IsMethodIdempotent(request->method())); @@ -876,8 +879,9 @@ mock_socket_factory()->AddSocketDataProvider(&retry_socket); net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> url_request(context()->CreateRequest( - GURL("http://www.google.com"), net::IDLE, &delegate)); + std::unique_ptr<net::URLRequest> url_request( + context()->CreateRequest(GURL("http://www.google.com"), net::IDLE, + &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); url_request->Start(); drp_test_context()->RunUntilIdle(); @@ -935,8 +939,9 @@ base::HistogramTester histogram_tester; net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> request(context()->CreateRequest( - GURL("http://google.com"), net::IDLE, &delegate)); + std::unique_ptr<net::URLRequest> request( + context()->CreateRequest(GURL("http://google.com"), net::IDLE, + &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); request->Start(); drp_test_context()->RunUntilIdle(); @@ -971,7 +976,8 @@ TestDelegate d; std::unique_ptr<URLRequest> r(context_->CreateRequest( - GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, &d)); + GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, &d, + TRAFFIC_ANNOTATION_FOR_TESTS)); r->set_method("GET"); r->SetLoadFlags(net::LOAD_NORMAL);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc index cd7ddb4..c8922c5 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
@@ -40,6 +40,7 @@ #include "net/http/http_util.h" #include "net/proxy/proxy_server.h" #include "net/socket/socket_test_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_storage.h" @@ -80,14 +81,15 @@ test_context_ = DataReductionProxyTestContext::Builder().WithMockConfig().Build(); - mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_); + mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_, + TRAFFIC_ANNOTATION_FOR_TESTS); } std::unique_ptr<net::URLRequest> CreateURLRequestWithResponseHeaders( const GURL& url, const std::string& response_headers) { - std::unique_ptr<net::URLRequest> fake_request = - context_.CreateRequest(url, net::IDLE, &delegate_); + std::unique_ptr<net::URLRequest> fake_request = context_.CreateRequest( + url, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS); // Create a test job that will fill in the given response headers for the // |fake_request|. @@ -326,8 +328,8 @@ retry_socket_data_provider.get()); } - std::unique_ptr<net::URLRequest> request( - context_.CreateRequest(url, net::IDLE, &delegate_)); + std::unique_ptr<net::URLRequest> request(context_.CreateRequest( + url, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS)); request->set_method("GET"); request->SetLoadFlags(load_flags); request->Start(); @@ -385,7 +387,8 @@ mock_socket_factory_.AddSocketDataProvider(&response_socket_data_provider); std::unique_ptr<net::URLRequest> request( - context_.CreateRequest(GURL("http://foo.com"), net::IDLE, &delegate_)); + context_.CreateRequest(GURL("http://foo.com"), net::IDLE, &delegate_, + TRAFFIC_ANNOTATION_FOR_TESTS)); request->set_method("GET"); request->Start(); drp_test_context_->RunUntilIdle();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc index 1a5cffc..f301943 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
@@ -35,6 +35,7 @@ #include "net/http/http_response_headers.h" #include "net/proxy/proxy_server.h" #include "net/socket/socket_test_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_context_storage.h" #include "net/url_request/url_request_test_util.h" #include "testing/gmock/include/gmock/gmock.h" @@ -1091,8 +1092,9 @@ net::TestDelegate test_delegate; std::unique_ptr<net::URLRequest> request( - test_url_request_context()->CreateRequest(GURL(tests[i].url), net::IDLE, - &test_delegate)); + test_url_request_context()->CreateRequest( + GURL(tests[i].url), net::IDLE, &test_delegate, + TRAFFIC_ANNOTATION_FOR_TESTS)); request->Start(); RunUntilIdle();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index f70b5e70..2b55df8b 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -49,6 +49,7 @@ #include "net/nqe/network_quality_estimator_test_util.h" #include "net/proxy/proxy_server.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request.h" @@ -916,8 +917,8 @@ base::HistogramTester histogram_tester; net::TestURLRequestContext context_; net::TestDelegate delegate_; - std::unique_ptr<net::URLRequest> request = - context_.CreateRequest(GURL(), net::IDLE, &delegate_); + std::unique_ptr<net::URLRequest> request = context_.CreateRequest( + GURL(), net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS); request->SetLoadFlags(request->load_flags() | net::LOAD_MAIN_FRAME_DEPRECATED); bool should_enable_lofi = config()->ShouldEnableLoFi(*request.get());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc index 4ace1e8..5ee76c7 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc
@@ -12,6 +12,7 @@ #include "base/message_loop/message_loop.h" #include "net/base/request_priority.h" #include "net/nqe/effective_connection_type.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "testing/gtest/include/gtest/gtest.h" @@ -65,7 +66,8 @@ TEST_F(DataReductionProxyDataTest, AddToURLRequest) { std::unique_ptr<net::URLRequestContext> context(new net::URLRequestContext()); std::unique_ptr<net::URLRequest> fake_request(context->CreateRequest( - GURL("http://www.google.com"), net::RequestPriority::IDLE, nullptr)); + GURL("http://www.google.com"), net::RequestPriority::IDLE, nullptr, + TRAFFIC_ANNOTATION_FOR_TESTS)); DataReductionProxyData* data = DataReductionProxyData::GetData(*fake_request.get()); EXPECT_FALSE(data); @@ -122,7 +124,8 @@ TEST_F(DataReductionProxyDataTest, ClearData) { std::unique_ptr<net::URLRequestContext> context(new net::URLRequestContext()); std::unique_ptr<net::URLRequest> fake_request(context->CreateRequest( - GURL("http://www.google.com"), net::RequestPriority::IDLE, nullptr)); + GURL("http://www.google.com"), net::RequestPriority::IDLE, nullptr, + TRAFFIC_ANNOTATION_FOR_TESTS)); DataReductionProxyData* data = DataReductionProxyData::GetDataAndCreateIfNecessary(fake_request.get());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc index f7a2306..0969234 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
@@ -51,6 +51,7 @@ #include "net/proxy/proxy_config.h" #include "net/proxy/proxy_server.h" #include "net/socket/socket_test_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -658,8 +659,8 @@ mock_socket_factory_.AddSocketDataProvider(&socket); net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> request = - context_.CreateRequest(url, net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> request = context_.CreateRequest( + url, net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); if (request_headers) request->SetExtraRequestHeaders(*request_headers); @@ -1037,8 +1038,9 @@ mock_socket_factory()->AddSocketDataProvider(&socket); net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> request = context()->CreateRequest( - GURL("http://example.com/path/"), net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> request = + context()->CreateRequest(GURL("http://example.com/path/"), net::IDLE, + &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); request->Start(); base::RunLoop().RunUntilIdle(); @@ -1058,8 +1060,9 @@ mock_socket_factory()->AddSocketDataProvider(&socket); net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> request = context()->CreateRequest( - GURL("http://example.com/path/"), net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> request = + context()->CreateRequest(GURL("http://example.com/path/"), net::IDLE, + &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); request->Start(); base::RunLoop().RunUntilIdle(); @@ -1150,8 +1153,9 @@ mock_socket_factory()->AddSocketDataProvider(&socket); net::TestDelegate test_delegate; - std::unique_ptr<net::URLRequest> request = context()->CreateRequest( - GURL("http://example.com"), net::IDLE, &test_delegate); + std::unique_ptr<net::URLRequest> request = + context()->CreateRequest(GURL("http://example.com"), net::IDLE, + &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS); request->Start(); base::RunLoop().RunUntilIdle();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc index 4d8f088..4497aeb 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
@@ -32,6 +32,7 @@ #include "net/proxy/proxy_server.h" #include "net/socket/socket_test_util.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context_storage.h" #include "net/url_request/url_request_intercepting_job_factory.h" @@ -172,8 +173,9 @@ Init(std::move(factory1)); net::TestDelegate d; - std::unique_ptr<net::URLRequest> req(default_context_->CreateRequest( - GURL("http://foo"), net::DEFAULT_PRIORITY, &d)); + std::unique_ptr<net::URLRequest> req( + default_context_->CreateRequest(GURL("http://foo"), net::DEFAULT_PRIORITY, + &d, TRAFFIC_ANNOTATION_FOR_TESTS)); req->Start(); base::RunLoop().Run(); @@ -262,7 +264,8 @@ // DataReductionProxyProtocolTest. net::TestDelegate delegate; std::unique_ptr<net::URLRequest> request(context().CreateRequest( - direct().GetURL("/block10.html"), net::DEFAULT_PRIORITY, &delegate)); + direct().GetURL("/block10.html"), net::DEFAULT_PRIORITY, &delegate, + TRAFFIC_ANNOTATION_FOR_TESTS)); request->Start(); EXPECT_TRUE(request->is_pending()); base::RunLoop().Run(); @@ -274,7 +277,8 @@ TEST_F(DataReductionProxyInterceptorWithServerTest, TestNoBypass) { net::TestDelegate delegate; std::unique_ptr<net::URLRequest> request(context().CreateRequest( - direct().GetURL("/noblock.html"), net::DEFAULT_PRIORITY, &delegate)); + direct().GetURL("/noblock.html"), net::DEFAULT_PRIORITY, &delegate, + TRAFFIC_ANNOTATION_FOR_TESTS)); request->Start(); EXPECT_TRUE(request->is_pending()); base::RunLoop().Run(); @@ -312,8 +316,8 @@ // Creates a URLRequest using the test's TestURLRequestContext and executes // it. Returns the created URLRequest. std::unique_ptr<net::URLRequest> CreateAndExecuteRequest(const GURL& url) { - std::unique_ptr<net::URLRequest> request( - context_.CreateRequest(url, net::IDLE, &delegate_)); + std::unique_ptr<net::URLRequest> request(context_.CreateRequest( + url, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS)); request->Start(); drp_test_context_->RunUntilIdle(); return request;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc index 7b09403..67deac59 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -27,6 +27,7 @@ #include "net/log/net_log_with_source.h" #include "net/proxy/proxy_info.h" #include "net/proxy/proxy_service.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_interceptor.h" @@ -123,8 +124,9 @@ // When creating a network delegate, expect that it properly wraps a // network delegate. Such a network delegate is thoroughly tested by // DataReductionProxyNetworkDelegateTest. - std::unique_ptr<net::URLRequest> fake_request = context().CreateRequest( - GURL("http://www.foo.com/"), net::IDLE, delegate()); + std::unique_ptr<net::URLRequest> fake_request = + context().CreateRequest(GURL("http://www.foo.com/"), net::IDLE, + delegate(), TRAFFIC_ANNOTATION_FOR_TESTS); CountingNetworkDelegate* wrapped_network_delegate = new CountingNetworkDelegate(); std::unique_ptr<DataReductionProxyNetworkDelegate> network_delegate =
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc index 756102e..00a4da1f 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -57,6 +57,7 @@ #include "net/test/cert_test_util.h" #include "net/test/gtest_util.h" #include "net/test/test_data_directory.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_job_factory_impl.h" #include "net/url_request/url_request_status.h" @@ -320,8 +321,8 @@ mock_socket_factory_.AddSocketDataProvider(&socket); net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> request = - context_.CreateRequest(url, net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> request = context_.CreateRequest( + url, net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); if (request_headers) request->SetExtraRequestHeaders(*request_headers); request->SetLoadFlags(request->load_flags() | load_flags); @@ -429,8 +430,8 @@ mock_socket_factory_.AddSocketDataProvider(&socket); net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> request = - context_.CreateRequest(url, net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> request = context_.CreateRequest( + url, net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); if (request_headers) request->SetExtraRequestHeaders(*request_headers); @@ -706,8 +707,8 @@ net::ProxyRetryInfoMap proxy_retry_info; net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> fake_request = - context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest( + GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); fake_request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED); lofi_decider()->SetIsUsingLoFi( config()->ShouldEnableLoFi(*fake_request.get())); @@ -725,8 +726,8 @@ net::HttpRequestHeaders headers; net::ProxyRetryInfoMap proxy_retry_info; net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> fake_request = - context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest( + GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); lofi_decider()->SetIsUsingLoFi(false); NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info, proxy_retry_info, &headers); @@ -740,8 +741,8 @@ net::HttpRequestHeaders headers; net::ProxyRetryInfoMap proxy_retry_info; net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> fake_request = - context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest( + GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); lofi_decider()->SetIsUsingLoFi(true); NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info, @@ -757,8 +758,8 @@ net::HttpRequestHeaders headers; net::ProxyRetryInfoMap proxy_retry_info; net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> fake_request = - context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest( + GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); fake_request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED); lofi_decider()->SetIsUsingLoFi(false); NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info, @@ -773,8 +774,8 @@ net::HttpRequestHeaders headers; net::ProxyRetryInfoMap proxy_retry_info; net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> fake_request = - context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest( + GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); lofi_decider()->SetIsUsingLoFi(false); NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info, proxy_retry_info, &headers); @@ -788,8 +789,8 @@ net::HttpRequestHeaders headers; net::ProxyRetryInfoMap proxy_retry_info; net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> fake_request = - context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate); + std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest( + GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); fake_request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED); lofi_decider()->SetIsUsingLoFi( config()->ShouldEnableLoFi(*fake_request.get())); @@ -844,8 +845,9 @@ test_network_quality_estimator()->set_effective_connection_type( net::EFFECTIVE_CONNECTION_TYPE_OFFLINE); - std::unique_ptr<net::URLRequest> request = context()->CreateRequest( - GURL(kTestURL), net::RequestPriority::IDLE, nullptr); + std::unique_ptr<net::URLRequest> request = + context()->CreateRequest(GURL(kTestURL), net::RequestPriority::IDLE, + nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); request->SetLoadFlags(test.main_frame ? net::LOAD_MAIN_FRAME_DEPRECATED : 0); lofi_decider()->SetIsUsingLoFi(test.lofi_on); @@ -907,8 +909,9 @@ else data_reduction_proxy_info.UseNamedProxy("some.other.proxy"); config()->UpdateConfigForTesting(test.data_reduction_proxy_enabled, true); - std::unique_ptr<net::URLRequest> request = context()->CreateRequest( - GURL(kTestURL), net::RequestPriority::IDLE, nullptr); + std::unique_ptr<net::URLRequest> request = + context()->CreateRequest(GURL(kTestURL), net::RequestPriority::IDLE, + nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); request->set_method("GET"); net::HttpRequestHeaders headers; net::ProxyRetryInfoMap proxy_retry_info; @@ -939,8 +942,9 @@ test_network_quality_estimator()->set_effective_connection_type( net::EFFECTIVE_CONNECTION_TYPE_OFFLINE); - std::unique_ptr<net::URLRequest> request = context()->CreateRequest( - GURL(kTestURL), net::RequestPriority::IDLE, nullptr); + std::unique_ptr<net::URLRequest> request = + context()->CreateRequest(GURL(kTestURL), net::RequestPriority::IDLE, + nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED); lofi_decider()->SetIsUsingLoFi(true); io_data()->request_options()->SetSecureSession("fake-session");
diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc index 9ecda9b5..99c97ab7 100644 --- a/components/favicon/core/favicon_handler.cc +++ b/components/favicon/core/favicon_handler.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/memory/ref_counted_memory.h" +#include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "components/favicon/core/favicon_service.h" #include "components/favicon_base/favicon_util.h" @@ -59,6 +60,30 @@ return bitmap_result.is_valid(); } +void RecordDownloadAttemptsForHandlerType( + FaviconDriverObserver::NotificationIconType handler_type, + int attempts) { + // If not at least one attempts was recorded or more than 15 attempts were + // registered, something went wrong. Underflows are stored in bucket 0 and + // overflows in bucket 16. + attempts = std::max(0, std::min(attempts, 16)); + switch (handler_type) { + case FaviconDriverObserver::NON_TOUCH_16_DIP: + UMA_HISTOGRAM_SPARSE_SLOWLY("Favicons.DownloadAttempts.Favicons", + attempts); + return; + case FaviconDriverObserver::NON_TOUCH_LARGEST: + UMA_HISTOGRAM_SPARSE_SLOWLY("Favicons.DownloadAttempts.LargeIcons", + attempts); + return; + case FaviconDriverObserver::TOUCH_LARGEST: + UMA_HISTOGRAM_SPARSE_SLOWLY("Favicons.DownloadAttempts.TouchIcons", + attempts); + return; + } + NOTREACHED(); +} + // Returns true if |bitmap_results| is non-empty and: // - At least one of the bitmaps in |bitmap_results| is expired // OR @@ -167,6 +192,7 @@ notification_icon_type_(favicon_base::INVALID_ICON), service_(service), delegate_(delegate), + num_download_requests_(0), current_candidate_index_(0u) { DCHECK(delegate_); } @@ -199,6 +225,7 @@ candidates_.clear(); notification_icon_url_ = GURL(); notification_icon_type_ = favicon_base::INVALID_ICON; + num_download_requests_ = 0; current_candidate_index_ = 0u; best_favicon_ = DownloadedFavicon(); @@ -308,6 +335,7 @@ download_request_.Cancel(); candidates_ = std::move(sorted_candidates); + num_download_requests_ = 0; current_candidate_index_ = 0u; best_favicon_ = DownloadedFavicon(); @@ -395,6 +423,9 @@ ++current_candidate_index_; DownloadCurrentCandidateOrAskFaviconService(); } else { + // OnDidDownloadFavicon() can only be called after requesting a download, so + // |num_download_requests_| can never be 0. + RecordDownloadAttemptsForHandlerType(handler_type_, num_download_requests_); // We have either found the ideal candidate or run out of candidates. if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) { // No more icons to request, set the favicon from the candidate. @@ -403,6 +434,7 @@ } // Clear download related state. current_candidate_index_ = candidates_.size(); + num_download_requests_ = 0; best_favicon_ = DownloadedFavicon(); } } @@ -513,6 +545,8 @@ if (has_expired_or_incomplete_result) { ScheduleDownload(current_candidate()->icon_url, current_candidate()->icon_type); + } else if (num_download_requests_ > 0) { + RecordDownloadAttemptsForHandlerType(handler_type_, num_download_requests_); } } @@ -527,6 +561,7 @@ std::vector<gfx::Size>()); return; } + ++num_download_requests_; download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this), icon_type)); // A max bitmap size is specified to avoid receiving huge bitmaps in
diff --git a/components/favicon/core/favicon_handler.h b/components/favicon/core/favicon_handler.h index 9105723c..24d849e0 100644 --- a/components/favicon/core/favicon_handler.h +++ b/components/favicon/core/favicon_handler.h
@@ -290,6 +290,10 @@ // This handler's delegate. Delegate* delegate_; + // Captures the number of download requests that were initiated for the + // current url_. + int num_download_requests_; + // The index of the favicon URL in |image_urls_| which is currently being // requested from history or downloaded. size_t current_candidate_index_;
diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc index 5e651a64..e855508 100644 --- a/components/favicon/core/favicon_handler_unittest.cc +++ b/components/favicon/core/favicon_handler_unittest.cc
@@ -16,6 +16,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/test/histogram_tester.h" #include "components/favicon/core/favicon_driver.h" #include "components/favicon/core/test/mock_favicon_service.h" #include "testing/gmock/include/gmock/gmock.h" @@ -78,20 +79,21 @@ std::vector<FaviconRawBitmapResult> CreateRawBitmapResult( const GURL& icon_url, favicon_base::IconType icon_type = FAVICON, - bool expired = false) { + bool expired = false, + int edge_size = gfx::kFaviconSize) { scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); - data->data() = FillBitmapWithEdgeSize(gfx::kFaviconSize); + data->data() = FillBitmapWithEdgeSize(edge_size); FaviconRawBitmapResult bitmap_result; bitmap_result.expired = expired; bitmap_result.bitmap_data = data; // Use a pixel size other than (0,0) as (0,0) has a special meaning. - bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); + bitmap_result.pixel_size = gfx::Size(edge_size, edge_size); bitmap_result.icon_type = icon_type; bitmap_result.icon_url = icon_url; return {bitmap_result}; } -// Fake that implements the calls to FaviconHalder::Delegate's DownloadImage(), +// Fake that implements the calls to FaviconHandler::Delegate's DownloadImage(), // delegated to this class through MockDelegate. class FakeImageDownloader { public: @@ -382,6 +384,7 @@ }; TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { + base::HistogramTester histogram_tester; const GURL kIconURL("http://www.google.com/favicon"); favicon_service_.fake()->Store(kPageURL, kIconURL, @@ -393,6 +396,12 @@ RunHandlerWithSimpleFaviconCandidates({kIconURL}); EXPECT_THAT(delegate_.downloads(), IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), + IsEmpty()); } // Test that UpdateFaviconsAndFetch() is called with the appropriate parameters @@ -535,15 +544,12 @@ // - The icon is redownloaded. TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { // Set non empty but invalid data. - FaviconRawBitmapResult bitmap_result; - bitmap_result.expired = false; + std::vector<FaviconRawBitmapResult> bitmap_result = + CreateRawBitmapResult(kIconURL16x16); // Empty bitmap data is invalid. - bitmap_result.bitmap_data = new base::RefCountedBytes(); - bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); - bitmap_result.icon_type = FAVICON; - bitmap_result.icon_url = kIconURL16x16; + bitmap_result[0].bitmap_data = new base::RefCountedBytes(); - favicon_service_.fake()->Store(kPageURL, kIconURL16x16, {bitmap_result}); + favicon_service_.fake()->Store(kPageURL, kIconURL16x16, bitmap_result); // TODO(crbug.com/700811): It would be nice if we could check the image // being published to rule out invalid data. @@ -1031,5 +1037,116 @@ FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); } +TEST_F(FaviconHandlerTest, TestRecordMultipleDownloadAttempts) { + base::HistogramTester histogram_tester; + + // Try to download the three failing icons and end up logging three attempts. + RunHandlerWithCandidates( + FaviconDriverObserver::NON_TOUCH_LARGEST, + {FaviconURL(GURL("http://www.google.com/a"), FAVICON, kEmptySizes), + FaviconURL(GURL("http://www.google.com/b"), FAVICON, kEmptySizes), + FaviconURL(GURL("http://www.google.com/c"), FAVICON, kEmptySizes)}); + + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), + ElementsAre(base::Bucket(/*sample=*/3, /*expected_count=*/1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), + IsEmpty()); +} + +TEST_F(FaviconHandlerTest, TestRecordSingleFaviconDownloadAttempt) { + base::HistogramTester histogram_tester; + + RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); + + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), + ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), + IsEmpty()); +} + +TEST_F(FaviconHandlerTest, TestRecordSingleLargeIconDownloadAttempt) { + base::HistogramTester histogram_tester; + + RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_LARGEST, + {FaviconURL(kIconURL64x64, FAVICON, kEmptySizes)}); + + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), + ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), + IsEmpty()); +} + +TEST_F(FaviconHandlerTest, TestRecordSingleTouchIconDownloadAttempt) { + base::HistogramTester histogram_tester; + RunHandlerWithCandidates( + FaviconDriverObserver::TOUCH_LARGEST, + {FaviconURL(kIconURL64x64, TOUCH_ICON, kEmptySizes)}); + + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), + ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); +} + +TEST_F(FaviconHandlerTest, TestRecordDownloadAttemptsFinishedByCache) { + const GURL kIconURL1024x1024("http://www.google.com/a-404-ing-icon"); + base::HistogramTester histogram_tester; + favicon_service_.fake()->Store( + GURL("http://so.de"), kIconURL64x64, + CreateRawBitmapResult(kIconURL64x64, FAVICON, /*expired=*/false, 64)); + + RunHandlerWithCandidates( + FaviconDriverObserver::NON_TOUCH_LARGEST, + {FaviconURL(kIconURL1024x1024, FAVICON, {gfx::Size(1024, 1024)}), + FaviconURL(kIconURL12x12, FAVICON, {gfx::Size(12, 12)}), + FaviconURL(kIconURL64x64, FAVICON, {gfx::Size(64, 64)})}); + + // Should try only the first (receive 404) and get second icon from cache. + EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL1024x1024)); + + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), + ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), + IsEmpty()); +} + +TEST_F(FaviconHandlerTest, TestRecordSingleDownloadAttemptForRefreshingIcons) { + base::HistogramTester histogram_tester; + favicon_service_.fake()->Store( + GURL("http://www.google.com/ps"), kIconURL16x16, + CreateRawBitmapResult(kIconURL16x16, FAVICON, /*expired=*/true)); + + RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); + + EXPECT_THAT( + histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), + ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); +} + } // namespace } // namespace favicon
diff --git a/components/network_session_configurator/network_session_configurator.cc b/components/network_session_configurator/network_session_configurator.cc index a0432839..4bb6f77 100644 --- a/components/network_session_configurator/network_session_configurator.cc +++ b/components/network_session_configurator/network_session_configurator.cc
@@ -134,12 +134,34 @@ return net::ParseQuicConnectionOptions(it->second); } +float GetQuicLoadServerInfoTimeoutSrttMultiplier( + const VariationParameters& quic_trial_params) { + double value; + if (base::StringToDouble( + GetVariationParam(quic_trial_params, "load_server_info_time_to_srtt"), + &value)) { + return static_cast<float>(value); + } + return 0.0f; +} + +bool ShouldQuicEnableConnectionRacing( + const VariationParameters& quic_trial_params) { + return base::LowerCaseEqualsASCII( + GetVariationParam(quic_trial_params, "enable_connection_racing"), "true"); +} + bool ShouldQuicEnableNonBlockingIO( const VariationParameters& quic_trial_params) { return base::LowerCaseEqualsASCII( GetVariationParam(quic_trial_params, "enable_non_blocking_io"), "true"); } +bool ShouldQuicDisableDiskCache(const VariationParameters& quic_trial_params) { + return base::LowerCaseEqualsASCII( + GetVariationParam(quic_trial_params, "disable_disk_cache"), "true"); +} + bool ShouldForceHolBlocking(const VariationParameters& quic_trial_params) { return base::LowerCaseEqualsASCII( GetVariationParam(quic_trial_params, "force_hol_blocking"), "true"); @@ -273,8 +295,18 @@ ShouldRetryWithoutAltSvcOnQuicErrors(quic_trial_params); if (params->enable_quic) { + float load_server_info_timeout_srtt_multiplier = + GetQuicLoadServerInfoTimeoutSrttMultiplier(quic_trial_params); + if (load_server_info_timeout_srtt_multiplier != 0) { + params->quic_load_server_info_timeout_srtt_multiplier = + load_server_info_timeout_srtt_multiplier; + } + params->quic_enable_connection_racing = + ShouldQuicEnableConnectionRacing(quic_trial_params); params->quic_enable_non_blocking_io = ShouldQuicEnableNonBlockingIO(quic_trial_params); + params->quic_disable_disk_cache = + ShouldQuicDisableDiskCache(quic_trial_params); params->quic_force_hol_blocking = ShouldForceHolBlocking(quic_trial_params); params->quic_connection_options = GetQuicConnectionOptions(quic_trial_params);
diff --git a/components/network_session_configurator/network_session_configurator_unittest.cc b/components/network_session_configurator/network_session_configurator_unittest.cc index b9a21af..0a52ae01 100644 --- a/components/network_session_configurator/network_session_configurator_unittest.cc +++ b/components/network_session_configurator/network_session_configurator_unittest.cc
@@ -70,8 +70,11 @@ EXPECT_FALSE(params_.retry_without_alt_svc_on_quic_errors); EXPECT_EQ(1350u, params_.quic_max_packet_length); EXPECT_EQ(net::QuicTagVector(), params_.quic_connection_options); + EXPECT_EQ(0.25f, params_.quic_load_server_info_timeout_srtt_multiplier); + EXPECT_FALSE(params_.quic_enable_connection_racing); EXPECT_FALSE(params_.enable_server_push_cancellation); EXPECT_FALSE(params_.quic_enable_non_blocking_io); + EXPECT_FALSE(params_.quic_disable_disk_cache); EXPECT_FALSE(params_.quic_close_sessions_on_ip_change); EXPECT_EQ(net::kIdleConnectionTimeoutSeconds, params_.quic_idle_connection_timeout_seconds); @@ -336,6 +339,29 @@ EXPECT_EQ(expected_settings, params_.http2_settings); } +TEST_F(NetworkSessionConfiguratorTest, + QuicLoadServerInfoTimeToSmoothedRttFromFieldTrialParams) { + std::map<std::string, std::string> field_trial_params; + field_trial_params["load_server_info_time_to_srtt"] = "0.5"; + variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); + + ParseFieldTrials(); + + EXPECT_EQ(0.5f, params_.quic_load_server_info_timeout_srtt_multiplier); +} + +TEST_F(NetworkSessionConfiguratorTest, QuicEnableConnectionRacing) { + std::map<std::string, std::string> field_trial_params; + field_trial_params["enable_connection_racing"] = "true"; + variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); + + ParseFieldTrials(); + + EXPECT_TRUE(params_.quic_enable_connection_racing); +} + TEST_F(NetworkSessionConfiguratorTest, QuicEnableNonBlockingIO) { std::map<std::string, std::string> field_trial_params; field_trial_params["enable_non_blocking_io"] = "true"; @@ -347,6 +373,17 @@ EXPECT_TRUE(params_.quic_enable_non_blocking_io); } +TEST_F(NetworkSessionConfiguratorTest, QuicDisableDiskCache) { + std::map<std::string, std::string> field_trial_params; + field_trial_params["disable_disk_cache"] = "true"; + variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); + + ParseFieldTrials(); + + EXPECT_TRUE(params_.quic_disable_disk_cache); +} + TEST_F(NetworkSessionConfiguratorTest, TCPFastOpenHttpsEnabled) { base::FieldTrialList::CreateFieldTrial("TCPFastOpen", "HttpsEnabled");
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc index bfc64f94..d251027 100644 --- a/components/omnibox/browser/autocomplete_controller.cc +++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -430,7 +430,7 @@ void AutocompleteController::UpdateMatchDestinationURL( const TemplateURLRef::SearchTermsArgs& search_terms_args, AutocompleteMatch* match) const { - TemplateURL* template_url = match->GetTemplateURL( + const TemplateURL* template_url = match->GetTemplateURL( template_url_service_, false); if (!template_url) return;
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index 801b0d7..0056537 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc
@@ -435,7 +435,7 @@ // to eliminate cases like past search URLs from history that differ only // by some obscure query param from each other or from the search/keyword // provider matches. - TemplateURL* template_url = GetTemplateURLWithKeyword( + const TemplateURL* template_url = GetTemplateURLWithKeyword( template_url_service, keyword, stripped_destination_url.host()); if (template_url != NULL && template_url->SupportsReplacement(
diff --git a/components/omnibox/browser/base_search_provider.cc b/components/omnibox/browser/base_search_provider.cc index 618c483..8a331e7 100644 --- a/components/omnibox/browser/base_search_provider.cc +++ b/components/omnibox/browser/base_search_provider.cc
@@ -133,7 +133,7 @@ base::Unretained(this)))); } - TemplateURL* template_url = + const TemplateURL* template_url = match.GetTemplateURL(client_->GetTemplateURLService(), false); // This may be NULL if the template corresponding to the keyword has been // deleted or there is no keyword set.
diff --git a/components/omnibox/browser/omnibox_client.cc b/components/omnibox/browser/omnibox_client.cc index 7f85f44..0a9a332 100644 --- a/components/omnibox/browser/omnibox_client.cc +++ b/components/omnibox/browser/omnibox_client.cc
@@ -73,7 +73,7 @@ } bool OmniboxClient::ProcessExtensionKeyword( - TemplateURL* template_url, + const TemplateURL* template_url, const AutocompleteMatch& match, WindowOpenDisposition disposition, OmniboxNavigationObserver* observer) {
diff --git a/components/omnibox/browser/omnibox_client.h b/components/omnibox/browser/omnibox_client.h index 4d8cf2b..6b516e95 100644 --- a/components/omnibox/browser/omnibox_client.h +++ b/components/omnibox/browser/omnibox_client.h
@@ -97,7 +97,7 @@ // that was created by CreateOmniboxNavigationObserver() for |match|; in some // embedding contexts, processing an extension keyword involves invoking // action on this observer. - virtual bool ProcessExtensionKeyword(TemplateURL* template_url, + virtual bool ProcessExtensionKeyword(const TemplateURL* template_url, const AutocompleteMatch& match, WindowOpenDisposition disposition, OmniboxNavigationObserver* observer);
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp index 54e8336..f90b393d 100644 --- a/components/page_info_strings.grdp +++ b/components/page_info_strings.grdp
@@ -111,4 +111,27 @@ Certificate Information </message> </if> + + <!-- Content settings strings --> + <message name="IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_POLICY" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly allowed by the user's enterprise policy."> + Allowed by your administrator + </message> + <message name="IDS_PAGE_INFO_PERMISSION_BLOCKED_BY_POLICY" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly blocked by the user's enterprise policy."> + Blocked by your administrator + </message> + <message name="IDS_PAGE_INFO_PERMISSION_ASK_BY_POLICY" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly set to 'Ask' by the user's enterprise policy."> + Setting controlled by your administrator + </message> + <message name="IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_EXTENSION" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly allowed by one of the user's extensions."> + Allowed by an extension + </message> + <message name="IDS_PAGE_INFO_PERMISSION_BLOCKED_BY_EXTENSION" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly blocked by one of the user's extensions."> + Blocked by an extension + </message> + <message name="IDS_PAGE_INFO_PERMISSION_ASK_BY_EXTENSION" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly set to 'Ask' by one of the user's extensions."> + Setting controlled by an extension + </message> + <message name="IDS_PAGE_INFO_PERMISSION_AUTOMATICALLY_BLOCKED" desc="The label used underneath a permission listed in the Page Info bubble if the permission was blocked by Chrome on behalf of the user."> + Automatically blocked + </message> </grit-part>
diff --git a/components/precache/core/precache_manifest_util.cc b/components/precache/core/precache_manifest_util.cc index 668a77f..ab801f6 100644 --- a/components/precache/core/precache_manifest_util.cc +++ b/components/precache/core/precache_manifest_util.cc
@@ -36,19 +36,26 @@ if (it != resource_bitset_map.end()) { if (it->second.has_bitset()) { const std::string& bitset = it->second.bitset(); - ret.emplace(bitset.size() * 8); - for (size_t i = 0; i < bitset.size(); ++i) { - for (size_t j = 0; j < 8; ++j) { - if ((1 << j) & bitset[i]) - ret.value()[i * 8 + j] = true; + const int bitset_size = bitset.size() * 8; + DCHECK_GE(bitset_size, manifest.resource_size()); + if (bitset_size >= manifest.resource_size()) { + ret.emplace(bitset_size); + for (size_t i = 0; i < bitset.size(); ++i) { + for (size_t j = 0; j < 8; ++j) { + if ((1 << j) & bitset[i]) + ret.value()[i * 8 + j] = true; + } } } } else if (it->second.has_deprecated_bitset()) { uint64_t bitset = it->second.deprecated_bitset(); - ret.emplace(64); - for (int i = 0; i < 64; ++i) { - if ((0x1ULL << i) & bitset) - ret.value()[i] = true; + DCHECK_GE(64, manifest.resource_size()); + if (64 >= manifest.resource_size()) { + ret.emplace(64); + for (int i = 0; i < 64; ++i) { + if ((0x1ULL << i) & bitset) + ret.value()[i] = true; + } } } }
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index 1f687bf..dfce55d 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc
@@ -396,6 +396,13 @@ TemplateURL* TemplateURLService::GetTemplateURLForKeyword( const base::string16& keyword) { + return const_cast<TemplateURL*>( + static_cast<const TemplateURLService*>(this)-> + GetTemplateURLForKeyword(keyword)); +} + +const TemplateURL* TemplateURLService::GetTemplateURLForKeyword( + const base::string16& keyword) const { KeywordToTURLAndMeaningfulLength::const_iterator elem( keyword_to_turl_and_length_.find(keyword)); if (elem != keyword_to_turl_and_length_.end()) @@ -408,6 +415,13 @@ TemplateURL* TemplateURLService::GetTemplateURLForGUID( const std::string& sync_guid) { +return const_cast<TemplateURL*>( + static_cast<const TemplateURLService*>(this)-> + GetTemplateURLForGUID(sync_guid)); +} + +const TemplateURL* TemplateURLService::GetTemplateURLForGUID( + const std::string& sync_guid) const { GUIDToTURL::const_iterator elem(guid_to_turl_.find(sync_guid)); if (elem != guid_to_turl_.end()) return elem->second; @@ -419,6 +433,13 @@ TemplateURL* TemplateURLService::GetTemplateURLForHost( const std::string& host) { + return const_cast<TemplateURL*>( + static_cast<const TemplateURLService*>(this)-> + GetTemplateURLForHost(host)); +} + +const TemplateURL* TemplateURLService::GetTemplateURLForHost( + const std::string& host) const { if (loaded_) return provider_map_->GetTemplateURLForHost(host); TemplateURL* initial_dsp = initial_default_search_provider_.get(); @@ -840,10 +861,7 @@ base::string16 TemplateURLService::GetKeywordShortName( const base::string16& keyword, bool* is_omnibox_api_extension_keyword) const { - // TODO(jeffschiller): Make GetTemplateURLForKeyword const and remove the - // const_cast. - const TemplateURL* template_url = - const_cast<TemplateURLService*>(this)->GetTemplateURLForKeyword(keyword); + const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService // to track changes to the model, this should become a DCHECK. @@ -1253,7 +1271,7 @@ TemplateURLServiceClient* client, PrefService* prefs, const SearchTermsData& search_terms_data, - TemplateURL* existing_turl, + const TemplateURL* existing_turl, const syncer::SyncData& sync_data, syncer::SyncChangeList* change_list) { DCHECK(change_list); @@ -2220,10 +2238,7 @@ const TemplateURL* local_turl, const TemplateURL* sync_turl, bool prefer_local_default) const { - // TODO(jeffschiller): Make GetTemplateURLForKeyword const and remove the - // const_cast. - DCHECK(const_cast<TemplateURLService*>(this)->GetTemplateURLForGUID( - local_turl->sync_guid())); + DCHECK(GetTemplateURLForGUID(local_turl->sync_guid())); return local_turl->last_modified() > sync_turl->last_modified() || local_turl->created_by_policy() || (prefer_local_default && local_turl == GetDefaultSearchProvider()); @@ -2401,7 +2416,7 @@ return; } - TemplateURL* turl = GetTemplateURLForGUID(new_guid); + const TemplateURL* turl = GetTemplateURLForGUID(new_guid); if (turl) default_search_manager_.SetUserSelectedDefaultSearchEngine(turl->data()); }
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h index 7e57b2b..7698f8fd 100644 --- a/components/search_engines/template_url_service.h +++ b/components/search_engines/template_url_service.h
@@ -167,15 +167,19 @@ // The caller should not try to delete the returned pointer; the data store // retains ownership of it. TemplateURL* GetTemplateURLForKeyword(const base::string16& keyword); + const TemplateURL* GetTemplateURLForKeyword( + const base::string16& keyword) const; // Returns that TemplateURL with the specified GUID, or NULL if not found. // The caller should not try to delete the returned pointer; the data store // retains ownership of it. TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid); + const TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid) const; // Returns the first TemplateURL found with a URL using the specified |host|, // or NULL if there are no such TemplateURLs TemplateURL* GetTemplateURLForHost(const std::string& host); + const TemplateURL* GetTemplateURLForHost(const std::string& host) const; // Adds |template_url| to this model. Returns a raw pointer to |template_url| // if the addition succeeded, or null on failure. (Many callers need still @@ -388,7 +392,7 @@ TemplateURLServiceClient* client, PrefService* prefs, const SearchTermsData& search_terms_data, - TemplateURL* existing_turl, + const TemplateURL* existing_turl, const syncer::SyncData& sync_data, syncer::SyncChangeList* change_list);
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc index 34e79b1..34be8222 100644 --- a/components/variations/service/variations_service.cc +++ b/components/variations/service/variations_service.cc
@@ -41,6 +41,7 @@ #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" #include "net/http/http_util.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" #include "ui/base/device_form_factor.h" @@ -531,8 +532,27 @@ if (pending_seed_request_) return; - pending_seed_request_ = net::URLFetcher::Create(0, variations_server_url_, - net::URLFetcher::GET, this); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("chrome_variations_service", R"( + semantics { + sender: "Chrome Variations Service" + description: + "Retrieves the list of Google Chrome's Variations from the server, " + "which will apply to the next Chrome session upon a restart." + trigger: + "Requests are made periodically while Google Chrome is running." + data: "The operating system name." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: false + setting: "This feature cannot be disabled by settings." + policy_exception_justification: + "Not implemented, considered not required." + })"); + pending_seed_request_ = + net::URLFetcher::Create(0, variations_server_url_, net::URLFetcher::GET, + this, traffic_annotation); data_use_measurement::DataUseUserData::AttachToFetcher( pending_seed_request_.get(), data_use_measurement::DataUseUserData::VARIATIONS);
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc index 3cb728df..3dbea50 100644 --- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc +++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -172,9 +172,14 @@ uint64_t client_tracing_process_id = ClientIdToTracingProcessId(client_id); - base::trace_event::MemoryAllocatorDumpGuid shared_buffer_guid = - gfx::GetGpuMemoryBufferGUIDForTracing(client_tracing_process_id, - buffer_id); + base::trace_event::MemoryAllocatorDumpGuid shared_buffer_guid; + if (buffer.second.type == gfx::SHARED_MEMORY_BUFFER) { + shared_buffer_guid = gfx::GetSharedMemoryGUIDForTracing( + client_tracing_process_id, buffer_id); + } else { + shared_buffer_guid = gfx::GetGenericSharedGpuMemoryGUIDForTracing( + client_tracing_process_id, buffer_id); + } pmd->CreateSharedGlobalAllocatorDump(shared_buffer_guid); pmd->AddOwnershipEdge(dump->guid(), shared_buffer_guid); }
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 486b536..b752011 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -929,8 +929,8 @@ // If a browser-based widget consumes the touch event, it's critical that // touch event interception be disabled. This avoids issues with // double-handling for embedder-detected gestures like side swipe. - if (selection_controller_ && - selection_controller_->WillHandleTouchEvent(event)) { + if (touch_selection_controller_ && + touch_selection_controller_->WillHandleTouchEvent(event)) { RequestDisallowInterceptTouchEvent(); return true; } @@ -969,8 +969,8 @@ bool RenderWidgetHostViewAndroid::OnTouchHandleEvent( const ui::MotionEvent& event) { - return selection_controller_ && - selection_controller_->WillHandleTouchEvent(event); + return touch_selection_controller_ && + touch_selection_controller_->WillHandleTouchEvent(event); } void RenderWidgetHostViewAndroid::ResetGestureDetection() { @@ -1300,7 +1300,7 @@ void RenderWidgetHostViewAndroid::OnSelectionEvent( ui::SelectionEventType event) { DCHECK(content_view_core_); - DCHECK(selection_controller_); + DCHECK(touch_selection_controller_); // If a selection drag has started, it has taken over the active touch // sequence. Immediately cancel gesture detection and any downstream touch // listeners (e.g., web content) to communicate this transfer. @@ -1309,8 +1309,8 @@ ResetGestureDetection(); } content_view_core_->OnSelectionEvent( - event, selection_controller_->GetStartPosition(), - GetSelectionRect(*selection_controller_)); + event, touch_selection_controller_->GetStartPosition(), + GetSelectionRect(*touch_selection_controller_)); } std::unique_ptr<ui::TouchHandleDrawable> @@ -1381,8 +1381,8 @@ if (overscroll_controller_) overscroll_controller_->OnFrameMetadataUpdated(frame_metadata); - if (selection_controller_) { - selection_controller_->OnSelectionBoundsChanged( + if (touch_selection_controller_) { + touch_selection_controller_->OnSelectionBoundsChanged( frame_metadata.selection.start, frame_metadata.selection.end); // Set parameters for adaptive handle orientation. @@ -1391,7 +1391,7 @@ gfx::RectF viewport_rect(0.0f, frame_metadata.top_controls_height * frame_metadata.top_controls_shown_ratio, viewport_size.width(), viewport_size.height()); - selection_controller_->OnViewportChanged(viewport_rect); + touch_selection_controller_->OnViewportChanged(viewport_rect); } UpdateBackgroundColor(is_transparent ? SK_ColorTRANSPARENT @@ -1600,8 +1600,8 @@ needs_animate |= overscroll_controller_->Animate( frame_time, content_view_core_->GetViewAndroid()->GetLayer()); } - if (selection_controller_) - needs_animate |= selection_controller_->Animate(frame_time); + if (touch_selection_controller_) + needs_animate |= touch_selection_controller_->Animate(frame_time); return needs_animate; } @@ -1645,26 +1645,26 @@ InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent( const blink::WebInputEvent& input_event) { - if (selection_controller_ && + if (touch_selection_controller_ && blink::WebInputEvent::IsGestureEventType(input_event.GetType())) { const blink::WebGestureEvent& gesture_event = static_cast<const blink::WebGestureEvent&>(input_event); switch (gesture_event.GetType()) { case blink::WebInputEvent::kGestureLongPress: - selection_controller_->HandleLongPressEvent( + touch_selection_controller_->HandleLongPressEvent( base::TimeTicks() + base::TimeDelta::FromSecondsD(input_event.TimeStampSeconds()), gfx::PointF(gesture_event.x, gesture_event.y)); break; case blink::WebInputEvent::kGestureTap: - selection_controller_->HandleTapEvent( + touch_selection_controller_->HandleTapEvent( gfx::PointF(gesture_event.x, gesture_event.y), gesture_event.data.tap.tap_count); break; case blink::WebInputEvent::kGestureScrollBegin: - selection_controller_->OnScrollBeginEvent(); + touch_selection_controller_->OnScrollBeginEvent(); break; default: @@ -1831,13 +1831,13 @@ } void RenderWidgetHostViewAndroid::DismissTextHandles() { - if (selection_controller_) - selection_controller_->HideAndDisallowShowingAutomatically(); + if (touch_selection_controller_) + touch_selection_controller_->HideAndDisallowShowingAutomatically(); } void RenderWidgetHostViewAndroid::SetTextHandlesTemporarilyHidden(bool hidden) { - if (selection_controller_) - selection_controller_->SetTemporarilyHidden(hidden); + if (touch_selection_controller_) + touch_selection_controller_->SetTemporarilyHidden(hidden); } SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const { @@ -1884,7 +1884,7 @@ bool resize = false; if (content_view_core != content_view_core_) { - selection_controller_.reset(); + touch_selection_controller_.reset(); RunAckCallbacks(); // TODO(yusufo) : Get rid of the below conditions and have a better handling // for resizing after crbug.com/628302 is handled. @@ -1928,8 +1928,9 @@ if (resize) WasResized(); - if (!selection_controller_) - selection_controller_ = CreateSelectionController(this, content_view_core_); + if (!touch_selection_controller_) + touch_selection_controller_ = + CreateSelectionController(this, content_view_core_); if (content_view_core_) CreateOverscrollControllerIfPossible();
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 704204f..bbfa9fc8 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -394,7 +394,7 @@ // Manages selection handle rendering and manipulation. // This will always be NULL if |content_view_core_| is NULL. - std::unique_ptr<ui::TouchSelectionController> selection_controller_; + std::unique_ptr<ui::TouchSelectionController> touch_selection_controller_; // Bounds to use if we have no backing ContentViewCore gfx::Rect default_bounds_;
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index 93aaf34..e130e4b9 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" -#include "base/threading/non_thread_safe.h" #include "base/trace_event/trace_event.h" #include "content/browser/bad_message.h" #include "content/browser/devtools/service_worker_devtools_manager.h" @@ -80,9 +79,11 @@ const GURL& scope, bool is_installed, mojom::EmbeddedWorkerInstanceClientRequest request, - const base::Callback<void(int worker_devtools_agent_route_id, - bool wait_for_debugger)>& callback) { + const base::Callback< + void(std::unique_ptr<EmbeddedWorkerInstance::DevToolsProxy>, + bool wait_for_debugger)>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + std::unique_ptr<EmbeddedWorkerInstance::DevToolsProxy> devtools_proxy; int worker_devtools_agent_route_id = MSG_ROUTING_NONE; bool wait_for_debugger = false; if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) { @@ -97,11 +98,12 @@ is_installed); if (request.is_pending()) BindInterface(rph, std::move(request)); + devtools_proxy = base::MakeUnique<EmbeddedWorkerInstance::DevToolsProxy>( + process_id, worker_devtools_agent_route_id); } BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger)); + BrowserThread::IO, FROM_HERE, + base::Bind(callback, base::Passed(&devtools_proxy), wait_for_debugger)); } void CallDetach(EmbeddedWorkerInstance* instance) { @@ -137,15 +139,16 @@ } // namespace -// Lives on IO thread, proxies notifications to DevToolsManager that lives on -// UI thread. Owned by EmbeddedWorkerInstance. -class EmbeddedWorkerInstance::DevToolsProxy : public base::NonThreadSafe { +// Created on UI thread and moved to IO thread. Proxies notifications to +// DevToolsManager that lives on UI thread. Owned by EmbeddedWorkerInstance. +class EmbeddedWorkerInstance::DevToolsProxy { public: DevToolsProxy(int process_id, int agent_route_id) : process_id_(process_id), agent_route_id_(agent_route_id) {} ~DevToolsProxy() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, @@ -154,21 +157,21 @@ } void NotifyWorkerReadyForInspection() { - DCHECK(CalledOnValidThread()); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(NotifyWorkerReadyForInspectionOnUI, process_id_, agent_route_id_)); } void NotifyWorkerVersionInstalled() { - DCHECK(CalledOnValidThread()); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(NotifyWorkerVersionInstalledOnUI, process_id_, agent_route_id_)); } void NotifyWorkerVersionDoomed() { - DCHECK(CalledOnValidThread()); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(NotifyWorkerVersionDoomedOnUI, process_id_, agent_route_id_)); @@ -186,6 +189,7 @@ const int process_id_; const int agent_route_id_; bool worker_stop_ignored_notified_ = false; + DISALLOW_COPY_AND_ASSIGN(DevToolsProxy); }; @@ -248,7 +252,6 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); TRACE_EVENT_ASYNC_END0("ServiceWorker", "EmbeddedWorkerInstance::Start", this); - if (!instance_->context_) return; @@ -372,21 +375,22 @@ is_new_process))); } - void OnSetupOnUICompleted(std::unique_ptr<EmbeddedWorkerStartParams> params, - bool is_new_process, - int worker_devtools_agent_route_id, - bool wait_for_debugger) { + void OnSetupOnUICompleted( + std::unique_ptr<EmbeddedWorkerStartParams> params, + bool is_new_process, + std::unique_ptr<EmbeddedWorkerInstance::DevToolsProxy> devtools_proxy, + bool wait_for_debugger) { DCHECK_CURRENTLY_ON(BrowserThread::IO); TRACE_EVENT_ASYNC_STEP_PAST0("ServiceWorker", "EmbeddedWorkerInstance::Start", this, "OnSetupOnUICompleted"); + params->worker_devtools_agent_route_id = devtools_proxy->agent_route_id(); + params->wait_for_debugger = wait_for_debugger; + // Notify the instance that it is registered to the devtools manager. instance_->OnRegisteredToDevToolsManager( - is_new_process, worker_devtools_agent_route_id, wait_for_debugger); - - params->worker_devtools_agent_route_id = worker_devtools_agent_route_id; - params->wait_for_debugger = wait_for_debugger; + is_new_process, std::move(devtools_proxy), wait_for_debugger); ServiceWorkerStatusCode status = instance_->SendStartWorker(std::move(params)); @@ -478,21 +482,21 @@ // Abort an inflight start task. inflight_start_task_.reset(); - if (status_ == EmbeddedWorkerStatus::STARTING && - !HasSentStartWorker(starting_phase())) { - // Don't send the StopWorker message when the StartWorker message hasn't - // been sent. - // TODO(shimazu): Invoke OnStopping/OnStopped after the legacy IPC path is - // removed. - OnDetached(); - return false; - } - client_->StopWorker(); + if (status_ == EmbeddedWorkerStatus::STARTING && + !HasSentStartWorker(starting_phase())) { + // Don't send the StopWorker message when the StartWorker message hasn't + // been sent. + // TODO(shimazu): Invoke OnStopping/OnStopped after the legacy IPC path is + // removed. + OnDetached(); + return false; + } + client_->StopWorker(); - status_ = EmbeddedWorkerStatus::STOPPING; - for (auto& observer : listener_list_) - observer.OnStopping(); - return true; + status_ = EmbeddedWorkerStatus::STOPPING; + for (auto& observer : listener_list_) + observer.OnStopping(); + return true; } void EmbeddedWorkerInstance::StopIfIdle() { @@ -562,12 +566,11 @@ void EmbeddedWorkerInstance::OnRegisteredToDevToolsManager( bool is_new_process, - int worker_devtools_agent_route_id, + std::unique_ptr<DevToolsProxy> devtools_proxy, bool wait_for_debugger) { - if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) { + if (devtools_proxy) { DCHECK(!devtools_proxy_); - devtools_proxy_.reset( - new DevToolsProxy(process_id(), worker_devtools_agent_route_id)); + devtools_proxy_ = std::move(devtools_proxy); } if (wait_for_debugger) { // We don't measure the start time when wait_for_debugger flag is set. So @@ -627,7 +630,6 @@ void EmbeddedWorkerInstance::OnScriptLoaded() { using LoadSource = ServiceWorkerMetrics::LoadSource; - TRACE_EVENT0("ServiceWorker", "EmbeddedWorkerInstance::OnScriptLoaded"); if (!inflight_start_task_)
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h index 71ed5e6c..737417c8 100644 --- a/content/browser/service_worker/embedded_worker_instance.h +++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -50,6 +50,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance : NON_EXPORTED_BASE(public mojom::EmbeddedWorkerInstanceHost) { public: + class DevToolsProxy; typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback; // This enum is used in UMA histograms. Append-only. @@ -191,7 +192,6 @@ private: typedef base::ObserverList<Listener> ListenerList; - class DevToolsProxy; class StartTask; class WorkerProcessHandle; friend class EmbeddedWorkerRegistry; @@ -210,9 +210,10 @@ // Called back from StartTask after the worker is registered to // WorkerDevToolsManager. - void OnRegisteredToDevToolsManager(bool is_new_process, - int worker_devtools_agent_route_id, - bool wait_for_debugger); + void OnRegisteredToDevToolsManager( + bool is_new_process, + std::unique_ptr<DevToolsProxy> devtools_proxy, + bool wait_for_debugger); // Sends StartWorker message via Mojo. ServiceWorkerStatusCode SendStartWorker(
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index c4c8faae..d7a1a5e 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -72,8 +72,6 @@ "../public/test/javascript_test_observer.h", "../public/test/memory_coordinator_test_utils.cc", "../public/test/memory_coordinator_test_utils.h", - "../public/test/mock_blob_url_request_context.cc", - "../public/test/mock_blob_url_request_context.h", "../public/test/mock_download_item.cc", "../public/test/mock_download_item.h", "../public/test/mock_download_manager.cc", @@ -1059,7 +1057,6 @@ "../browser/compositor/reflector_impl_unittest.cc", "../browser/compositor/software_browser_compositor_output_surface_unittest.cc", "../browser/compositor/software_output_device_ozone_unittest.cc", - "../browser/database_tracker_unittest.cc", "../browser/devtools/devtools_http_handler_unittest.cc", "../browser/devtools/devtools_manager_unittest.cc", "../browser/devtools/protocol/tracing_handler_unittest.cc", @@ -1080,13 +1077,8 @@ "../browser/download/parallel_download_utils_unittest.cc", "../browser/download/rate_estimator_unittest.cc", "../browser/download/save_package_unittest.cc", - "../browser/fileapi/file_system_operation_impl_write_unittest.cc", "../browser/fileapi/file_system_operation_runner_unittest.cc", "../browser/fileapi/fileapi_message_filter_unittest.cc", - "../browser/fileapi/sandbox_database_test_helper.cc", - "../browser/fileapi/sandbox_database_test_helper.h", - "../browser/fileapi/sandbox_directory_database_unittest.cc", - "../browser/fileapi/sandbox_origin_database_unittest.cc", "../browser/fileapi/upload_file_system_file_element_reader_unittest.cc", "../browser/frame_host/ancestor_throttle_unittest.cc", "../browser/frame_host/frame_tree_node_blame_context_unittest.cc",
diff --git a/device/usb/BUILD.gn b/device/usb/BUILD.gn index 76fa59e..83ff8c11 100644 --- a/device/usb/BUILD.gn +++ b/device/usb/BUILD.gn
@@ -57,13 +57,22 @@ deps = [ ":usb_device_ids", - "//base", "//base/third_party/dynamic_annotations", "//components/device_event_log", "//device/base", "//net", ] + public_deps = [ + "//base", + "//url", + + # Depend on the header generation target only to avoid the circular + # dependency caused by both using enums defined in the mojom headers and + # typemappings linking against this target. + "public/interfaces:interfaces__generator", + ] + if (use_udev) { sources += [ "usb_service_linux.cc",
diff --git a/device/usb/fake_usb_device_handle.cc b/device/usb/fake_usb_device_handle.cc index 27ddfb3..78c0134 100644 --- a/device/usb/fake_usb_device_handle.cc +++ b/device/usb/fake_usb_device_handle.cc
@@ -55,9 +55,9 @@ } void FakeUsbDeviceHandle::ControlTransfer( - UsbEndpointDirection direction, - UsbDeviceHandle::TransferRequestType request_type, - UsbDeviceHandle::TransferRecipient recipient, + UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -66,7 +66,7 @@ unsigned int timeout, const UsbDeviceHandle::TransferCallback& callback) { if (position_ == size_) { - callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); + callback.Run(UsbTransferStatus::DISCONNECT, buffer, 0); return; } @@ -79,14 +79,14 @@ bytes_transferred = std::min(bytes_transferred, size_ - position_); } - if (direction == USB_DIRECTION_INBOUND) { + if (direction == UsbTransferDirection::INBOUND) { memcpy(buffer->data(), &data_[position_], bytes_transferred); position_ += bytes_transferred; } - callback.Run(USB_TRANSFER_COMPLETED, buffer, bytes_transferred); + callback.Run(UsbTransferStatus::COMPLETED, buffer, bytes_transferred); } else { - callback.Run(USB_TRANSFER_ERROR, buffer, 0); + callback.Run(UsbTransferStatus::TRANSFER_ERROR, buffer, 0); } } @@ -107,7 +107,7 @@ NOTIMPLEMENTED(); } -void FakeUsbDeviceHandle::GenericTransfer(UsbEndpointDirection direction, +void FakeUsbDeviceHandle::GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length,
diff --git a/device/usb/fake_usb_device_handle.h b/device/usb/fake_usb_device_handle.h index 121a287..aa48ad7 100644 --- a/device/usb/fake_usb_device_handle.h +++ b/device/usb/fake_usb_device_handle.h
@@ -37,9 +37,9 @@ void ResetDevice(const ResultCallback& callback) override; void ClearHalt(uint8_t endpoint, const ResultCallback& callback) override; - void ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + void ControlTransfer(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -61,7 +61,7 @@ unsigned int timeout, const IsochronousTransferCallback& callback) override; - void GenericTransfer(UsbEndpointDirection direction, + void GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length,
diff --git a/device/usb/mock_usb_device_handle.h b/device/usb/mock_usb_device_handle.h index 5e2a3c2..15e6974f 100644 --- a/device/usb/mock_usb_device_handle.h +++ b/device/usb/mock_usb_device_handle.h
@@ -36,9 +36,9 @@ MOCK_METHOD2(ClearHalt, void(uint8_t endpoint, const ResultCallback& callback)); MOCK_METHOD10(ControlTransfer, - void(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + void(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -58,7 +58,7 @@ unsigned int timeout, const IsochronousTransferCallback& callback)); MOCK_METHOD6(GenericTransfer, - void(UsbEndpointDirection direction, + void(UsbTransferDirection direction, uint8_t endpoint, scoped_refptr<net::IOBuffer> buffer, size_t length,
diff --git a/device/usb/mojo/device_impl.cc b/device/usb/mojo/device_impl.cc index 574cb90d..2d8f7c4 100644 --- a/device/usb/mojo/device_impl.cc +++ b/device/usb/mojo/device_impl.cc
@@ -334,9 +334,7 @@ if (HasControlTransferPermission(params->recipient, params->index)) { scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); device_handle_->ControlTransfer( - USB_DIRECTION_INBOUND, - mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), - mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), + UsbTransferDirection::INBOUND, params->type, params->recipient, params->request, params->value, params->index, buffer, length, timeout, base::Bind(&OnTransferIn, callback)); } else { @@ -358,9 +356,7 @@ scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); std::copy(data.begin(), data.end(), buffer->data()); device_handle_->ControlTransfer( - USB_DIRECTION_OUTBOUND, - mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), - mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), + UsbTransferDirection::OUTBOUND, params->type, params->recipient, params->request, params->value, params->index, buffer, data.size(), timeout, base::Bind(&OnTransferOut, callback)); } else { @@ -379,8 +375,8 @@ uint8_t endpoint_address = endpoint_number | 0x80; scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length); - device_handle_->GenericTransfer(USB_DIRECTION_INBOUND, endpoint_address, - buffer, length, timeout, + device_handle_->GenericTransfer(UsbTransferDirection::INBOUND, + endpoint_address, buffer, length, timeout, base::Bind(&OnTransferIn, callback)); } @@ -397,9 +393,9 @@ uint8_t endpoint_address = endpoint_number; scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); std::copy(data.begin(), data.end(), buffer->data()); - device_handle_->GenericTransfer(USB_DIRECTION_OUTBOUND, endpoint_address, - buffer, data.size(), timeout, - base::Bind(&OnTransferOut, callback)); + device_handle_->GenericTransfer( + UsbTransferDirection::OUTBOUND, endpoint_address, buffer, data.size(), + timeout, base::Bind(&OnTransferOut, callback)); } void DeviceImpl::IsochronousTransferIn(
diff --git a/device/usb/mojo/device_impl_unittest.cc b/device/usb/mojo/device_impl_unittest.cc index a077a81..68362907 100644 --- a/device/usb/mojo/device_impl_unittest.cc +++ b/device/usb/mojo/device_impl_unittest.cc
@@ -307,7 +307,7 @@ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(length); std::copy(bytes.begin(), bytes.end(), buffer->data()); mock_inbound_data_.pop(); - callback.Run(USB_TRANSFER_COMPLETED, buffer, length); + callback.Run(UsbTransferStatus::COMPLETED, buffer, length); } void OutboundTransfer(scoped_refptr<net::IOBuffer> buffer, @@ -321,12 +321,12 @@ << i; } mock_outbound_data_.pop(); - callback.Run(USB_TRANSFER_COMPLETED, buffer, length); + callback.Run(UsbTransferStatus::COMPLETED, buffer, length); } - void ControlTransfer(UsbEndpointDirection direction, - UsbDeviceHandle::TransferRequestType request_type, - UsbDeviceHandle::TransferRecipient recipient, + void ControlTransfer(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -334,19 +334,19 @@ size_t length, unsigned int timeout, const UsbDeviceHandle::TransferCallback& callback) { - if (direction == USB_DIRECTION_INBOUND) + if (direction == UsbTransferDirection::INBOUND) InboundTransfer(callback); else OutboundTransfer(buffer, length, callback); } - void GenericTransfer(UsbEndpointDirection direction, + void GenericTransfer(UsbTransferDirection direction, uint8_t endpoint, scoped_refptr<net::IOBuffer> buffer, size_t length, unsigned int timeout, const UsbDeviceHandle::TransferCallback& callback) { - if (direction == USB_DIRECTION_INBOUND) + if (direction == UsbTransferDirection::INBOUND) InboundTransfer(callback); else OutboundTransfer(buffer, length, callback); @@ -718,8 +718,10 @@ AddMockInboundData(fake_data); EXPECT_CALL(mock_handle(), - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 5, 6, 7, _, _, 0, _)); + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 5, 6, 7, _, + _, 0, _)); EXPECT_CALL(permission_provider(), HasConfigurationPermission(1, _)); { @@ -741,8 +743,10 @@ AddMockOutboundData(fake_data); EXPECT_CALL(mock_handle(), - ControlTransfer(USB_DIRECTION_OUTBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::INTERFACE, 5, 6, 7, _, _, 0, _)); + ControlTransfer(UsbTransferDirection::OUTBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::INTERFACE, 5, 6, 7, + _, _, 0, _)); EXPECT_CALL(permission_provider(), HasFunctionPermission(7, 1, _)); { @@ -787,8 +791,9 @@ AddMockOutboundData(fake_outbound_data); AddMockInboundData(fake_inbound_data); - EXPECT_CALL(mock_handle(), GenericTransfer(USB_DIRECTION_OUTBOUND, 0x01, _, - fake_outbound_data.size(), 0, _)); + EXPECT_CALL(mock_handle(), + GenericTransfer(UsbTransferDirection::OUTBOUND, 0x01, _, + fake_outbound_data.size(), 0, _)); { base::RunLoop loop; @@ -799,8 +804,9 @@ loop.Run(); } - EXPECT_CALL(mock_handle(), GenericTransfer(USB_DIRECTION_INBOUND, 0x81, _, - fake_inbound_data.size(), 0, _)); + EXPECT_CALL(mock_handle(), + GenericTransfer(UsbTransferDirection::INBOUND, 0x81, _, + fake_inbound_data.size(), 0, _)); { base::RunLoop loop; @@ -831,7 +837,7 @@ for (size_t i = 0; i < fake_packets.size(); ++i) { fake_packets[i].length = 8; fake_packets[i].transferred_length = 8; - fake_packets[i].status = USB_TRANSFER_COMPLETED; + fake_packets[i].status = UsbTransferStatus::COMPLETED; } std::vector<uint32_t> fake_packet_lengths(4, 8);
diff --git a/device/usb/mojo/type_converters.cc b/device/usb/mojo/type_converters.cc index da85613..fbe17d8 100644 --- a/device/usb/mojo/type_converters.cc +++ b/device/usb/mojo/type_converters.cc
@@ -17,114 +17,14 @@ namespace mojo { // static -device::mojom::UsbTransferDirection TypeConverter< - device::mojom::UsbTransferDirection, - device::UsbEndpointDirection>::Convert(const device::UsbEndpointDirection& - direction) { - if (direction == device::USB_DIRECTION_INBOUND) - return device::mojom::UsbTransferDirection::INBOUND; - DCHECK(direction == device::USB_DIRECTION_OUTBOUND); - return device::mojom::UsbTransferDirection::OUTBOUND; -} - -// static -device::mojom::UsbTransferStatus -TypeConverter<device::mojom::UsbTransferStatus, device::UsbTransferStatus>:: - Convert(const device::UsbTransferStatus& status) { - switch (status) { - case device::USB_TRANSFER_COMPLETED: - return device::mojom::UsbTransferStatus::COMPLETED; - case device::USB_TRANSFER_ERROR: - return device::mojom::UsbTransferStatus::TRANSFER_ERROR; - case device::USB_TRANSFER_TIMEOUT: - return device::mojom::UsbTransferStatus::TIMEOUT; - case device::USB_TRANSFER_CANCELLED: - return device::mojom::UsbTransferStatus::CANCELLED; - case device::USB_TRANSFER_STALLED: - return device::mojom::UsbTransferStatus::STALLED; - case device::USB_TRANSFER_DISCONNECT: - return device::mojom::UsbTransferStatus::DISCONNECT; - case device::USB_TRANSFER_OVERFLOW: - return device::mojom::UsbTransferStatus::BABBLE; - case device::USB_TRANSFER_LENGTH_SHORT: - return device::mojom::UsbTransferStatus::SHORT_PACKET; - default: - NOTREACHED(); - return device::mojom::UsbTransferStatus::TRANSFER_ERROR; - } -} - -// static -device::UsbDeviceHandle::TransferRequestType -TypeConverter<device::UsbDeviceHandle::TransferRequestType, - device::mojom::UsbControlTransferType>:: - Convert(const device::mojom::UsbControlTransferType& type) { - switch (type) { - case device::mojom::UsbControlTransferType::STANDARD: - return device::UsbDeviceHandle::STANDARD; - case device::mojom::UsbControlTransferType::CLASS: - return device::UsbDeviceHandle::CLASS; - case device::mojom::UsbControlTransferType::VENDOR: - return device::UsbDeviceHandle::VENDOR; - case device::mojom::UsbControlTransferType::RESERVED: - return device::UsbDeviceHandle::RESERVED; - default: - NOTREACHED(); - return device::UsbDeviceHandle::RESERVED; - } -} - -// static -device::UsbDeviceHandle::TransferRecipient -TypeConverter<device::UsbDeviceHandle::TransferRecipient, - device::mojom::UsbControlTransferRecipient>:: - Convert(const device::mojom::UsbControlTransferRecipient& recipient) { - switch (recipient) { - case device::mojom::UsbControlTransferRecipient::DEVICE: - return device::UsbDeviceHandle::DEVICE; - case device::mojom::UsbControlTransferRecipient::INTERFACE: - return device::UsbDeviceHandle::INTERFACE; - case device::mojom::UsbControlTransferRecipient::ENDPOINT: - return device::UsbDeviceHandle::ENDPOINT; - case device::mojom::UsbControlTransferRecipient::OTHER: - return device::UsbDeviceHandle::OTHER; - default: - NOTREACHED(); - return device::UsbDeviceHandle::OTHER; - } -} - -// static -device::mojom::UsbEndpointType -TypeConverter<device::mojom::UsbEndpointType, device::UsbTransferType>::Convert( - const device::UsbTransferType& type) { - switch (type) { - case device::USB_TRANSFER_ISOCHRONOUS: - return device::mojom::UsbEndpointType::ISOCHRONOUS; - case device::USB_TRANSFER_BULK: - return device::mojom::UsbEndpointType::BULK; - case device::USB_TRANSFER_INTERRUPT: - return device::mojom::UsbEndpointType::INTERRUPT; - // Note that we do not expose control transfer in the public interface - // because control endpoints are implied rather than explicitly enumerated - // there. - default: - NOTREACHED(); - return device::mojom::UsbEndpointType::BULK; - } -} - -// static device::mojom::UsbEndpointInfoPtr TypeConverter< device::mojom::UsbEndpointInfoPtr, device::UsbEndpointDescriptor>::Convert(const device::UsbEndpointDescriptor& endpoint) { auto info = device::mojom::UsbEndpointInfo::New(); info->endpoint_number = endpoint.address & 0xf; - info->direction = - ConvertTo<device::mojom::UsbTransferDirection>(endpoint.direction); - info->type = - ConvertTo<device::mojom::UsbEndpointType>(endpoint.transfer_type); + info->direction = endpoint.direction; + info->type = endpoint.transfer_type; info->packet_size = static_cast<uint32_t>(endpoint.maximum_packet_size); return info; } @@ -143,7 +43,7 @@ // Filter out control endpoints for the public interface. info->endpoints.reserve(interface.endpoints.size()); for (const auto& endpoint : interface.endpoints) { - if (endpoint.transfer_type != device::USB_TRANSFER_CONTROL) + if (endpoint.transfer_type != device::UsbTransferType::CONTROL) info->endpoints.push_back(device::mojom::UsbEndpointInfo::From(endpoint)); }
diff --git a/device/usb/mojo/type_converters.h b/device/usb/mojo/type_converters.h index 4cee02c..cb9514c 100644 --- a/device/usb/mojo/type_converters.h +++ b/device/usb/mojo/type_converters.h
@@ -25,40 +25,6 @@ namespace mojo { template <> -struct TypeConverter<device::mojom::UsbTransferDirection, - device::UsbEndpointDirection> { - static device::mojom::UsbTransferDirection Convert( - const device::UsbEndpointDirection& direction); -}; - -template <> -struct TypeConverter<device::mojom::UsbTransferStatus, - device::UsbTransferStatus> { - static device::mojom::UsbTransferStatus Convert( - const device::UsbTransferStatus& status); -}; - -template <> -struct TypeConverter<device::UsbDeviceHandle::TransferRequestType, - device::mojom::UsbControlTransferType> { - static device::UsbDeviceHandle::TransferRequestType Convert( - const device::mojom::UsbControlTransferType& type); -}; - -template <> -struct TypeConverter<device::UsbDeviceHandle::TransferRecipient, - device::mojom::UsbControlTransferRecipient> { - static device::UsbDeviceHandle::TransferRecipient Convert( - const device::mojom::UsbControlTransferRecipient& recipient); -}; - -template <> -struct TypeConverter<device::mojom::UsbEndpointType, device::UsbTransferType> { - static device::mojom::UsbEndpointType Convert( - const device::UsbTransferType& type); -}; - -template <> struct TypeConverter<device::mojom::UsbEndpointInfoPtr, device::UsbEndpointDescriptor> { static device::mojom::UsbEndpointInfoPtr Convert(
diff --git a/device/usb/public/interfaces/device.mojom b/device/usb/public/interfaces/device.mojom index e23406a..d1c139a 100644 --- a/device/usb/public/interfaces/device.mojom +++ b/device/usb/public/interfaces/device.mojom
@@ -15,8 +15,9 @@ ALREADY_OPEN, }; +// Corresponds to the USBDirection WebIDL type. enum UsbTransferDirection { - INBOUND, + INBOUND = 0, OUTBOUND, }; @@ -27,6 +28,7 @@ RESERVED }; +// Corresponds to the USBRecipient WebIDL type. enum UsbControlTransferRecipient { DEVICE, INTERFACE, @@ -34,16 +36,17 @@ OTHER }; -enum UsbEndpointType { +enum UsbTransferType { + CONTROL = 0, + ISOCHRONOUS, BULK, INTERRUPT, - ISOCHRONOUS, }; struct UsbEndpointInfo { uint8 endpoint_number; UsbTransferDirection direction; - UsbEndpointType type; + UsbTransferType type; uint32 packet_size; }; @@ -95,16 +98,15 @@ uint16 index; }; +// This enum is exposed through the chrome.usb extension API so existing values +// should not be changed or reordered. enum UsbTransferStatus { // The transfer completed successfully. - COMPLETED, + COMPLETED = 0, // The transfer failed due to a non-specific error. TRANSFER_ERROR, - // The transfer was not allowed. - PERMISSION_DENIED, - // The transfer timed out. TIMEOUT, @@ -124,6 +126,9 @@ // The transfer succeeded, but the device sent less data than was requested. // This applies only to inbound transfers. SHORT_PACKET, + + // The transfer was not allowed. + PERMISSION_DENIED, }; struct UsbIsochronousPacket {
diff --git a/device/usb/usb_descriptors.cc b/device/usb/usb_descriptors.cc index 5ad332b..645ee56 100644 --- a/device/usb/usb_descriptors.cc +++ b/device/usb/usb_descriptors.cc
@@ -97,7 +97,7 @@ UsbTransferStatus status, scoped_refptr<IOBuffer> buffer, size_t length) { - if (status == USB_TRANSFER_COMPLETED) { + if (status == UsbTransferStatus::COMPLETED) { if (!desc->Parse( std::vector<uint8_t>(buffer->data(), buffer->data() + length))) { LOG(ERROR) << "Failed to parse configuration descriptor."; @@ -115,13 +115,13 @@ UsbTransferStatus status, scoped_refptr<IOBuffer> header, size_t length) { - if (status == USB_TRANSFER_COMPLETED && length == 4) { + if (status == UsbTransferStatus::COMPLETED && length == 4) { const uint8_t* data = reinterpret_cast<const uint8_t*>(header->data()); uint16_t total_length = data[2] | data[3] << 8; scoped_refptr<IOBuffer> buffer = new IOBuffer(total_length); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, kGetDescriptorRequest, + UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, kGetDescriptorRequest, kConfigurationDescriptorType << 8 | index, 0, buffer, total_length, kControlTransferTimeout, base::Bind(&OnReadConfigDescriptor, desc, closure)); @@ -138,7 +138,7 @@ UsbTransferStatus status, scoped_refptr<IOBuffer> buffer, size_t length) { - if (status != USB_TRANSFER_COMPLETED) { + if (status != UsbTransferStatus::COMPLETED) { LOG(ERROR) << "Failed to read device descriptor."; callback.Run(nullptr); return; @@ -166,8 +166,8 @@ for (uint8_t i = 0; i < num_configurations; ++i) { scoped_refptr<IOBufferWithSize> header = new IOBufferWithSize(4); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, kGetDescriptorRequest, + UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, kGetDescriptorRequest, kConfigurationDescriptorType << 8 | i, 0, header, header->size(), kControlTransferTimeout, base::Bind(&OnReadConfigDescriptorHeader, device_handle, desc_ptr, i, @@ -188,7 +188,7 @@ scoped_refptr<IOBuffer> buffer, size_t length) { base::string16 string; - if (status == USB_TRANSFER_COMPLETED && + if (status == UsbTransferStatus::COMPLETED && ParseUsbStringDescriptor( std::vector<uint8_t>(buffer->data(), buffer->data() + length), &string)) { @@ -205,10 +205,10 @@ const base::Callback<void(const base::string16&)>& callback) { scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(255); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, UsbDeviceHandle::DEVICE, - kGetDescriptorRequest, kStringDescriptorType << 8 | index, language_id, - buffer, buffer->size(), kControlTransferTimeout, - base::Bind(&OnReadStringDescriptor, callback)); + UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, kGetDescriptorRequest, + kStringDescriptorType << 8 | index, language_id, buffer, buffer->size(), + kControlTransferTimeout, base::Bind(&OnReadStringDescriptor, callback)); } void OnReadLanguageIds(scoped_refptr<UsbDeviceHandle> device_handle, @@ -254,24 +254,24 @@ // These fields are defined in Table 9-24 of the USB 3.1 Specification. switch (address & 0x80) { case 0x00: - direction = USB_DIRECTION_OUTBOUND; + direction = UsbTransferDirection::OUTBOUND; break; case 0x80: - direction = USB_DIRECTION_INBOUND; + direction = UsbTransferDirection::INBOUND; break; } switch (attributes & 0x03) { case 0x00: - transfer_type = USB_TRANSFER_CONTROL; + transfer_type = UsbTransferType::CONTROL; break; case 0x01: - transfer_type = USB_TRANSFER_ISOCHRONOUS; + transfer_type = UsbTransferType::ISOCHRONOUS; break; case 0x02: - transfer_type = USB_TRANSFER_BULK; + transfer_type = UsbTransferType::BULK; break; case 0x03: - transfer_type = USB_TRANSFER_INTERRUPT; + transfer_type = UsbTransferType::INTERRUPT; break; } switch (attributes & 0x0F) { @@ -500,9 +500,10 @@ scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(kDeviceDescriptorLength); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, UsbDeviceHandle::DEVICE, - kGetDescriptorRequest, kDeviceDescriptorType << 8, 0, buffer, - buffer->size(), kControlTransferTimeout, + UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, kGetDescriptorRequest, + kDeviceDescriptorType << 8, 0, buffer, buffer->size(), + kControlTransferTimeout, base::Bind(&OnReadDeviceDescriptor, device_handle, callback)); }
diff --git a/device/usb/usb_descriptors.h b/device/usb/usb_descriptors.h index 9039c95..b0f5be6 100644 --- a/device/usb/usb_descriptors.h +++ b/device/usb/usb_descriptors.h
@@ -14,22 +14,14 @@ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/strings/string16.h" +#include "device/usb/public/interfaces/device.mojom.h" namespace device { class UsbDeviceHandle; -enum UsbTransferType { - USB_TRANSFER_CONTROL = 0, - USB_TRANSFER_ISOCHRONOUS, - USB_TRANSFER_BULK, - USB_TRANSFER_INTERRUPT, -}; - -enum UsbEndpointDirection { - USB_DIRECTION_INBOUND = 0, - USB_DIRECTION_OUTBOUND, -}; +using UsbTransferType = mojom::UsbTransferType; +using UsbTransferDirection = mojom::UsbTransferDirection; enum UsbSynchronizationType { USB_SYNCHRONIZATION_NONE = 0, @@ -61,7 +53,7 @@ ~UsbEndpointDescriptor(); uint8_t address; - UsbEndpointDirection direction; + UsbTransferDirection direction; uint16_t maximum_packet_size; UsbSynchronizationType synchronization_type; UsbTransferType transfer_type;
diff --git a/device/usb/usb_descriptors_unittest.cc b/device/usb/usb_descriptors_unittest.cc index 195b01b..06cc6824 100644 --- a/device/usb/usb_descriptors_unittest.cc +++ b/device/usb/usb_descriptors_unittest.cc
@@ -22,7 +22,7 @@ ACTION_P2(InvokeCallback, data, length) { size_t transferred_length = std::min(length, arg7); memcpy(arg6->data(), data, transferred_length); - arg9.Run(USB_TRANSFER_COMPLETED, arg6, transferred_length); + arg9.Run(UsbTransferStatus::COMPLETED, arg6, transferred_length); } void ExpectStringDescriptors( @@ -86,33 +86,36 @@ EXPECT_EQ(0, config.interfaces[0].first_interface); // Endpoint 1 IN EXPECT_EQ(0x81, config.interfaces[0].endpoints[0].address); - EXPECT_EQ(USB_DIRECTION_INBOUND, config.interfaces[0].endpoints[0].direction); + EXPECT_EQ(UsbTransferDirection::INBOUND, + config.interfaces[0].endpoints[0].direction); EXPECT_EQ(512, config.interfaces[0].endpoints[0].maximum_packet_size); EXPECT_EQ(USB_SYNCHRONIZATION_NONE, config.interfaces[0].endpoints[0].synchronization_type); - EXPECT_EQ(USB_TRANSFER_BULK, config.interfaces[0].endpoints[0].transfer_type); + EXPECT_EQ(UsbTransferType::BULK, + config.interfaces[0].endpoints[0].transfer_type); EXPECT_EQ(USB_USAGE_RESERVED, config.interfaces[0].endpoints[0].usage_type); EXPECT_EQ(0, config.interfaces[0].endpoints[0].polling_interval); EXPECT_EQ(0u, config.interfaces[0].endpoints[0].extra_data.size()); // Endpoint 2 IN EXPECT_EQ(0x82, config.interfaces[0].endpoints[1].address); - EXPECT_EQ(USB_DIRECTION_INBOUND, config.interfaces[0].endpoints[1].direction); + EXPECT_EQ(UsbTransferDirection::INBOUND, + config.interfaces[0].endpoints[1].direction); EXPECT_EQ(512, config.interfaces[0].endpoints[1].maximum_packet_size); EXPECT_EQ(USB_SYNCHRONIZATION_NONE, config.interfaces[0].endpoints[1].synchronization_type); - EXPECT_EQ(USB_TRANSFER_INTERRUPT, + EXPECT_EQ(UsbTransferType::INTERRUPT, config.interfaces[0].endpoints[1].transfer_type); EXPECT_EQ(USB_USAGE_PERIODIC, config.interfaces[0].endpoints[1].usage_type); EXPECT_EQ(4, config.interfaces[0].endpoints[1].polling_interval); EXPECT_EQ(0u, config.interfaces[0].endpoints[1].extra_data.size()); // Endpoint 3 OUT EXPECT_EQ(0x03, config.interfaces[0].endpoints[2].address); - EXPECT_EQ(USB_DIRECTION_OUTBOUND, + EXPECT_EQ(UsbTransferDirection::OUTBOUND, config.interfaces[0].endpoints[2].direction); EXPECT_EQ(512, config.interfaces[0].endpoints[2].maximum_packet_size); EXPECT_EQ(USB_SYNCHRONIZATION_NONE, config.interfaces[0].endpoints[2].synchronization_type); - EXPECT_EQ(USB_TRANSFER_INTERRUPT, + EXPECT_EQ(UsbTransferType::INTERRUPT, config.interfaces[0].endpoints[2].transfer_type); EXPECT_EQ(USB_USAGE_NOTIFICATION, config.interfaces[0].endpoints[2].usage_type); @@ -157,23 +160,24 @@ EXPECT_EQ(0, config.interfaces[1].first_interface); // Endpoint 1 IN EXPECT_EQ(0x81, config.interfaces[1].endpoints[0].address); - EXPECT_EQ(USB_DIRECTION_INBOUND, config.interfaces[1].endpoints[0].direction); + EXPECT_EQ(UsbTransferDirection::INBOUND, + config.interfaces[1].endpoints[0].direction); EXPECT_EQ(1024, config.interfaces[1].endpoints[0].maximum_packet_size); EXPECT_EQ(USB_SYNCHRONIZATION_NONE, config.interfaces[1].endpoints[0].synchronization_type); - EXPECT_EQ(USB_TRANSFER_ISOCHRONOUS, + EXPECT_EQ(UsbTransferType::ISOCHRONOUS, config.interfaces[1].endpoints[0].transfer_type); EXPECT_EQ(USB_USAGE_DATA, config.interfaces[1].endpoints[0].usage_type); EXPECT_EQ(8, config.interfaces[1].endpoints[0].polling_interval); EXPECT_EQ(0u, config.interfaces[1].endpoints[0].extra_data.size()); // Endpoint 2 OUT EXPECT_EQ(0x02, config.interfaces[1].endpoints[1].address); - EXPECT_EQ(USB_DIRECTION_OUTBOUND, + EXPECT_EQ(UsbTransferDirection::OUTBOUND, config.interfaces[1].endpoints[1].direction); EXPECT_EQ(1024, config.interfaces[1].endpoints[1].maximum_packet_size); EXPECT_EQ(USB_SYNCHRONIZATION_NONE, config.interfaces[1].endpoints[1].synchronization_type); - EXPECT_EQ(USB_TRANSFER_ISOCHRONOUS, + EXPECT_EQ(UsbTransferType::ISOCHRONOUS, config.interfaces[1].endpoints[1].transfer_type); EXPECT_EQ(USB_USAGE_FEEDBACK, config.interfaces[1].endpoints[1].usage_type); EXPECT_EQ(8, config.interfaces[1].endpoints[1].polling_interval); @@ -219,21 +223,24 @@ scoped_refptr<MockUsbDeviceHandle> device_handle( new MockUsbDeviceHandle(nullptr)); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0100, 0x0000, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0100, + 0x0000, _, _, _, _)) .WillOnce(InvokeCallback(kDeviceDescriptor, sizeof(kDeviceDescriptor))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0200, 0x0000, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0200, + 0x0000, _, _, _, _)) .Times(2) .WillRepeatedly( InvokeCallback(kConfig1Descriptor, sizeof(kConfig1Descriptor))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0201, 0x0000, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0201, + 0x0000, _, _, _, _)) .Times(2) .WillRepeatedly( InvokeCallback(kConfig2Descriptor, sizeof(kConfig2Descriptor))); @@ -400,33 +407,37 @@ new MockUsbDeviceHandle(nullptr)); static const uint8_t kStringDescriptor0[] = {0x04, 0x03, 0x21, 0x43}; EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0300, 0x0000, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0300, + 0x0000, _, _, _, _)) .WillOnce(InvokeCallback(kStringDescriptor0, sizeof(kStringDescriptor0))); static const uint8_t kStringDescriptor1[] = {0x12, 0x03, 'S', 0, 't', 0, 'r', 0, 'i', 0, 'n', 0, 'g', 0, ' ', 0, '1', 0}; EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0301, 0x4321, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0301, + 0x4321, _, _, _, _)) .WillOnce(InvokeCallback(kStringDescriptor1, sizeof(kStringDescriptor1))); static const uint8_t kStringDescriptor2[] = {0x12, 0x03, 'S', 0, 't', 0, 'r', 0, 'i', 0, 'n', 0, 'g', 0, ' ', 0, '2', 0}; EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0302, 0x4321, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0302, + 0x4321, _, _, _, _)) .WillOnce(InvokeCallback(kStringDescriptor2, sizeof(kStringDescriptor2))); static const uint8_t kStringDescriptor3[] = {0x12, 0x03, 'S', 0, 't', 0, 'r', 0, 'i', 0, 'n', 0, 'g', 0, ' ', 0, '3', 0}; EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0303, 0x4321, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0303, + 0x4321, _, _, _, _)) .WillOnce(InvokeCallback(kStringDescriptor3, sizeof(kStringDescriptor3))); ReadUsbStringDescriptors(device_handle, std::move(string_map),
diff --git a/device/usb/usb_device_handle.h b/device/usb/usb_device_handle.h index 32d25f3..d592a8d4 100644 --- a/device/usb/usb_device_handle.h +++ b/device/usb/usb_device_handle.h
@@ -16,6 +16,7 @@ #include "base/memory/ref_counted.h" #include "base/strings/string16.h" #include "base/threading/thread_checker.h" +#include "device/usb/public/interfaces/device.mojom.h" #include "device/usb/usb_descriptors.h" namespace net { @@ -26,16 +27,9 @@ class UsbDevice; -enum UsbTransferStatus { - USB_TRANSFER_COMPLETED = 0, - USB_TRANSFER_ERROR, - USB_TRANSFER_TIMEOUT, - USB_TRANSFER_CANCELLED, - USB_TRANSFER_STALLED, - USB_TRANSFER_DISCONNECT, - USB_TRANSFER_OVERFLOW, - USB_TRANSFER_LENGTH_SHORT, -}; +using UsbTransferStatus = mojom::UsbTransferStatus; +using UsbControlTransferType = mojom::UsbControlTransferType; +using UsbControlTransferRecipient = mojom::UsbControlTransferRecipient; // UsbDeviceHandle class provides basic I/O related functionalities. class UsbDeviceHandle : public base::RefCountedThreadSafe<UsbDeviceHandle> { @@ -53,9 +47,6 @@ base::Callback<void(scoped_refptr<net::IOBuffer>, const std::vector<IsochronousPacket>& packets)>; - enum TransferRequestType { STANDARD, CLASS, VENDOR, RESERVED }; - enum TransferRecipient { DEVICE, INTERFACE, ENDPOINT, OTHER }; - virtual scoped_refptr<UsbDevice> GetDevice() const = 0; // Notifies UsbDevice to drop the reference of this object; cancels all the @@ -80,9 +71,9 @@ // The transfer functions may be called from any thread. The provided callback // will be run on the caller's thread. - virtual void ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + virtual void ControlTransfer(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -104,7 +95,7 @@ unsigned int timeout, const IsochronousTransferCallback& callback) = 0; - virtual void GenericTransfer(UsbEndpointDirection direction, + virtual void GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length,
diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc index d8b28a9..ee398ed 100644 --- a/device/usb/usb_device_handle_impl.cc +++ b/device/usb/usb_device_handle_impl.cc
@@ -35,49 +35,48 @@ namespace { -uint8_t ConvertTransferDirection(UsbEndpointDirection direction) { +uint8_t ConvertTransferDirection(UsbTransferDirection direction) { switch (direction) { - case USB_DIRECTION_INBOUND: + case UsbTransferDirection::INBOUND: return LIBUSB_ENDPOINT_IN; - case USB_DIRECTION_OUTBOUND: + case UsbTransferDirection::OUTBOUND: return LIBUSB_ENDPOINT_OUT; - default: - NOTREACHED(); - return LIBUSB_ENDPOINT_IN; } + NOTREACHED(); + return 0; } -uint8_t CreateRequestType(UsbEndpointDirection direction, - UsbDeviceHandle::TransferRequestType request_type, - UsbDeviceHandle::TransferRecipient recipient) { +uint8_t CreateRequestType(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient) { uint8_t result = ConvertTransferDirection(direction); switch (request_type) { - case UsbDeviceHandle::STANDARD: + case UsbControlTransferType::STANDARD: result |= LIBUSB_REQUEST_TYPE_STANDARD; break; - case UsbDeviceHandle::CLASS: + case UsbControlTransferType::CLASS: result |= LIBUSB_REQUEST_TYPE_CLASS; break; - case UsbDeviceHandle::VENDOR: + case UsbControlTransferType::VENDOR: result |= LIBUSB_REQUEST_TYPE_VENDOR; break; - case UsbDeviceHandle::RESERVED: + case UsbControlTransferType::RESERVED: result |= LIBUSB_REQUEST_TYPE_RESERVED; break; } switch (recipient) { - case UsbDeviceHandle::DEVICE: + case UsbControlTransferRecipient::DEVICE: result |= LIBUSB_RECIPIENT_DEVICE; break; - case UsbDeviceHandle::INTERFACE: + case UsbControlTransferRecipient::INTERFACE: result |= LIBUSB_RECIPIENT_INTERFACE; break; - case UsbDeviceHandle::ENDPOINT: + case UsbControlTransferRecipient::ENDPOINT: result |= LIBUSB_RECIPIENT_ENDPOINT; break; - case UsbDeviceHandle::OTHER: + case UsbControlTransferRecipient::OTHER: result |= LIBUSB_RECIPIENT_OTHER; break; } @@ -89,23 +88,22 @@ const libusb_transfer_status status) { switch (status) { case LIBUSB_TRANSFER_COMPLETED: - return USB_TRANSFER_COMPLETED; + return UsbTransferStatus::COMPLETED; case LIBUSB_TRANSFER_ERROR: - return USB_TRANSFER_ERROR; + return UsbTransferStatus::TRANSFER_ERROR; case LIBUSB_TRANSFER_TIMED_OUT: - return USB_TRANSFER_TIMEOUT; + return UsbTransferStatus::TIMEOUT; case LIBUSB_TRANSFER_STALL: - return USB_TRANSFER_STALLED; + return UsbTransferStatus::STALLED; case LIBUSB_TRANSFER_NO_DEVICE: - return USB_TRANSFER_DISCONNECT; + return UsbTransferStatus::DISCONNECT; case LIBUSB_TRANSFER_OVERFLOW: - return USB_TRANSFER_OVERFLOW; + return UsbTransferStatus::BABBLE; case LIBUSB_TRANSFER_CANCELLED: - return USB_TRANSFER_CANCELLED; - default: - NOTREACHED(); - return USB_TRANSFER_ERROR; + return UsbTransferStatus::CANCELLED; } + NOTREACHED(); + return UsbTransferStatus::TRANSFER_ERROR; } static void RunTransferCallback( @@ -298,7 +296,7 @@ scoped_refptr<base::TaskRunner> callback_task_runner, const TransferCallback& callback) { std::unique_ptr<Transfer> transfer(new Transfer( - device_handle, nullptr, USB_TRANSFER_CONTROL, buffer, + device_handle, nullptr, UsbTransferType::CONTROL, buffer, length + LIBUSB_CONTROL_SETUP_SIZE, callback_task_runner, callback)); transfer->platform_transfer_ = libusb_alloc_transfer(0); @@ -330,7 +328,7 @@ const TransferCallback& callback) { std::unique_ptr<Transfer> transfer(new Transfer( device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), - USB_TRANSFER_BULK, buffer, length, callback_task_runner, callback)); + UsbTransferType::BULK, buffer, length, callback_task_runner, callback)); transfer->platform_transfer_ = libusb_alloc_transfer(0); if (!transfer->platform_transfer_) { @@ -359,7 +357,8 @@ const TransferCallback& callback) { std::unique_ptr<Transfer> transfer(new Transfer( device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), - USB_TRANSFER_INTERRUPT, buffer, length, callback_task_runner, callback)); + UsbTransferType::INTERRUPT, buffer, length, callback_task_runner, + callback)); transfer->platform_transfer_ = libusb_alloc_transfer(0); if (!transfer->platform_transfer_) { @@ -433,7 +432,7 @@ scoped_refptr<net::IOBuffer> buffer, scoped_refptr<base::TaskRunner> callback_task_runner, const IsochronousTransferCallback& callback) - : transfer_type_(USB_TRANSFER_ISOCHRONOUS), + : transfer_type_(UsbTransferType::ISOCHRONOUS), device_handle_(device_handle), buffer_(buffer), claimed_interface_(claimed_interface), @@ -453,7 +452,7 @@ if (rv != LIBUSB_SUCCESS) { USB_LOG(EVENT) << "Failed to submit transfer: " << ConvertPlatformUsbErrorToString(rv); - TransferComplete(USB_TRANSFER_ERROR, 0); + TransferComplete(UsbTransferStatus::TRANSFER_ERROR, 0); } } @@ -475,7 +474,7 @@ << "data too big for our buffer (libusb failure?)"; switch (transfer_type_) { - case USB_TRANSFER_CONTROL: + case UsbTransferType::CONTROL: // If the transfer is a control transfer we do not expose the control // setup header to the caller. This logic strips off the header if // present before invoking the callback provided with the transfer. @@ -495,13 +494,13 @@ } // Fall through! - case USB_TRANSFER_BULK: - case USB_TRANSFER_INTERRUPT: + case UsbTransferType::BULK: + case UsbTransferType::INTERRUPT: TransferComplete(ConvertTransferStatus(platform_transfer_->status), actual_length); break; - case USB_TRANSFER_ISOCHRONOUS: + case UsbTransferType::ISOCHRONOUS: IsochronousTransferComplete(); break; @@ -523,7 +522,7 @@ void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status, size_t bytes_transferred) { base::Closure closure; - if (transfer_type_ == USB_TRANSFER_ISOCHRONOUS) { + if (transfer_type_ == UsbTransferType::ISOCHRONOUS) { DCHECK_NE(LIBUSB_TRANSFER_COMPLETED, platform_transfer_->status); std::vector<IsochronousPacket> packets(platform_transfer_->num_iso_packets); for (size_t i = 0; i < packets.size(); ++i) { @@ -697,9 +696,9 @@ this, endpoint, callback)); } -void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, +void UsbDeviceHandleImpl::ControlTransfer(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -726,7 +725,7 @@ unsigned int timeout, const IsochronousTransferCallback& callback) { uint8_t endpoint_address = - ConvertTransferDirection(USB_DIRECTION_INBOUND) | endpoint_number; + ConvertTransferDirection(UsbTransferDirection::INBOUND) | endpoint_number; if (task_runner_->BelongsToCurrentThread()) { IsochronousTransferInInternal(endpoint_address, packet_lengths, timeout, task_runner_, callback); @@ -746,7 +745,8 @@ unsigned int timeout, const IsochronousTransferCallback& callback) { uint8_t endpoint_address = - ConvertTransferDirection(USB_DIRECTION_OUTBOUND) | endpoint_number; + ConvertTransferDirection(UsbTransferDirection::OUTBOUND) | + endpoint_number; if (task_runner_->BelongsToCurrentThread()) { IsochronousTransferOutInternal(endpoint_address, buffer, packet_lengths, timeout, task_runner_, callback); @@ -759,7 +759,7 @@ } } -void UsbDeviceHandleImpl::GenericTransfer(UsbEndpointDirection direction, +void UsbDeviceHandleImpl::GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length, @@ -969,9 +969,9 @@ } void UsbDeviceHandleImpl::ControlTransferInternal( - UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -983,15 +983,15 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!device_) { - RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT, - buffer, 0); + RunTransferCallback(callback_task_runner, callback, + UsbTransferStatus::DISCONNECT, buffer, 0); return; } if (!base::IsValueInRangeForNumericType<uint16_t>(length)) { USB_LOG(USER) << "Transfer too long."; - RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, - buffer, 0); + RunTransferCallback(callback_task_runner, callback, + UsbTransferStatus::TRANSFER_ERROR, buffer, 0); return; } @@ -999,8 +999,8 @@ scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBufferWithSize(resized_length); if (!resized_buffer.get()) { - RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, - buffer, 0); + RunTransferCallback(callback_task_runner, callback, + UsbTransferStatus::TRANSFER_ERROR, buffer, 0); return; } memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), @@ -1011,8 +1011,8 @@ value, index, static_cast<uint16_t>(length), resized_buffer, timeout, callback_task_runner, callback); if (!transfer) { - RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, - buffer, 0); + RunTransferCallback(callback_task_runner, callback, + UsbTransferStatus::TRANSFER_ERROR, buffer, 0); return; } @@ -1029,7 +1029,8 @@ if (!device_) { ReportIsochronousTransferError(callback_task_runner, callback, - packet_lengths, USB_TRANSFER_DISCONNECT); + packet_lengths, + UsbTransferStatus::DISCONNECT); return; } @@ -1054,7 +1055,8 @@ if (!device_) { ReportIsochronousTransferError(callback_task_runner, callback, - packet_lengths, USB_TRANSFER_DISCONNECT); + packet_lengths, + UsbTransferStatus::DISCONNECT); return; } @@ -1077,8 +1079,8 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!device_) { - RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT, - buffer, 0); + RunTransferCallback(callback_task_runner, callback, + UsbTransferStatus::DISCONNECT, buffer, 0); return; } @@ -1087,33 +1089,33 @@ USB_LOG(DEBUG) << "Failed to submit transfer because endpoint " << static_cast<int>(endpoint_address) << " not part of a claimed interface."; - RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, - buffer, 0); + RunTransferCallback(callback_task_runner, callback, + UsbTransferStatus::TRANSFER_ERROR, buffer, 0); return; } if (!base::IsValueInRangeForNumericType<int>(length)) { USB_LOG(DEBUG) << "Transfer too long."; - RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, - buffer, 0); + RunTransferCallback(callback_task_runner, callback, + UsbTransferStatus::TRANSFER_ERROR, buffer, 0); return; } std::unique_ptr<Transfer> transfer; UsbTransferType transfer_type = endpoint_it->second.endpoint->transfer_type; - if (transfer_type == USB_TRANSFER_BULK) { + if (transfer_type == UsbTransferType::BULK) { transfer = Transfer::CreateBulkTransfer(this, endpoint_address, buffer, static_cast<int>(length), timeout, callback_task_runner, callback); - } else if (transfer_type == USB_TRANSFER_INTERRUPT) { + } else if (transfer_type == UsbTransferType::INTERRUPT) { transfer = Transfer::CreateInterruptTransfer( this, endpoint_address, buffer, static_cast<int>(length), timeout, callback_task_runner, callback); } else { USB_LOG(DEBUG) << "Endpoint " << static_cast<int>(endpoint_address) << " is not a bulk or interrupt endpoint."; - RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, - buffer, 0); + RunTransferCallback(callback_task_runner, callback, + UsbTransferStatus::TRANSFER_ERROR, buffer, 0); return; }
diff --git a/device/usb/usb_device_handle_impl.h b/device/usb/usb_device_handle_impl.h index 4d3401a..1322e19 100644 --- a/device/usb/usb_device_handle_impl.h +++ b/device/usb/usb_device_handle_impl.h
@@ -61,9 +61,9 @@ void ResetDevice(const ResultCallback& callback) override; void ClearHalt(uint8_t endpoint, const ResultCallback& callback) override; - void ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + void ControlTransfer(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -85,7 +85,7 @@ unsigned int timeout, const IsochronousTransferCallback& callback) override; - void GenericTransfer(UsbEndpointDirection direction, + void GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length, @@ -141,9 +141,9 @@ uint8_t endpoint); void ControlTransferInternal( - UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index,
diff --git a/device/usb/usb_device_handle_unittest.cc b/device/usb/usb_device_handle_unittest.cc index ab20c41..20a76e4f 100644 --- a/device/usb/usb_device_handle_unittest.cc +++ b/device/usb/usb_device_handle_unittest.cc
@@ -147,7 +147,7 @@ scoped_refptr<net::IOBufferWithSize> in_buffer(new net::IOBufferWithSize(64)); TestCompletionCallback in_completion; - handle->GenericTransfer(USB_DIRECTION_INBOUND, 0x81, in_buffer.get(), + handle->GenericTransfer(UsbTransferDirection::INBOUND, 0x81, in_buffer.get(), in_buffer->size(), 5000, // 5 second timeout in_completion.callback()); @@ -159,17 +159,17 @@ out_buffer->data()[i] = i; } - handle->GenericTransfer(USB_DIRECTION_OUTBOUND, 0x01, out_buffer.get(), - out_buffer->size(), + handle->GenericTransfer(UsbTransferDirection::OUTBOUND, 0x01, + out_buffer.get(), out_buffer->size(), 5000, // 5 second timeout out_completion.callback()); out_completion.WaitForResult(); - ASSERT_EQ(USB_TRANSFER_COMPLETED, out_completion.status()); + ASSERT_EQ(UsbTransferStatus::COMPLETED, out_completion.status()); EXPECT_EQ(static_cast<size_t>(out_buffer->size()), out_completion.transferred()); in_completion.WaitForResult(); - ASSERT_EQ(USB_TRANSFER_COMPLETED, in_completion.status()); + ASSERT_EQ(UsbTransferStatus::COMPLETED, in_completion.status()); EXPECT_EQ(static_cast<size_t>(in_buffer->size()), in_completion.transferred()); for (size_t i = 0; i < in_completion.transferred(); ++i) { @@ -216,7 +216,7 @@ scoped_refptr<net::IOBufferWithSize> in_buffer( new net::IOBufferWithSize(512)); TestCompletionCallback in_completion; - handle->GenericTransfer(USB_DIRECTION_INBOUND, 0x82, in_buffer.get(), + handle->GenericTransfer(UsbTransferDirection::INBOUND, 0x82, in_buffer.get(), in_buffer->size(), 5000, // 5 second timeout in_completion.callback()); @@ -228,17 +228,17 @@ out_buffer->data()[i] = i; } - handle->GenericTransfer(USB_DIRECTION_OUTBOUND, 0x02, out_buffer.get(), - out_buffer->size(), + handle->GenericTransfer(UsbTransferDirection::OUTBOUND, 0x02, + out_buffer.get(), out_buffer->size(), 5000, // 5 second timeout out_completion.callback()); out_completion.WaitForResult(); - ASSERT_EQ(USB_TRANSFER_COMPLETED, out_completion.status()); + ASSERT_EQ(UsbTransferStatus::COMPLETED, out_completion.status()); EXPECT_EQ(static_cast<size_t>(out_buffer->size()), out_completion.transferred()); in_completion.WaitForResult(); - ASSERT_EQ(USB_TRANSFER_COMPLETED, in_completion.status()); + ASSERT_EQ(UsbTransferStatus::COMPLETED, in_completion.status()); EXPECT_EQ(static_cast<size_t>(in_buffer->size()), in_completion.transferred()); for (size_t i = 0; i < in_completion.transferred(); ++i) { @@ -268,11 +268,12 @@ scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(255)); TestCompletionCallback completion; - handle->ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0301, 0x0409, buffer, - buffer->size(), 0, completion.callback()); + handle->ControlTransfer( + UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0301, 0x0409, buffer, + buffer->size(), 0, completion.callback()); completion.WaitForResult(); - ASSERT_EQ(USB_TRANSFER_COMPLETED, completion.status()); + ASSERT_EQ(UsbTransferStatus::COMPLETED, completion.status()); const char expected_str[] = "\x18\x03G\0o\0o\0g\0l\0e\0 \0I\0n\0c\0.\0"; EXPECT_EQ(sizeof(expected_str) - 1, completion.transferred()); for (size_t i = 0; i < completion.transferred(); ++i) { @@ -334,14 +335,14 @@ scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(512)); TestCompletionCallback completion; - handle->GenericTransfer(USB_DIRECTION_INBOUND, 0x82, buffer.get(), + handle->GenericTransfer(UsbTransferDirection::INBOUND, 0x82, buffer.get(), buffer->size(), 5000, // 5 second timeout completion.callback()); handle->Close(); completion.WaitForResult(); - ASSERT_EQ(USB_TRANSFER_CANCELLED, completion.status()); + ASSERT_EQ(UsbTransferStatus::CANCELLED, completion.status()); } TEST_F(UsbDeviceHandleTest, CancelOnDisconnect) { @@ -365,14 +366,14 @@ scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(512)); TestCompletionCallback completion; - handle->GenericTransfer(USB_DIRECTION_INBOUND, 0x82, buffer.get(), + handle->GenericTransfer(UsbTransferDirection::INBOUND, 0x82, buffer.get(), buffer->size(), 5000, // 5 second timeout completion.callback()); ASSERT_TRUE(gadget->Disconnect()); completion.WaitForResult(); - ASSERT_EQ(USB_TRANSFER_DISCONNECT, completion.status()); + ASSERT_EQ(UsbTransferStatus::DISCONNECT, completion.status()); handle->Close(); } @@ -398,13 +399,13 @@ scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(512)); TestCompletionCallback completion; - handle->GenericTransfer(USB_DIRECTION_INBOUND, 0x82, buffer.get(), + handle->GenericTransfer(UsbTransferDirection::INBOUND, 0x82, buffer.get(), buffer->size(), 10, // 10 millisecond timeout completion.callback()); completion.WaitForResult(); - ASSERT_EQ(USB_TRANSFER_TIMEOUT, completion.status()); + ASSERT_EQ(UsbTransferStatus::TIMEOUT, completion.status()); handle->Close(); }
diff --git a/device/usb/usb_device_handle_usbfs.cc b/device/usb/usb_device_handle_usbfs.cc index 6871cdc..d168e2f 100644 --- a/device/usb/usb_device_handle_usbfs.cc +++ b/device/usb/usb_device_handle_usbfs.cc
@@ -32,41 +32,41 @@ namespace { -uint8_t ConvertEndpointDirection(UsbEndpointDirection direction) { +uint8_t ConvertEndpointDirection(UsbTransferDirection direction) { switch (direction) { - case USB_DIRECTION_INBOUND: + case UsbTransferDirection::INBOUND: return USB_DIR_IN; - case USB_DIRECTION_OUTBOUND: + case UsbTransferDirection::OUTBOUND: return USB_DIR_OUT; } NOTREACHED(); return 0; } -uint8_t ConvertRequestType(UsbDeviceHandle::TransferRequestType request_type) { +uint8_t ConvertRequestType(UsbControlTransferType request_type) { switch (request_type) { - case UsbDeviceHandle::STANDARD: + case UsbControlTransferType::STANDARD: return USB_TYPE_STANDARD; - case UsbDeviceHandle::CLASS: + case UsbControlTransferType::CLASS: return USB_TYPE_CLASS; - case UsbDeviceHandle::VENDOR: + case UsbControlTransferType::VENDOR: return USB_TYPE_VENDOR; - case UsbDeviceHandle::RESERVED: + case UsbControlTransferType::RESERVED: return USB_TYPE_RESERVED; } NOTREACHED(); return 0; } -uint8_t ConvertRecipient(UsbDeviceHandle::TransferRecipient recipient) { +uint8_t ConvertRecipient(UsbControlTransferRecipient recipient) { switch (recipient) { - case UsbDeviceHandle::DEVICE: + case UsbControlTransferRecipient::DEVICE: return USB_RECIP_DEVICE; - case UsbDeviceHandle::INTERFACE: + case UsbControlTransferRecipient::INTERFACE: return USB_RECIP_INTERFACE; - case UsbDeviceHandle::ENDPOINT: + case UsbControlTransferRecipient::ENDPOINT: return USB_RECIP_ENDPOINT; - case UsbDeviceHandle::OTHER: + case UsbControlTransferRecipient::OTHER: return USB_RECIP_OTHER; } NOTREACHED(); @@ -74,9 +74,9 @@ } scoped_refptr<net::IOBuffer> BuildControlTransferBuffer( - UsbEndpointDirection direction, - UsbDeviceHandle::TransferRequestType request_type, - UsbDeviceHandle::TransferRecipient recipient, + UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -100,13 +100,13 @@ uint8_t ConvertTransferType(UsbTransferType type) { switch (type) { - case USB_TRANSFER_CONTROL: + case UsbTransferType::CONTROL: return USBDEVFS_URB_TYPE_CONTROL; - case USB_TRANSFER_ISOCHRONOUS: + case UsbTransferType::ISOCHRONOUS: return USBDEVFS_URB_TYPE_ISO; - case USB_TRANSFER_BULK: + case UsbTransferType::BULK: return USBDEVFS_URB_TYPE_BULK; - case USB_TRANSFER_INTERRUPT: + case UsbTransferType::INTERRUPT: return USBDEVFS_URB_TYPE_INTERRUPT; } NOTREACHED(); @@ -116,19 +116,19 @@ UsbTransferStatus ConvertTransferResult(int rc) { switch (rc) { case 0: - return USB_TRANSFER_COMPLETED; + return UsbTransferStatus::COMPLETED; case EPIPE: - return USB_TRANSFER_STALLED; + return UsbTransferStatus::STALLED; case ENODEV: case ESHUTDOWN: case EPROTO: - return USB_TRANSFER_DISCONNECT; + return UsbTransferStatus::DISCONNECT; default: // TODO(reillyg): Add a specific error message whenever one of the cases // above fails to match. USB_LOG(ERROR) << "Unknown system error: " << logging::SystemErrorCodeToString(rc); - return USB_TRANSFER_ERROR; + return UsbTransferStatus::TRANSFER_ERROR; } } @@ -437,7 +437,7 @@ device_ = nullptr; for (const auto& transfer : transfers_) - CancelTransfer(transfer.get(), USB_TRANSFER_CANCELLED); + CancelTransfer(transfer.get(), UsbTransferStatus::CANCELLED); // Releases |helper_|. blocking_task_runner_->PostTask( @@ -551,19 +551,21 @@ base::Unretained(helper_.get()), endpoint_address, callback)); } -void UsbDeviceHandleUsbfs::ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, - uint8_t request, - uint16_t value, - uint16_t index, - scoped_refptr<net::IOBuffer> buffer, - size_t length, - unsigned int timeout, - const TransferCallback& callback) { +void UsbDeviceHandleUsbfs::ControlTransfer( + UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, + uint8_t request, + uint16_t value, + uint16_t index, + scoped_refptr<net::IOBuffer> buffer, + size_t length, + unsigned int timeout, + const TransferCallback& callback) { if (!device_) { task_runner_->PostTask( - FROM_HERE, base::Bind(callback, USB_TRANSFER_DISCONNECT, nullptr, 0)); + FROM_HERE, + base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); return; } @@ -617,7 +619,7 @@ packet_lengths, timeout, callback); } -void UsbDeviceHandleUsbfs::GenericTransfer(UsbEndpointDirection direction, +void UsbDeviceHandleUsbfs::GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length, @@ -689,7 +691,8 @@ unsigned int timeout, const IsochronousTransferCallback& callback) { if (!device_) { - ReportIsochronousError(packet_lengths, callback, USB_TRANSFER_DISCONNECT); + ReportIsochronousError(packet_lengths, callback, + UsbTransferStatus::DISCONNECT); return; } @@ -697,7 +700,8 @@ if (it == endpoints_.end()) { USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) << " is not part of a claimed interface."; - ReportIsochronousError(packet_lengths, callback, USB_TRANSFER_ERROR); + ReportIsochronousError(packet_lengths, callback, + UsbTransferStatus::TRANSFER_ERROR); return; } @@ -726,7 +730,7 @@ } void UsbDeviceHandleUsbfs::GenericTransferInternal( - UsbEndpointDirection direction, + UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length, @@ -735,7 +739,8 @@ scoped_refptr<base::SingleThreadTaskRunner> callback_runner) { if (!device_) { callback_runner->PostTask( - FROM_HERE, base::Bind(callback, USB_TRANSFER_DISCONNECT, nullptr, 0)); + FROM_HERE, + base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); return; } @@ -746,7 +751,8 @@ USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) << " is not part of a claimed interface."; callback_runner->PostTask( - FROM_HERE, base::Bind(callback, USB_TRANSFER_ERROR, nullptr, 0)); + FROM_HERE, + base::Bind(callback, UsbTransferStatus::TRANSFER_ERROR, nullptr, 0)); return; } @@ -867,7 +873,7 @@ if (timeout > 0) { transfer->timeout_closure.Reset( base::Bind(&UsbDeviceHandleUsbfs::CancelTransfer, this, transfer, - USB_TRANSFER_TIMEOUT)); + UsbTransferStatus::TIMEOUT)); task_runner_->PostDelayedTask(FROM_HERE, transfer->timeout_closure.callback(), base::TimeDelta::FromMilliseconds(timeout));
diff --git a/device/usb/usb_device_handle_usbfs.h b/device/usb/usb_device_handle_usbfs.h index e49de9b..a9bf1e27 100644 --- a/device/usb/usb_device_handle_usbfs.h +++ b/device/usb/usb_device_handle_usbfs.h
@@ -50,9 +50,9 @@ const ResultCallback& callback) override; void ResetDevice(const ResultCallback& callback) override; void ClearHalt(uint8_t endpoint, const ResultCallback& callback) override; - void ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + void ControlTransfer(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -73,7 +73,7 @@ const IsochronousTransferCallback& callback) override; // To support DevTools this function may be called from any thread and on // completion |callback| will be run on that thread. - void GenericTransfer(UsbEndpointDirection direction, + void GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length, @@ -119,7 +119,7 @@ unsigned int timeout, const IsochronousTransferCallback& callback); void GenericTransferInternal( - UsbEndpointDirection direction, + UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length,
diff --git a/device/usb/usb_device_handle_win.cc b/device/usb/usb_device_handle_win.cc index 74a7de6..f8a54a2 100644 --- a/device/usb/usb_device_handle_win.cc +++ b/device/usb/usb_device_handle_win.cc
@@ -158,9 +158,9 @@ } } -void UsbDeviceHandleWin::ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, +void UsbDeviceHandleWin::ControlTransfer(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -172,14 +172,15 @@ if (!device_) { task_runner_->PostTask( - FROM_HERE, base::Bind(callback, USB_TRANSFER_DISCONNECT, nullptr, 0)); + FROM_HERE, + base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); return; } if (hub_handle_.IsValid()) { - if (direction == USB_DIRECTION_INBOUND && - request_type == TransferRequestType::STANDARD && - recipient == TransferRecipient::DEVICE && + if (direction == UsbTransferDirection::INBOUND && + request_type == UsbControlTransferType::STANDARD && + recipient == UsbControlTransferRecipient::DEVICE && request == USB_REQUEST_GET_DESCRIPTOR) { if ((value >> 8) == USB_DEVICE_DESCRIPTOR_TYPE) { auto* node_connection_info = new USB_NODE_CONNECTION_INFORMATION_EX; @@ -225,13 +226,15 @@ // Unsupported transfer for hub. task_runner_->PostTask( - FROM_HERE, base::Bind(callback, USB_TRANSFER_ERROR, nullptr, 0)); + FROM_HERE, + base::Bind(callback, UsbTransferStatus::TRANSFER_ERROR, nullptr, 0)); return; } // Regular control transfers unimplemented. - task_runner_->PostTask(FROM_HERE, - base::Bind(callback, USB_TRANSFER_ERROR, nullptr, 0)); + task_runner_->PostTask( + FROM_HERE, + base::Bind(callback, UsbTransferStatus::TRANSFER_ERROR, nullptr, 0)); } void UsbDeviceHandleWin::IsochronousTransferIn( @@ -251,7 +254,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); } -void UsbDeviceHandleWin::GenericTransfer(UsbEndpointDirection direction, +void UsbDeviceHandleWin::GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length, @@ -310,7 +313,7 @@ if (win32_result != ERROR_SUCCESS) { SetLastError(win32_result); USB_PLOG(ERROR) << "Failed to get node connection information"; - callback.Run(USB_TRANSFER_ERROR, nullptr, 0); + callback.Run(UsbTransferStatus::TRANSFER_ERROR, nullptr, 0); return; } @@ -318,7 +321,7 @@ bytes_transferred = std::min(sizeof(USB_DEVICE_DESCRIPTOR), buffer_length); memcpy(buffer->data(), &node_connection_info->DeviceDescriptor, bytes_transferred); - callback.Run(USB_TRANSFER_COMPLETED, buffer, bytes_transferred); + callback.Run(UsbTransferStatus::COMPLETED, buffer, bytes_transferred); } void UsbDeviceHandleWin::GotDescriptorFromNodeConnection( @@ -334,7 +337,7 @@ if (win32_result != ERROR_SUCCESS) { SetLastError(win32_result); USB_PLOG(ERROR) << "Failed to read descriptor from node connection"; - callback.Run(USB_TRANSFER_ERROR, nullptr, 0); + callback.Run(UsbTransferStatus::TRANSFER_ERROR, nullptr, 0); return; } @@ -343,7 +346,8 @@ memcpy(original_buffer->data(), request_buffer->data() + sizeof(USB_DESCRIPTOR_REQUEST), bytes_transferred); - callback.Run(USB_TRANSFER_COMPLETED, original_buffer, bytes_transferred); + callback.Run(UsbTransferStatus::COMPLETED, original_buffer, + bytes_transferred); } } // namespace device
diff --git a/device/usb/usb_device_handle_win.h b/device/usb/usb_device_handle_win.h index 69e6e28..75b65f6 100644 --- a/device/usb/usb_device_handle_win.h +++ b/device/usb/usb_device_handle_win.h
@@ -46,9 +46,9 @@ void ResetDevice(const ResultCallback& callback) override; void ClearHalt(uint8_t endpoint, const ResultCallback& callback) override; - void ControlTransfer(UsbEndpointDirection direction, - TransferRequestType request_type, - TransferRecipient recipient, + void ControlTransfer(UsbTransferDirection direction, + UsbControlTransferType request_type, + UsbControlTransferRecipient recipient, uint8_t request, uint16_t value, uint16_t index, @@ -70,7 +70,7 @@ unsigned int timeout, const IsochronousTransferCallback& callback) override; - void GenericTransfer(UsbEndpointDirection direction, + void GenericTransfer(UsbTransferDirection direction, uint8_t endpoint_number, scoped_refptr<net::IOBuffer> buffer, size_t length,
diff --git a/device/usb/webusb_descriptors.cc b/device/usb/webusb_descriptors.cc index 1bc243d..e2ebc14 100644 --- a/device/usb/webusb_descriptors.cc +++ b/device/usb/webusb_descriptors.cc
@@ -192,7 +192,7 @@ UsbTransferStatus status, scoped_refptr<net::IOBuffer> buffer, size_t length) { - if (status != USB_TRANSFER_COMPLETED) { + if (status != UsbTransferStatus::COMPLETED) { USB_LOG(EVENT) << "Failed to read WebUSB URL descriptor: " << index; callback.Run(); return; @@ -216,9 +216,9 @@ const base::Closure& callback) { scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(255); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, UsbDeviceHandle::DEVICE, - vendor_code, index, kGetUrlRequest, buffer, buffer->size(), - kControlTransferTimeout, + UsbTransferDirection::INBOUND, UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, vendor_code, index, kGetUrlRequest, + buffer, buffer->size(), kControlTransferTimeout, base::Bind(&OnReadUrlDescriptor, url_map, index, callback)); } @@ -265,7 +265,7 @@ UsbTransferStatus status, scoped_refptr<net::IOBuffer> buffer, size_t length) { - if (status != USB_TRANSFER_COMPLETED) { + if (status != UsbTransferStatus::COMPLETED) { USB_LOG(EVENT) << "Failed to read WebUSB allowed origins."; callback.Run(nullptr); return; @@ -288,7 +288,7 @@ UsbTransferStatus status, scoped_refptr<net::IOBuffer> buffer, size_t length) { - if (status != USB_TRANSFER_COMPLETED || length != 4) { + if (status != UsbTransferStatus::COMPLETED || length != 4) { USB_LOG(EVENT) << "Failed to read WebUSB allowed origins header."; callback.Run(nullptr); return; @@ -298,8 +298,9 @@ uint16_t new_length = data[2] | (data[3] << 8); scoped_refptr<IOBufferWithSize> new_buffer = new IOBufferWithSize(new_length); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, UsbDeviceHandle::DEVICE, - vendor_code, 0, kGetAllowedOriginsRequest, new_buffer, new_buffer->size(), + UsbTransferDirection::INBOUND, UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, vendor_code, 0, + kGetAllowedOriginsRequest, new_buffer, new_buffer->size(), kControlTransferTimeout, base::Bind(&OnReadWebUsbAllowedOrigins, callback)); } @@ -310,8 +311,9 @@ const ReadWebUsbAllowedOriginsCallback& callback) { scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(4); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, UsbDeviceHandle::DEVICE, - vendor_code, 0, kGetAllowedOriginsRequest, buffer, buffer->size(), + UsbTransferDirection::INBOUND, UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, vendor_code, 0, + kGetAllowedOriginsRequest, buffer, buffer->size(), kControlTransferTimeout, base::Bind(&OnReadWebUsbAllowedOriginsHeader, device_handle, callback, vendor_code)); @@ -322,7 +324,7 @@ UsbTransferStatus status, scoped_refptr<net::IOBuffer> buffer, size_t length) { - if (status != USB_TRANSFER_COMPLETED) { + if (status != UsbTransferStatus::COMPLETED) { USB_LOG(EVENT) << "Failed to read BOS descriptor."; callback.Run(nullptr, GURL()); return; @@ -346,7 +348,7 @@ UsbTransferStatus status, scoped_refptr<net::IOBuffer> buffer, size_t length) { - if (status != USB_TRANSFER_COMPLETED || length != 5) { + if (status != UsbTransferStatus::COMPLETED || length != 5) { USB_LOG(EVENT) << "Failed to read BOS descriptor header."; callback.Run(nullptr, GURL()); return; @@ -356,9 +358,10 @@ uint16_t new_length = data[2] | (data[3] << 8); scoped_refptr<IOBufferWithSize> new_buffer = new IOBufferWithSize(new_length); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, UsbDeviceHandle::DEVICE, - kGetDescriptorRequest, kBosDescriptorType << 8, 0, new_buffer, - new_buffer->size(), kControlTransferTimeout, + UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, kGetDescriptorRequest, + kBosDescriptorType << 8, 0, new_buffer, new_buffer->size(), + kControlTransferTimeout, base::Bind(&OnReadBosDescriptor, device_handle, callback)); } @@ -568,8 +571,9 @@ const ReadWebUsbDescriptorsCallback& callback) { scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(5); device_handle->ControlTransfer( - USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, UsbDeviceHandle::DEVICE, - kGetDescriptorRequest, kBosDescriptorType << 8, 0, buffer, buffer->size(), + UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, kGetDescriptorRequest, + kBosDescriptorType << 8, 0, buffer, buffer->size(), kControlTransferTimeout, base::Bind(&OnReadBosDescriptorHeader, device_handle, callback)); }
diff --git a/device/usb/webusb_descriptors_unittest.cc b/device/usb/webusb_descriptors_unittest.cc index 8350a6d..d0fd216 100644 --- a/device/usb/webusb_descriptors_unittest.cc +++ b/device/usb/webusb_descriptors_unittest.cc
@@ -75,7 +75,7 @@ ACTION_P2(InvokeCallback, data, length) { size_t transferred_length = std::min(length, arg7); memcpy(arg6->data(), data, transferred_length); - arg9.Run(USB_TRANSFER_COMPLETED, arg6, transferred_length); + arg9.Run(UsbTransferStatus::COMPLETED, arg6, transferred_length); } void ExpectAllowedOriginsAndLandingPage( @@ -407,53 +407,61 @@ new MockUsbDeviceHandle(nullptr)); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 0x06, 0x0F00, 0x0000, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 0x06, 0x0F00, + 0x0000, _, _, _, _)) .Times(2) .WillRepeatedly( InvokeCallback(kExampleBosDescriptor, sizeof(kExampleBosDescriptor))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, - UsbDeviceHandle::DEVICE, 0x42, 0x0000, 0x0001, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, 0x42, 0x0000, + 0x0001, _, _, _, _)) .Times(2) .WillRepeatedly(InvokeCallback(kExampleAllowedOrigins, sizeof(kExampleAllowedOrigins))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, - UsbDeviceHandle::DEVICE, 0x42, 0x0001, 0x0002, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, 0x42, 0x0001, + 0x0002, _, _, _, _)) .WillOnce(InvokeCallback(kExampleUrlDescriptor1, sizeof(kExampleUrlDescriptor1))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, - UsbDeviceHandle::DEVICE, 0x42, 0x0002, 0x0002, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, 0x42, 0x0002, + 0x0002, _, _, _, _)) .WillOnce(InvokeCallback(kExampleUrlDescriptor2, sizeof(kExampleUrlDescriptor2))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, - UsbDeviceHandle::DEVICE, 0x42, 0x0003, 0x0002, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, 0x42, 0x0003, + 0x0002, _, _, _, _)) .WillOnce(InvokeCallback(kExampleUrlDescriptor3, sizeof(kExampleUrlDescriptor3))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, - UsbDeviceHandle::DEVICE, 0x42, 0x0004, 0x0002, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, 0x42, 0x0004, + 0x0002, _, _, _, _)) .WillOnce(InvokeCallback(kExampleUrlDescriptor4, sizeof(kExampleUrlDescriptor4))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, - UsbDeviceHandle::DEVICE, 0x42, 0x0005, 0x0002, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, 0x42, 0x0005, + 0x0002, _, _, _, _)) .WillOnce(InvokeCallback(kExampleUrlDescriptor5, sizeof(kExampleUrlDescriptor5))); EXPECT_CALL(*device_handle, - ControlTransfer(USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, - UsbDeviceHandle::DEVICE, 0x42, 0x0006, 0x0002, _, - _, _, _)) + ControlTransfer(UsbTransferDirection::INBOUND, + UsbControlTransferType::VENDOR, + UsbControlTransferRecipient::DEVICE, 0x42, 0x0006, + 0x0002, _, _, _, _)) .WillOnce(InvokeCallback(kExampleUrlDescriptor6, sizeof(kExampleUrlDescriptor6)));
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn index 05a3377..5392ebd 100644 --- a/extensions/browser/api/BUILD.gn +++ b/extensions/browser/api/BUILD.gn
@@ -102,7 +102,6 @@ "//device/hid", "//device/power_save_blocker", "//device/serial", - "//device/usb", ] if (is_chromeos) {
diff --git a/extensions/browser/api/printer_provider/BUILD.gn b/extensions/browser/api/printer_provider/BUILD.gn index 0b242a0..b730331 100644 --- a/extensions/browser/api/printer_provider/BUILD.gn +++ b/extensions/browser/api/printer_provider/BUILD.gn
@@ -13,6 +13,7 @@ ] deps = [ + "//device/usb", "//extensions/common/api", ] }
diff --git a/extensions/browser/api/usb/BUILD.gn b/extensions/browser/api/usb/BUILD.gn index ceb5094..925e761 100644 --- a/extensions/browser/api/usb/BUILD.gn +++ b/extensions/browser/api/usb/BUILD.gn
@@ -22,6 +22,7 @@ deps = [ "//content/public/browser", "//content/public/common", + "//device/usb", "//extensions/common/api", ] }
diff --git a/extensions/browser/api/usb/usb_api.cc b/extensions/browser/api/usb/usb_api.cc index 6006dfb..8280a63 100644 --- a/extensions/browser/api/usb/usb_api.cc +++ b/extensions/browser/api/usb/usb_api.cc
@@ -51,14 +51,16 @@ using content::BrowserThread; using device::UsbConfigDescriptor; +using device::UsbControlTransferRecipient; +using device::UsbControlTransferType; using device::UsbDevice; using device::UsbDeviceFilter; using device::UsbDeviceHandle; using device::UsbEndpointDescriptor; -using device::UsbEndpointDirection; using device::UsbInterfaceDescriptor; using device::UsbService; using device::UsbSynchronizationType; +using device::UsbTransferDirection; using device::UsbTransferStatus; using device::UsbTransferType; using device::UsbUsageType; @@ -127,13 +129,13 @@ const int kMaxPacketLength = 64 * 1024; bool ConvertDirectionFromApi(const Direction& input, - UsbEndpointDirection* output) { + UsbTransferDirection* output) { switch (input) { case usb::DIRECTION_IN: - *output = device::USB_DIRECTION_INBOUND; + *output = UsbTransferDirection::INBOUND; return true; case usb::DIRECTION_OUT: - *output = device::USB_DIRECTION_OUTBOUND; + *output = UsbTransferDirection::OUTBOUND; return true; default: NOTREACHED(); @@ -142,19 +144,19 @@ } bool ConvertRequestTypeFromApi(const RequestType& input, - UsbDeviceHandle::TransferRequestType* output) { + UsbControlTransferType* output) { switch (input) { case usb::REQUEST_TYPE_STANDARD: - *output = UsbDeviceHandle::STANDARD; + *output = UsbControlTransferType::STANDARD; return true; case usb::REQUEST_TYPE_CLASS: - *output = UsbDeviceHandle::CLASS; + *output = UsbControlTransferType::CLASS; return true; case usb::REQUEST_TYPE_VENDOR: - *output = UsbDeviceHandle::VENDOR; + *output = UsbControlTransferType::VENDOR; return true; case usb::REQUEST_TYPE_RESERVED: - *output = UsbDeviceHandle::RESERVED; + *output = UsbControlTransferType::RESERVED; return true; default: NOTREACHED(); @@ -163,19 +165,19 @@ } bool ConvertRecipientFromApi(const Recipient& input, - UsbDeviceHandle::TransferRecipient* output) { + UsbControlTransferRecipient* output) { switch (input) { case usb::RECIPIENT_DEVICE: - *output = UsbDeviceHandle::DEVICE; + *output = UsbControlTransferRecipient::DEVICE; return true; case usb::RECIPIENT_INTERFACE: - *output = UsbDeviceHandle::INTERFACE; + *output = UsbControlTransferRecipient::INTERFACE; return true; case usb::RECIPIENT_ENDPOINT: - *output = UsbDeviceHandle::ENDPOINT; + *output = UsbControlTransferRecipient::ENDPOINT; return true; case usb::RECIPIENT_OTHER: - *output = UsbDeviceHandle::OTHER; + *output = UsbControlTransferRecipient::OTHER; return true; default: NOTREACHED(); @@ -204,7 +206,7 @@ template <class T> scoped_refptr<net::IOBuffer> CreateBufferForTransfer( const T& input, - UsbEndpointDirection direction, + UsbTransferDirection direction, size_t size) { if (size >= kMaxTransferLength) return NULL; @@ -215,9 +217,9 @@ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max(static_cast<size_t>(1), size)); - if (direction == device::USB_DIRECTION_INBOUND) { + if (direction == UsbTransferDirection::INBOUND) { return buffer; - } else if (direction == device::USB_DIRECTION_OUTBOUND) { + } else if (direction == UsbTransferDirection::OUTBOUND) { if (input.data.get() && size <= input.data->size()) { memcpy(buffer->data(), input.data->data(), size); return buffer; @@ -229,21 +231,21 @@ const char* ConvertTransferStatusToApi(const UsbTransferStatus status) { switch (status) { - case device::USB_TRANSFER_COMPLETED: + case UsbTransferStatus::COMPLETED: return ""; - case device::USB_TRANSFER_ERROR: + case UsbTransferStatus::TRANSFER_ERROR: return kErrorGeneric; - case device::USB_TRANSFER_TIMEOUT: + case UsbTransferStatus::TIMEOUT: return kErrorTimeout; - case device::USB_TRANSFER_CANCELLED: + case UsbTransferStatus::CANCELLED: return kErrorCancelled; - case device::USB_TRANSFER_STALLED: + case UsbTransferStatus::STALLED: return kErrorStalled; - case device::USB_TRANSFER_DISCONNECT: + case UsbTransferStatus::DISCONNECT: return kErrorDisconnect; - case device::USB_TRANSFER_OVERFLOW: + case UsbTransferStatus::BABBLE: return kErrorOverflow; - case device::USB_TRANSFER_LENGTH_SHORT: + case UsbTransferStatus::SHORT_PACKET: return kErrorTransferLength; default: NOTREACHED(); @@ -263,13 +265,13 @@ TransferType ConvertTransferTypeToApi(const UsbTransferType& input) { switch (input) { - case device::USB_TRANSFER_CONTROL: + case UsbTransferType::CONTROL: return usb::TRANSFER_TYPE_CONTROL; - case device::USB_TRANSFER_INTERRUPT: + case UsbTransferType::INTERRUPT: return usb::TRANSFER_TYPE_INTERRUPT; - case device::USB_TRANSFER_ISOCHRONOUS: + case UsbTransferType::ISOCHRONOUS: return usb::TRANSFER_TYPE_ISOCHRONOUS; - case device::USB_TRANSFER_BULK: + case UsbTransferType::BULK: return usb::TRANSFER_TYPE_BULK; default: NOTREACHED(); @@ -277,11 +279,11 @@ } } -Direction ConvertDirectionToApi(const UsbEndpointDirection& input) { +Direction ConvertDirectionToApi(const UsbTransferDirection& input) { switch (input) { - case device::USB_DIRECTION_INBOUND: + case UsbTransferDirection::INBOUND: return usb::DIRECTION_IN; - case device::USB_DIRECTION_OUTBOUND: + case UsbTransferDirection::OUTBOUND: return usb::DIRECTION_OUT; default: NOTREACHED(); @@ -463,7 +465,7 @@ size_t length) { std::unique_ptr<base::DictionaryValue> transfer_info( new base::DictionaryValue()); - transfer_info->SetInteger(kResultCodeKey, status); + transfer_info->SetInteger(kResultCodeKey, static_cast<int>(status)); if (data) { transfer_info->Set( @@ -472,7 +474,7 @@ transfer_info->Set(kDataKey, new base::Value(base::Value::Type::BINARY)); } - if (status == device::USB_TRANSFER_COMPLETED) { + if (status == UsbTransferStatus::COMPLETED) { Respond(OneArgument(std::move(transfer_info))); } else { std::unique_ptr<base::ListValue> error_args(new base::ListValue()); @@ -1016,9 +1018,9 @@ } const ControlTransferInfo& transfer = parameters->transfer_info; - UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; - UsbDeviceHandle::TransferRequestType request_type; - UsbDeviceHandle::TransferRecipient recipient; + UsbTransferDirection direction = UsbTransferDirection::INBOUND; + UsbControlTransferType request_type; + UsbControlTransferRecipient recipient; size_t size = 0; if (!ConvertDirectionFromApi(transfer.direction, &direction)) { @@ -1073,7 +1075,7 @@ } const GenericTransferInfo& transfer = parameters->transfer_info; - UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; + UsbTransferDirection direction = UsbTransferDirection::INBOUND; size_t size = 0; if (!ConvertDirectionFromApi(transfer.direction, &direction)) { @@ -1119,7 +1121,7 @@ } const GenericTransferInfo& transfer = parameters->transfer_info; - UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; + UsbTransferDirection direction = UsbTransferDirection::INBOUND; size_t size = 0; if (!ConvertDirectionFromApi(transfer.direction, &direction)) { @@ -1167,7 +1169,7 @@ const IsochronousTransferInfo& transfer = parameters->transfer_info; const GenericTransferInfo& generic_transfer = transfer.transfer_info; size_t size = 0; - UsbEndpointDirection direction = device::USB_DIRECTION_INBOUND; + UsbTransferDirection direction = UsbTransferDirection::INBOUND; if (!ConvertDirectionFromApi(generic_transfer.direction, &direction)) return RespondNow(Error(kErrorConvertDirection)); @@ -1193,7 +1195,7 @@ if (timeout < 0) return RespondNow(Error(kErrorInvalidTimeout)); - if (direction == device::USB_DIRECTION_INBOUND) { + if (direction == UsbTransferDirection::INBOUND) { device_handle->IsochronousTransferIn( generic_transfer.endpoint, packet_lengths, timeout, base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this)); @@ -1221,12 +1223,12 @@ std::vector<char> buffer; buffer.reserve(length); - UsbTransferStatus status = device::USB_TRANSFER_COMPLETED; + UsbTransferStatus status = UsbTransferStatus::COMPLETED; const char* data_ptr = data ? data->data() : nullptr; for (const auto& packet : packets) { // Capture the error status of the first unsuccessful packet. - if (status == device::USB_TRANSFER_COMPLETED && - packet.status != device::USB_TRANSFER_COMPLETED) { + if (status == UsbTransferStatus::COMPLETED && + packet.status != UsbTransferStatus::COMPLETED) { status = packet.status; } @@ -1239,9 +1241,9 @@ std::unique_ptr<base::DictionaryValue> transfer_info( new base::DictionaryValue()); - transfer_info->SetInteger(kResultCodeKey, status); + transfer_info->SetInteger(kResultCodeKey, static_cast<int>(status)); transfer_info->Set(kDataKey, new base::Value(std::move(buffer))); - if (status == device::USB_TRANSFER_COMPLETED) { + if (status == UsbTransferStatus::COMPLETED) { Respond(OneArgument(std::move(transfer_info))); } else { std::unique_ptr<base::ListValue> error_args(new base::ListValue());
diff --git a/extensions/browser/api/usb/usb_apitest.cc b/extensions/browser/api/usb/usb_apitest.cc index 9057178f..313e0c74 100644 --- a/extensions/browser/api/usb/usb_apitest.cc +++ b/extensions/browser/api/usb/usb_apitest.cc
@@ -28,9 +28,12 @@ using device::MockUsbDevice; using device::MockUsbDeviceHandle; using device::UsbConfigDescriptor; +using device::UsbControlTransferRecipient; +using device::UsbControlTransferType; using device::UsbDeviceHandle; -using device::UsbEndpointDirection; using device::UsbInterfaceDescriptor; +using device::UsbTransferDirection; +using device::UsbTransferStatus; namespace extensions { @@ -47,7 +50,7 @@ AND_1_VALUE_PARAMS(p1)) { net::IOBuffer* io_buffer = nullptr; size_t length = 0; - if (p1 != device::USB_TRANSFER_ERROR) { + if (p1 != UsbTransferStatus::TRANSFER_ERROR) { length = 1; io_buffer = new net::IOBuffer(length); memset(io_buffer->data(), 0, length); // Avoid uninitialized reads. @@ -63,10 +66,10 @@ packets[i].length = arg2[i]; if (i < success_packets) { packets[i].transferred_length = transferred_length; - packets[i].status = device::USB_TRANSFER_COMPLETED; + packets[i].status = UsbTransferStatus::COMPLETED; } else { packets[i].transferred_length = 0; - packets[i].status = device::USB_TRANSFER_ERROR; + packets[i].status = UsbTransferStatus::TRANSFER_ERROR; } } arg4.Run(arg1, packets); @@ -84,10 +87,10 @@ packets[i].transferred_length = transferred_length; if (i < success_packets) { packets[i].transferred_length = transferred_length; - packets[i].status = device::USB_TRANSFER_COMPLETED; + packets[i].status = UsbTransferStatus::COMPLETED; } else { packets[i].transferred_length = 0; - packets[i].status = device::USB_TRANSFER_ERROR; + packets[i].status = UsbTransferStatus::TRANSFER_ERROR; } } arg3.Run(io_buffer, packets); @@ -178,8 +181,8 @@ .WillOnce(InvokeCallback<0>(true)) .WillOnce(InvokeCallback<0>(false)); EXPECT_CALL(*mock_device_handle_, - GenericTransfer(device::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _)) - .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED)); + GenericTransfer(UsbTransferDirection::OUTBOUND, 2, _, 1, _, _)) + .WillOnce(InvokeUsbTransferCallback<5>(UsbTransferStatus::COMPLETED)); ASSERT_TRUE(RunAppTest("api_test/usb/reset_device")); } @@ -199,15 +202,16 @@ IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferEvent) { EXPECT_CALL( *mock_device_handle_, - ControlTransfer(device::USB_DIRECTION_OUTBOUND, UsbDeviceHandle::STANDARD, - UsbDeviceHandle::DEVICE, 1, 2, 3, _, 1, _, _)) - .WillOnce(InvokeUsbTransferCallback<9>(device::USB_TRANSFER_COMPLETED)); + ControlTransfer(UsbTransferDirection::OUTBOUND, + UsbControlTransferType::STANDARD, + UsbControlTransferRecipient::DEVICE, 1, 2, 3, _, 1, _, _)) + .WillOnce(InvokeUsbTransferCallback<9>(UsbTransferStatus::COMPLETED)); EXPECT_CALL(*mock_device_handle_, - GenericTransfer(device::USB_DIRECTION_OUTBOUND, 1, _, 1, _, _)) - .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED)); + GenericTransfer(UsbTransferDirection::OUTBOUND, 1, _, 1, _, _)) + .WillOnce(InvokeUsbTransferCallback<5>(UsbTransferStatus::COMPLETED)); EXPECT_CALL(*mock_device_handle_, - GenericTransfer(device::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _)) - .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED)); + GenericTransfer(UsbTransferDirection::OUTBOUND, 2, _, 1, _, _)) + .WillOnce(InvokeUsbTransferCallback<5>(UsbTransferStatus::COMPLETED)); EXPECT_CALL(*mock_device_handle_, IsochronousTransferOut(3, _, _, _, _)) .WillOnce(InvokeUsbIsochronousTransferOutCallback(1, 1u)); EXPECT_CALL(*mock_device_handle_, Close()).Times(AnyNumber()); @@ -216,17 +220,17 @@ IN_PROC_BROWSER_TEST_F(UsbApiTest, ZeroLengthTransfer) { EXPECT_CALL(*mock_device_handle_, GenericTransfer(_, _, _, 0, _, _)) - .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED)); + .WillOnce(InvokeUsbTransferCallback<5>(UsbTransferStatus::COMPLETED)); EXPECT_CALL(*mock_device_handle_, Close()).Times(AnyNumber()); ASSERT_TRUE(RunAppTest("api_test/usb/zero_length_transfer")); } IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferFailure) { EXPECT_CALL(*mock_device_handle_, - GenericTransfer(device::USB_DIRECTION_OUTBOUND, 1, _, _, _, _)) - .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_COMPLETED)) - .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_ERROR)) - .WillOnce(InvokeUsbTransferCallback<5>(device::USB_TRANSFER_TIMEOUT)); + GenericTransfer(UsbTransferDirection::OUTBOUND, 1, _, _, _, _)) + .WillOnce(InvokeUsbTransferCallback<5>(UsbTransferStatus::COMPLETED)) + .WillOnce(InvokeUsbTransferCallback<5>(UsbTransferStatus::TRANSFER_ERROR)) + .WillOnce(InvokeUsbTransferCallback<5>(UsbTransferStatus::TIMEOUT)); EXPECT_CALL(*mock_device_handle_, IsochronousTransferIn(2, _, _, _)) .WillOnce(InvokeUsbIsochronousTransferInCallback(8, 10u)) .WillOnce(InvokeUsbIsochronousTransferInCallback(8, 5u));
diff --git a/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc b/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc index 0d0e85f0..54423d5 100644 --- a/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc +++ b/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc
@@ -12,6 +12,7 @@ #include "base/numerics/safe_math.h" #include "base/process/memory.h" #include "ui/gfx/buffer_format_util.h" +#include "ui/gfx/gpu_memory_buffer_tracing.h" #include "ui/gl/gl_bindings.h" namespace gpu { @@ -211,4 +212,10 @@ return handle; } +base::trace_event::MemoryAllocatorDumpGuid +GpuMemoryBufferImplSharedMemory::GetGUIDForTracing( + uint64_t tracing_process_id) const { + return gfx::GetSharedMemoryGUIDForTracing(tracing_process_id, id_); +} + } // namespace gpu
diff --git a/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h b/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h index 243d3d5..47577fa 100644 --- a/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h +++ b/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h
@@ -55,6 +55,8 @@ void Unmap() override; int stride(size_t plane) const override; gfx::GpuMemoryBufferHandle GetHandle() const override; + base::trace_event::MemoryAllocatorDumpGuid GetGUIDForTracing( + uint64_t tracing_process_id) const override; private: GpuMemoryBufferImplSharedMemory(
diff --git a/ios/chrome/browser/ui/collection_view/collection_view_model_unittest.mm b/ios/chrome/browser/ui/collection_view/collection_view_model_unittest.mm index ae764af..0ae51f2 100644 --- a/ios/chrome/browser/ui/collection_view/collection_view_model_unittest.mm +++ b/ios/chrome/browser/ui/collection_view/collection_view_model_unittest.mm
@@ -4,7 +4,10 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" +#include "base/bind.h" +#include "base/logging.h" #include "base/mac/foundation_util.h" +#include "base/strings/string_piece.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" @@ -54,7 +57,10 @@ ItemTypeWeasleyFooter, }; -void LogSink(const std::string& str) { +void LogSink(const char* file, + int line, + const base::StringPiece message, + const base::StringPiece stack_trace) { // No-op. } @@ -312,7 +318,7 @@ CollectionViewModel* model = [[CollectionViewModel alloc] init]; [model addSectionWithIdentifier:SectionIdentifierCheese]; - logging::SetLogAssertHandler(&LogSink); + logging::ScopedLogAssertHandler scoped_assert_handler(base::Bind(LogSink)); bool out_of_bounds_exception_thrown = false; @try { [model indexInItemTypeForIndexPath:[NSIndexPath indexPathForItem:0 @@ -323,7 +329,6 @@ } } EXPECT_TRUE(out_of_bounds_exception_thrown); - logging::SetLogAssertHandler(nullptr); } TEST(CollectionViewModelTest, RemoveItems) {
diff --git a/ios/chrome/browser/ui/dialogs/BUILD.gn b/ios/chrome/browser/ui/dialogs/BUILD.gn index f28a15c..d28a3a5 100644 --- a/ios/chrome/browser/ui/dialogs/BUILD.gn +++ b/ios/chrome/browser/ui/dialogs/BUILD.gn
@@ -34,6 +34,7 @@ } source_set("dialogs_internal") { + configs += [ "//build/config/compiler:enable_arc" ] sources = [ "dialog_presenter.h", "dialog_presenter.mm",
diff --git a/ios/chrome/browser/ui/dialogs/dialog_presenter.mm b/ios/chrome/browser/ui/dialogs/dialog_presenter.mm index 55282667..5be1336d 100644 --- a/ios/chrome/browser/ui/dialogs/dialog_presenter.mm +++ b/ios/chrome/browser/ui/dialogs/dialog_presenter.mm
@@ -8,7 +8,6 @@ #include <map> #import "base/ios/block_types.h" -#import "base/ios/weak_nsobject.h" #include "base/logging.h" #import "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" @@ -24,6 +23,10 @@ #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + // Externed accessibility identifier. NSString* const kJavaScriptDialogTextFieldAccessibiltyIdentifier = @"JavaScriptDialogTextFieldAccessibiltyIdentifier"; @@ -35,26 +38,19 @@ } // namespace @interface DialogPresenter () { - // Backing objects for properties of the same name. - base::WeakNSProtocol<id<DialogPresenterDelegate>> _delegate; - base::WeakNSObject<UIViewController> _viewController; // Queue of WebStates which correspond to the keys in // |_dialogCoordinatorsForWebStates|. std::deque<web::WebState*> _queuedWebStates; // A map associating queued webStates with their coordinators. std::map<web::WebState*, base::scoped_nsobject<AlertCoordinator>> _dialogCoordinatorsForWebStates; - web::WebState* _presentedDialogWebState; - base::scoped_nsobject<AlertCoordinator> _presentedDialogCoordinator; - base::scoped_nsobject<ActionSheetCoordinator> - _blockingConfirmationCoordinator; } // The delegate passed on initialization. -@property(nonatomic, readonly) id<DialogPresenterDelegate> delegate; +@property(weak, nonatomic, readonly) id<DialogPresenterDelegate> delegate; // The presenting view controller passed on initialization. -@property(nonatomic, readonly) UIViewController* viewController; +@property(weak, nonatomic, readonly) UIViewController* viewController; // Whether a modal dialog is currently being shown. @property(nonatomic, readonly, getter=isShowingDialog) BOOL showingDialog; @@ -63,10 +59,10 @@ @property(nonatomic) web::WebState* presentedDialogWebState; // The dialog that's currently being shown, if any. -@property(nonatomic, retain) AlertCoordinator* presentedDialogCoordinator; +@property(nonatomic, strong) AlertCoordinator* presentedDialogCoordinator; // The JavaScript dialog blocking confirmation action sheet being shown, if any. -@property(nonatomic, retain) AlertCoordinator* blockingConfirmationCoordinator; +@property(nonatomic, strong) AlertCoordinator* blockingConfirmationCoordinator; // Adds |context| and |coordinator| to the queue. If a dialog is not already // being shown, |coordinator| will be presented. Otherwise, |coordinator| will @@ -106,14 +102,19 @@ @implementation DialogPresenter @synthesize active = _active; +@synthesize delegate = _delegate; +@synthesize viewController = _viewController; +@synthesize presentedDialogCoordinator = _presentedDialogCoordinator; +@synthesize blockingConfirmationCoordinator = _blockingConfirmationCoordinator; +@synthesize presentedDialogWebState = _presentedDialogWebState; - (instancetype)initWithDelegate:(id<DialogPresenterDelegate>)delegate presentingViewController:(UIViewController*)viewController { if ((self = [super init])) { DCHECK(delegate); DCHECK(viewController); - _delegate.reset(delegate); - _viewController.reset(viewController); + _delegate = delegate; + _viewController = viewController; } return self; } @@ -127,47 +128,12 @@ } } -- (id<DialogPresenterDelegate>)delegate { - return _delegate; -} - -- (UIViewController*)viewController { - return _viewController; -} - - (BOOL)isShowingDialog { DCHECK_EQ(self.presentedDialogWebState != nullptr, self.presentedDialogCoordinator != nil); return self.presentedDialogCoordinator != nil; } -- (web::WebState*)presentedDialogWebState { - return _presentedDialogWebState; -} - -- (void)setPresentedDialogWebState:(web::WebState*)presentedDialogWebState { - _presentedDialogWebState = presentedDialogWebState; -} - -- (AlertCoordinator*)presentedDialogCoordinator { - return _presentedDialogCoordinator; -} - -- (void)setPresentedDialogCoordinator: - (AlertCoordinator*)presentedDialogCoordinator { - _presentedDialogCoordinator.reset([presentedDialogCoordinator retain]); -} - -- (ActionSheetCoordinator*)blockingConfirmationCoordinator { - return _blockingConfirmationCoordinator; -} - -- (void)setBlockingConfirmationCoordinator: - (ActionSheetCoordinator*)blockingConfirmationActionSheetCoordinator { - _blockingConfirmationCoordinator.reset( - [blockingConfirmationActionSheetCoordinator retain]); -} - #pragma mark - Public - (void)runJavaScriptAlertPanelWithMessage:(NSString*)message @@ -176,14 +142,14 @@ completionHandler:(void (^)(void))completionHandler { NSString* title = [DialogPresenter localizedTitleForJavaScriptAlertFromPage:requestURL]; - AlertCoordinator* alertCoordinator = [[[AlertCoordinator alloc] - initWithBaseViewController:self.viewController - title:title - message:message] autorelease]; + AlertCoordinator* alertCoordinator = + [[AlertCoordinator alloc] initWithBaseViewController:self.viewController + title:title + message:message]; // Handler. - base::WeakNSObject<DialogPresenter> weakSelf(self); - base::WeakNSObject<AlertCoordinator> weakCoordinator(alertCoordinator); + __weak DialogPresenter* weakSelf = self; + __weak AlertCoordinator* weakCoordinator = alertCoordinator; ProceduralBlock OKHandler = ^{ if (completionHandler) completionHandler(); @@ -212,10 +178,10 @@ (void (^)(BOOL isConfirmed))completionHandler { NSString* title = [DialogPresenter localizedTitleForJavaScriptAlertFromPage:requestURL]; - AlertCoordinator* alertCoordinator = [[[AlertCoordinator alloc] - initWithBaseViewController:self.viewController - title:title - message:message] autorelease]; + AlertCoordinator* alertCoordinator = + [[AlertCoordinator alloc] initWithBaseViewController:self.viewController + title:title + message:message]; // Actions. ProceduralBlock confirmAction = ^{ @@ -249,13 +215,13 @@ (void (^)(NSString* input))completionHandler { NSString* title = [DialogPresenter localizedTitleForJavaScriptAlertFromPage:requestURL]; - InputAlertCoordinator* alertCoordinator = [[[InputAlertCoordinator alloc] + InputAlertCoordinator* alertCoordinator = [[InputAlertCoordinator alloc] initWithBaseViewController:self.viewController title:title - message:message] autorelease]; + message:message]; // Actions. - base::WeakNSObject<InputAlertCoordinator> weakCoordinator(alertCoordinator); + __weak InputAlertCoordinator* weakCoordinator = alertCoordinator; ProceduralBlock confirmAction = ^{ if (completionHandler) { NSString* textInput = [weakCoordinator textFields].firstObject.text; @@ -299,13 +265,13 @@ ios_internal::nsurlprotectionspace_util::MessageForHTTPAuth( protectionSpace); - InputAlertCoordinator* alertCoordinator = [[[InputAlertCoordinator alloc] + InputAlertCoordinator* alertCoordinator = [[InputAlertCoordinator alloc] initWithBaseViewController:self.viewController title:title - message:message] autorelease]; + message:message]; // Actions. - base::WeakNSObject<InputAlertCoordinator> weakCoordinator(alertCoordinator); + __weak InputAlertCoordinator* weakCoordinator = alertCoordinator; ProceduralBlock confirmAction = ^{ if (handler) { NSString* username = [[weakCoordinator textFields] objectAtIndex:0].text; @@ -398,7 +364,7 @@ DCHECK(!_dialogCoordinatorsForWebStates[webState]); _queuedWebStates.push_back(webState); _dialogCoordinatorsForWebStates[webState] = - base::scoped_nsobject<AlertCoordinator>([coordinator retain]); + base::scoped_nsobject<AlertCoordinator>(coordinator); if (self.active && !self.showingDialog && !self.delegate.presenting) [self showNextDialog]; @@ -435,8 +401,8 @@ cancelAction:(ProceduralBlock)cancelAction OKLabel:(NSString*)label { // Handlers. - base::WeakNSObject<DialogPresenter> weakSelf(self); - base::WeakNSObject<AlertCoordinator> weakCoordinator(alertCoordinator); + __weak DialogPresenter* weakSelf = self; + __weak AlertCoordinator* weakCoordinator = alertCoordinator; ProceduralBlock confirmHandler = ^{ if (confirmAction) @@ -469,8 +435,6 @@ DCHECK(webState); // Set up the start action. - base::WeakNSObject<DialogPresenter> weakSelf(self); - base::WeakNSObject<AlertCoordinator> weakCoordinator(alertCoordinator); ProceduralBlock originalStartAction = alertCoordinator.startAction; alertCoordinator.startAction = ^{ if (originalStartAction) @@ -492,33 +456,32 @@ } - (ProceduralBlock)blockingActionForCoordinator:(AlertCoordinator*)coordinator { - base::WeakNSObject<DialogPresenter> weakSelf(self); - base::WeakNSObject<AlertCoordinator> weakCoordinator(coordinator); - base::WeakNSObject<UIViewController> weakBaseViewController( - coordinator.baseViewController); + __weak DialogPresenter* weakSelf = self; + __weak AlertCoordinator* weakCoordinator = coordinator; + __weak UIViewController* weakBaseViewController = + coordinator.baseViewController; ProceduralBlock cancelAction = coordinator.cancelAction; - return [[^{ + return [^{ // Create the confirmation coordinator. Use an action sheet on iPhone and // an alert on iPhone. NSString* confirmMessage = l10n_util::GetNSString(IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION); AlertCoordinator* confirmationCoordinator = - IsIPadIdiom() - ? [[[AlertCoordinator alloc] - initWithBaseViewController:weakBaseViewController - title:nil - message:confirmMessage] autorelease] - : [[[ActionSheetCoordinator alloc] - initWithBaseViewController:weakBaseViewController - title:nil - message:confirmMessage - rect:CGRectZero - view:nil] autorelease]; + IsIPadIdiom() ? [[AlertCoordinator alloc] + initWithBaseViewController:weakBaseViewController + title:nil + message:confirmMessage] + : [[ActionSheetCoordinator alloc] + initWithBaseViewController:weakBaseViewController + title:nil + message:confirmMessage + rect:CGRectZero + view:nil]; // Set up button actions. ProceduralBlock confirmHandler = ^{ if (cancelAction) cancelAction(); - base::scoped_nsobject<DialogPresenter> strongSelf([weakSelf retain]); + DialogPresenter* strongSelf = weakSelf; if (!strongSelf) return; DialogBlockingOptionSelected([strongSelf presentedDialogWebState]); @@ -539,7 +502,7 @@ style:UIAlertActionStyleCancel]; [weakSelf setBlockingConfirmationCoordinator:confirmationCoordinator]; [[weakSelf blockingConfirmationCoordinator] start]; - } copy] autorelease]; + } copy]; } @end
diff --git a/ios/chrome/browser/ui/dialogs/java_script_dialog_presenter_impl.mm b/ios/chrome/browser/ui/dialogs/java_script_dialog_presenter_impl.mm index 5e463062..951911f 100644 --- a/ios/chrome/browser/ui/dialogs/java_script_dialog_presenter_impl.mm +++ b/ios/chrome/browser/ui/dialogs/java_script_dialog_presenter_impl.mm
@@ -7,9 +7,13 @@ #import "ios/chrome/browser/ui/dialogs/dialog_presenter.h" #import "ios/chrome/browser/ui/dialogs/javascript_dialog_blocking_util.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + JavaScriptDialogPresenterImpl::JavaScriptDialogPresenterImpl( DialogPresenter* dialogPresenter) - : dialog_presenter_([dialogPresenter retain]) {} + : dialog_presenter_(dialogPresenter) {} JavaScriptDialogPresenterImpl::~JavaScriptDialogPresenterImpl() {}
diff --git a/ios/chrome/browser/ui/dialogs/nsurl_protection_space_util.mm b/ios/chrome/browser/ui/dialogs/nsurl_protection_space_util.mm index b3f7562..0ffb4d3 100644 --- a/ios/chrome/browser/ui/dialogs/nsurl_protection_space_util.mm +++ b/ios/chrome/browser/ui/dialogs/nsurl_protection_space_util.mm
@@ -4,7 +4,6 @@ #import "ios/chrome/browser/ui/dialogs/nsurl_protection_space_util.h" -#import "base/mac/scoped_nsobject.h" #include "base/numerics/safe_conversions.h" #include "base/strings/sys_string_conversions.h" #include "components/strings/grit/components_strings.h" @@ -13,6 +12,10 @@ #include "url/gurl.h" #include "url/scheme_host_port.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ios_internal { namespace nsurlprotectionspace_util {
diff --git a/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.h b/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.h index 38f1e99..5cd1181 100644 --- a/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.h +++ b/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.h
@@ -45,7 +45,7 @@ AutocompleteClassifier* GetAutocompleteClassifier() override; gfx::Image GetIconIfExtensionMatch( const AutocompleteMatch& match) const override; - bool ProcessExtensionKeyword(TemplateURL* template_url, + bool ProcessExtensionKeyword(const TemplateURL* template_url, const AutocompleteMatch& match, WindowOpenDisposition disposition, OmniboxNavigationObserver* observer) override;
diff --git a/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.mm b/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.mm index 03e42e0..ce9a40b 100644 --- a/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.mm +++ b/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.mm
@@ -123,7 +123,7 @@ } bool ChromeOmniboxClientIOS::ProcessExtensionKeyword( - TemplateURL* template_url, + const TemplateURL* template_url, const AutocompleteMatch& match, WindowOpenDisposition disposition, OmniboxNavigationObserver* observer) {
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index 2037334..d3fc692 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -207,6 +207,7 @@ "//ios/chrome/browser/content_settings", "//ios/chrome/browser/infobars", "//ios/chrome/browser/ssl", + "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/overscroll_actions", "//ios/chrome/browser/ui/static_content",
diff --git a/ios/chrome/browser/web/auto_reload_bridge.mm b/ios/chrome/browser/web/auto_reload_bridge.mm index 817f740..1d968f2 100644 --- a/ios/chrome/browser/web/auto_reload_bridge.mm +++ b/ios/chrome/browser/web/auto_reload_bridge.mm
@@ -8,6 +8,8 @@ #include "base/ios/weak_nsobject.h" #include "base/mac/scoped_nsobject.h" +#import "ios/chrome/browser/tabs/tab.h" +#import "ios/web/public/navigation_manager.h" #include "net/base/network_change_notifier.h" namespace { @@ -80,7 +82,8 @@ #pragma mark AutoReloadDelegate methods - (void)reload { - [_tab reload]; + [_tab navigationManager]->Reload(web::ReloadType::NORMAL, + false /* check_for_repost */); } @end
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index cd1569a..9b79fba 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -1406,21 +1406,19 @@ DCHECK(main_task_runner_->BelongsToCurrentThread()); DCHECK_NE(ready_state_, WebMediaPlayer::kReadyStateHaveNothing); + TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); + // The input |size| is from the decoded video frame, which is the original // natural size and need to be rotated accordingly. gfx::Size rotated_size = GetRotatedVideoSize(pipeline_metadata_.video_rotation, size); - if (rotated_size == pipeline_metadata_.natural_size) + RecordVideoNaturalSize(rotated_size); + + gfx::Size old_size = pipeline_metadata_.natural_size; + if (rotated_size == old_size) return; - TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); - media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( - rotated_size.width(), rotated_size.height())); - - if (overlay_enabled_ && surface_manager_) - surface_manager_->NaturalSizeChanged(rotated_size); - pipeline_metadata_.natural_size = rotated_size; // Re-create |watch_time_reporter_| if we didn't originally know the video @@ -1428,6 +1426,9 @@ if (!watch_time_reporter_->IsSizeLargeEnoughToReportWatchTime()) CreateWatchTimeReporter(); + if (overlay_enabled_ && surface_manager_) + surface_manager_->NaturalSizeChanged(rotated_size); + client_->SizeChanged(); if (observer_) @@ -2372,4 +2373,32 @@ UMA_HISTOGRAM_TIMES("Media.UnderflowDuration.MSE", duration); } +#define UMA_HISTOGRAM_VIDEO_HEIGHT(name, sample) \ + UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 100, 10000, 50) + +void WebMediaPlayerImpl::RecordVideoNaturalSize(const gfx::Size& natural_size) { + // Always report video natural size to MediaLog. + media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( + natural_size.width(), natural_size.height())); + + if (initial_video_height_recorded_) + return; + + initial_video_height_recorded_ = true; + + int height = natural_size.height(); + + if (load_type_ == kLoadTypeURL) + UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.SRC", height); + else if (load_type_ == kLoadTypeMediaSource) + UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.MSE", height); + + if (is_encrypted_) + UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.EME", height); + + UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.All", height); +} + +#undef UMA_HISTOGRAM_VIDEO_HEIGHT + } // namespace media
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index a7382f8..0d932b3 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -457,6 +457,9 @@ // handling a src= or MSE based playback. void RecordUnderflowDuration(base::TimeDelta duration); + // Records |natural_size| to MediaLog and video height to UMA. + void RecordVideoNaturalSize(const gfx::Size& natural_size); + blink::WebLocalFrame* frame_; // The playback state last reported to |delegate_|, to avoid setting duplicate @@ -720,6 +723,8 @@ base::CancelableCallback<void(base::TimeTicks)> frame_time_report_cb_; + bool initial_video_height_recorded_ = false; + DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); };
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index d75f7aa..1994492 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -472,9 +472,9 @@ dump->AddScalar("free_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, frame_resources->IsInUse() ? 0 : buffer_size_in_bytes); - base::trace_event::MemoryAllocatorDumpGuid shared_buffer_guid = - gfx::GetGpuMemoryBufferGUIDForTracing(tracing_process_id, - buffer_id); + auto shared_buffer_guid = + plane_resource.gpu_memory_buffer->GetGUIDForTracing( + tracing_process_id); pmd->CreateSharedGlobalAllocatorDump(shared_buffer_guid); pmd->AddOwnershipEdge(dump->guid(), shared_buffer_guid, kImportance); }
diff --git a/net/BUILD.gn b/net/BUILD.gn index 0c33989d..1c06639 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -788,6 +788,8 @@ "http/bidirectional_stream_request_info.h", "http/des.cc", "http/des.h", + "http/disk_cache_based_quic_server_info.cc", + "http/disk_cache_based_quic_server_info.h", "http/failing_http_transaction_factory.cc", "http/failing_http_transaction_factory.h", "http/http_auth.cc", @@ -4323,6 +4325,7 @@ "ftp/ftp_util_unittest.cc", "http/bidirectional_stream_unittest.cc", "http/des_unittest.cc", + "http/disk_cache_based_quic_server_info_unittest.cc", "http/http_auth_cache_unittest.cc", "http/http_auth_challenge_tokenizer_unittest.cc", "http/http_auth_controller_unittest.cc",
diff --git a/net/http/disk_cache_based_quic_server_info.cc b/net/http/disk_cache_based_quic_server_info.cc new file mode 100644 index 0000000..b149fc9 --- /dev/null +++ b/net/http/disk_cache_based_quic_server_info.cc
@@ -0,0 +1,450 @@ +// 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 "net/http/disk_cache_based_quic_server_info.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/callback_helpers.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" +#include "base/trace_event/memory_usage_estimator.h" +#include "net/base/completion_callback.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/http/http_cache.h" +#include "net/http/http_network_session.h" +#include "net/quic/core/quic_server_id.h" + +namespace net { + +// Some APIs inside disk_cache take a handle that the caller must keep alive +// until the API has finished its asynchronous execution. +// +// Unfortunately, DiskCacheBasedQuicServerInfo may be deleted before the +// operation completes causing a use-after-free. +// +// This data shim struct is meant to provide a location for the disk_cache +// APIs to write into even if the originating DiskCacheBasedQuicServerInfo +// object has been deleted. The lifetime for instances of this struct +// should be bound to the CompletionCallback that is passed to the disk_cache +// API. We do this by binding an instance of this struct to an unused +// parameter for OnIOComplete() using base::Owned(). +// +// This is a hack. A better fix is to make it so that the disk_cache APIs +// take a Callback to a mutator for setting the output value rather than +// writing into a raw handle. Then the caller can just pass in a Callback +// bound to WeakPtr for itself. This callback would correctly "no-op" itself +// when the DiskCacheBasedQuicServerInfo object is deleted. +// +// TODO(ajwong): Change disk_cache's API to return results via Callback. +struct DiskCacheBasedQuicServerInfo::CacheOperationDataShim { + CacheOperationDataShim() : backend(NULL), entry(NULL) {} + + disk_cache::Backend* backend; + disk_cache::Entry* entry; +}; + +DiskCacheBasedQuicServerInfo::DiskCacheBasedQuicServerInfo( + const QuicServerId& server_id, + HttpCache* http_cache) + : QuicServerInfo(server_id), + data_shim_(new CacheOperationDataShim()), + state_(GET_BACKEND), + ready_(false), + found_entry_(false), + server_id_(server_id), + http_cache_(http_cache), + backend_(NULL), + entry_(NULL), + last_failure_(NO_FAILURE), + weak_factory_(this) { + io_callback_ = + base::Bind(&DiskCacheBasedQuicServerInfo::OnIOComplete, + weak_factory_.GetWeakPtr(), + base::Owned(data_shim_)); // Ownership assigned. +} + +DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() { + DCHECK(wait_for_ready_callback_.is_null()); + if (entry_) + entry_->Close(); +} + +void DiskCacheBasedQuicServerInfo::Start() { + DCHECK(CalledOnValidThread()); + DCHECK_EQ(GET_BACKEND, state_); + DCHECK_EQ(last_failure_, NO_FAILURE); + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_START); + load_start_time_ = base::TimeTicks::Now(); + DoLoop(OK); +} + +int DiskCacheBasedQuicServerInfo::WaitForDataReady( + const CompletionCallback& callback) { + DCHECK(CalledOnValidThread()); + DCHECK_NE(GET_BACKEND, state_); + wait_for_data_start_time_ = base::TimeTicks::Now(); + + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY); + if (ready_) { + wait_for_data_end_time_ = base::TimeTicks::Now(); + RecordLastFailure(); + return OK; + } + + if (!callback.is_null()) { + // Prevent a new callback for WaitForDataReady overwriting an existing + // pending callback (|wait_for_ready_callback_|). + if (!wait_for_ready_callback_.is_null()) { + RecordQuicServerInfoFailure(WAIT_FOR_DATA_READY_INVALID_ARGUMENT_FAILURE); + return ERR_INVALID_ARGUMENT; + } + wait_for_ready_callback_ = callback; + } + + return ERR_IO_PENDING; +} + +void DiskCacheBasedQuicServerInfo::ResetWaitForDataReadyCallback() { + DCHECK(CalledOnValidThread()); + wait_for_ready_callback_.Reset(); +} + +void DiskCacheBasedQuicServerInfo::CancelWaitForDataReadyCallback() { + DCHECK(CalledOnValidThread()); + + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL); + if (!wait_for_ready_callback_.is_null()) { + RecordLastFailure(); + wait_for_ready_callback_.Reset(); + } +} + +bool DiskCacheBasedQuicServerInfo::IsDataReady() { + return ready_; +} + +bool DiskCacheBasedQuicServerInfo::IsReadyToPersist() { + // The data can be persisted if it has been loaded from the disk cache + // and there are no pending writes. + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_READY_TO_PERSIST); + if (ready_ && new_data_.empty()) + return true; + RecordQuicServerInfoFailure(READY_TO_PERSIST_FAILURE); + return false; +} + +void DiskCacheBasedQuicServerInfo::Persist() { + DCHECK(CalledOnValidThread()); + if (!IsReadyToPersist()) { + // Handle updates while a write is pending or if we haven't loaded from disk + // cache. Save the data to be written into a temporary buffer and then + // persist that data when we are ready to persist. + pending_write_data_ = Serialize(); + return; + } + PersistInternal(); +} + +void DiskCacheBasedQuicServerInfo::PersistInternal() { + DCHECK(CalledOnValidThread()); + DCHECK_NE(GET_BACKEND, state_); + DCHECK(new_data_.empty()); + CHECK(ready_); + DCHECK(wait_for_ready_callback_.is_null()); + + if (pending_write_data_.empty()) { + new_data_ = Serialize(); + } else { + new_data_ = pending_write_data_; + base::STLClearObject(&pending_write_data_); + } + + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_PERSIST); + if (!backend_) { + RecordQuicServerInfoFailure(PERSIST_NO_BACKEND_FAILURE); + return; + } + + state_ = CREATE_OR_OPEN; + DoLoop(OK); +} + +void DiskCacheBasedQuicServerInfo::OnExternalCacheHit() { + DCHECK(CalledOnValidThread()); + DCHECK_NE(GET_BACKEND, state_); + + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_EXTERNAL_CACHE_HIT); + if (!backend_) { + RecordQuicServerInfoFailure(PERSIST_NO_BACKEND_FAILURE); + return; + } + + backend_->OnExternalCacheHit(key()); +} + +size_t DiskCacheBasedQuicServerInfo::EstimateMemoryUsage() const { + return base::trace_event::EstimateMemoryUsage(new_data_) + + base::trace_event::EstimateMemoryUsage(pending_write_data_) + + base::trace_event::EstimateMemoryUsage(server_id_) + + (read_buffer_ == nullptr ? 0 : read_buffer_->size()) + + (write_buffer_ == nullptr ? 0 : write_buffer_->size()) + + base::trace_event::EstimateMemoryUsage(data_); +} + +std::string DiskCacheBasedQuicServerInfo::key() const { + return "quicserverinfo:" + server_id_.ToString(); +} + +void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused, + int rv) { + DCHECK_NE(NONE, state_); + rv = DoLoop(rv); + if (rv == ERR_IO_PENDING) + return; + + base::WeakPtr<DiskCacheBasedQuicServerInfo> weak_this = + weak_factory_.GetWeakPtr(); + + if (!wait_for_ready_callback_.is_null()) { + wait_for_data_end_time_ = base::TimeTicks::Now(); + RecordLastFailure(); + base::ResetAndReturn(&wait_for_ready_callback_).Run(rv); + } + // |wait_for_ready_callback_| could delete the object if there is an error. + // Check if |weak_this| still exists before accessing it. + if (weak_this.get() && ready_ && !pending_write_data_.empty()) { + DCHECK_EQ(NONE, state_); + PersistInternal(); + } +} + +int DiskCacheBasedQuicServerInfo::DoLoop(int rv) { + do { + switch (state_) { + case GET_BACKEND: + rv = DoGetBackend(); + break; + case GET_BACKEND_COMPLETE: + rv = DoGetBackendComplete(rv); + break; + case OPEN: + rv = DoOpen(); + break; + case OPEN_COMPLETE: + rv = DoOpenComplete(rv); + break; + case READ: + rv = DoRead(); + break; + case READ_COMPLETE: + rv = DoReadComplete(rv); + break; + case WAIT_FOR_DATA_READY_DONE: + rv = DoWaitForDataReadyDone(); + break; + case CREATE_OR_OPEN: + rv = DoCreateOrOpen(); + break; + case CREATE_OR_OPEN_COMPLETE: + rv = DoCreateOrOpenComplete(rv); + break; + case WRITE: + rv = DoWrite(); + break; + case WRITE_COMPLETE: + rv = DoWriteComplete(rv); + break; + case SET_DONE: + rv = DoSetDone(); + break; + default: + rv = OK; + NOTREACHED(); + } + } while (rv != ERR_IO_PENDING && state_ != NONE); + + return rv; +} + +int DiskCacheBasedQuicServerInfo::DoGetBackendComplete(int rv) { + if (rv == OK) { + backend_ = data_shim_->backend; + state_ = OPEN; + } else { + RecordQuicServerInfoFailure(GET_BACKEND_FAILURE); + state_ = WAIT_FOR_DATA_READY_DONE; + } + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) { + if (rv == OK) { + entry_ = data_shim_->entry; + state_ = READ; + found_entry_ = true; + } else { + RecordQuicServerInfoFailure(OPEN_FAILURE); + state_ = WAIT_FOR_DATA_READY_DONE; + } + + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) { + if (rv > 0) + data_.assign(read_buffer_->data(), rv); + else if (rv < 0) + RecordQuicServerInfoFailure(READ_FAILURE); + + read_buffer_ = nullptr; + state_ = WAIT_FOR_DATA_READY_DONE; + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) { + if (rv < 0) + RecordQuicServerInfoFailure(WRITE_FAILURE); + write_buffer_ = nullptr; + state_ = SET_DONE; + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) { + if (rv != OK) { + RecordQuicServerInfoFailure(CREATE_OR_OPEN_FAILURE); + state_ = SET_DONE; + } else { + if (!entry_) { + entry_ = data_shim_->entry; + found_entry_ = true; + } + DCHECK(entry_); + state_ = WRITE; + } + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoGetBackend() { + state_ = GET_BACKEND_COMPLETE; + return http_cache_->GetBackend(&data_shim_->backend, io_callback_); +} + +int DiskCacheBasedQuicServerInfo::DoOpen() { + state_ = OPEN_COMPLETE; + return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_); +} + +int DiskCacheBasedQuicServerInfo::DoRead() { + const int32_t size = entry_->GetDataSize(0 /* index */); + if (!size) { + state_ = WAIT_FOR_DATA_READY_DONE; + return OK; + } + + read_buffer_ = new IOBufferWithSize(size); + state_ = READ_COMPLETE; + return entry_->ReadData( + 0 /* index */, 0 /* offset */, read_buffer_.get(), size, io_callback_); +} + +int DiskCacheBasedQuicServerInfo::DoWrite() { + write_buffer_ = new IOBufferWithSize(new_data_.size()); + memcpy(write_buffer_->data(), new_data_.data(), new_data_.size()); + state_ = WRITE_COMPLETE; + + return entry_->WriteData(0 /* index */, + 0 /* offset */, + write_buffer_.get(), + new_data_.size(), + io_callback_, + true /* truncate */); +} + +int DiskCacheBasedQuicServerInfo::DoCreateOrOpen() { + state_ = CREATE_OR_OPEN_COMPLETE; + if (entry_) + return OK; + + if (found_entry_) { + return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_); + } + + return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_); +} + +int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() { + DCHECK(!ready_); + state_ = NONE; + ready_ = true; + // We close the entry because, if we shutdown before ::Persist is called, + // then we might leak a cache reference, which causes a DCHECK on shutdown. + if (entry_) + entry_->Close(); + entry_ = NULL; + + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_PARSE); + if (!Parse(data_)) { + if (data_.empty()) + RecordQuicServerInfoFailure(PARSE_NO_DATA_FAILURE); + else + RecordQuicServerInfoFailure(PARSE_FAILURE); + } + + UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheLoadTime", + base::TimeTicks::Now() - load_start_time_); + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoSetDone() { + if (entry_) + entry_->Close(); + entry_ = NULL; + base::STLClearObject(&new_data_); + state_ = NONE; + return OK; +} + +void DiskCacheBasedQuicServerInfo::RecordQuicServerInfoStatus( + QuicServerInfoAPICall call) { + if (!backend_) { + UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.APICall.NoBackend", call, + QUIC_SERVER_INFO_NUM_OF_API_CALLS); + } else if (backend_->GetCacheType() == MEMORY_CACHE) { + UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.APICall.MemoryCache", call, + QUIC_SERVER_INFO_NUM_OF_API_CALLS); + } else { + UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.APICall.DiskCache", call, + QUIC_SERVER_INFO_NUM_OF_API_CALLS); + } +} + +void DiskCacheBasedQuicServerInfo::RecordLastFailure() { + if (last_failure_ != NO_FAILURE) { + UMA_HISTOGRAM_ENUMERATION( + "Net.QuicDiskCache.FailureReason.WaitForDataReady", + last_failure_, NUM_OF_FAILURES); + } + last_failure_ = NO_FAILURE; +} + +void DiskCacheBasedQuicServerInfo::RecordQuicServerInfoFailure( + FailureReason failure) { + last_failure_ = failure; + + if (!backend_) { + UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.FailureReason.NoBackend", + failure, NUM_OF_FAILURES); + } else if (backend_->GetCacheType() == MEMORY_CACHE) { + UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.FailureReason.MemoryCache", + failure, NUM_OF_FAILURES); + } else { + UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.FailureReason.DiskCache", + failure, NUM_OF_FAILURES); + } +} + +} // namespace net
diff --git a/net/http/disk_cache_based_quic_server_info.h b/net/http/disk_cache_based_quic_server_info.h new file mode 100644 index 0000000..2396f8c --- /dev/null +++ b/net/http/disk_cache_based_quic_server_info.h
@@ -0,0 +1,135 @@ +// 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 NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_ +#define NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/non_thread_safe.h" +#include "base/time/time.h" +#include "net/base/completion_callback.h" +#include "net/base/net_export.h" +#include "net/disk_cache/disk_cache.h" +#include "net/quic/chromium/quic_server_info.h" + +namespace net { + +class HttpCache; +class IOBufferWithSize; +class QuicServerId; + +// DiskCacheBasedQuicServerInfo fetches information about a QUIC server from +// our standard disk cache. Since the information is defined to be +// non-sensitive, it's ok for us to keep it on disk. +class NET_EXPORT_PRIVATE DiskCacheBasedQuicServerInfo + : public QuicServerInfo, + public NON_EXPORTED_BASE(base::NonThreadSafe) { + public: + DiskCacheBasedQuicServerInfo(const QuicServerId& server_id, + HttpCache* http_cache); + ~DiskCacheBasedQuicServerInfo() override; + + // QuicServerInfo implementation. + void Start() override; + int WaitForDataReady(const CompletionCallback& callback) override; + void ResetWaitForDataReadyCallback() override; + void CancelWaitForDataReadyCallback() override; + bool IsDataReady() override; + bool IsReadyToPersist() override; + void Persist() override; + void OnExternalCacheHit() override; + size_t EstimateMemoryUsage() const override; + + private: + struct CacheOperationDataShim; + + enum State { + GET_BACKEND, + GET_BACKEND_COMPLETE, + OPEN, + OPEN_COMPLETE, + READ, + READ_COMPLETE, + WAIT_FOR_DATA_READY_DONE, + CREATE_OR_OPEN, + CREATE_OR_OPEN_COMPLETE, + WRITE, + WRITE_COMPLETE, + SET_DONE, + NONE, + }; + + // Persists |pending_write_data_| if it is not empty, otherwise serializes the + // data and pesists it. + void PersistInternal(); + + std::string key() const; + + // The |unused| parameter is a small hack so that we can have the + // CacheOperationDataShim object owned by the Callback that is created for + // this method. See comment above CacheOperationDataShim for details. + void OnIOComplete(CacheOperationDataShim* unused, int rv); + + int DoLoop(int rv); + + int DoGetBackendComplete(int rv); + int DoOpenComplete(int rv); + int DoReadComplete(int rv); + int DoWriteComplete(int rv); + int DoCreateOrOpenComplete(int rv); + + int DoGetBackend(); + int DoOpen(); + int DoRead(); + int DoWrite(); + int DoCreateOrOpen(); + + // DoWaitForDataReadyDone is the terminal state of the read operation. + int DoWaitForDataReadyDone(); + + // DoSetDone is the terminal state of the write operation. + int DoSetDone(); + + // Tracks in a histogram the number of times data read/parse/write API calls + // of QuicServerInfo to and from disk cache is called. + void RecordQuicServerInfoStatus(QuicServerInfoAPICall call); + + // Tracks in a histogram the failure reasons to read/load/write of + // QuicServerInfo to and from disk cache. It also saves the |failure| in + // |last_failure_|. + void RecordQuicServerInfoFailure(FailureReason failure); + + // Tracks in a histogram if |last_failure_| is not NO_FAILURE. + void RecordLastFailure(); + + CacheOperationDataShim* data_shim_; // Owned by |io_callback_|. + CompletionCallback io_callback_; + State state_; + bool ready_; + bool found_entry_; // Controls the behavior of DoCreateOrOpen. + std::string new_data_; + std::string pending_write_data_; + const QuicServerId server_id_; + HttpCache* const http_cache_; + disk_cache::Backend* backend_; + disk_cache::Entry* entry_; + CompletionCallback wait_for_ready_callback_; + scoped_refptr<IOBufferWithSize> read_buffer_; + scoped_refptr<IOBufferWithSize> write_buffer_; + std::string data_; + base::TimeTicks load_start_time_; + FailureReason last_failure_; + + base::WeakPtrFactory<DiskCacheBasedQuicServerInfo> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(DiskCacheBasedQuicServerInfo); +}; + +} // namespace net + +#endif // NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_
diff --git a/net/http/disk_cache_based_quic_server_info_unittest.cc b/net/http/disk_cache_based_quic_server_info_unittest.cc new file mode 100644 index 0000000..55f5835 --- /dev/null +++ b/net/http/disk_cache_based_quic_server_info_unittest.cc
@@ -0,0 +1,721 @@ +// 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 "net/http/disk_cache_based_quic_server_info.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "net/base/net_errors.h" +#include "net/http/mock_http_cache.h" +#include "net/quic/chromium/quic_server_info.h" +#include "net/quic/core/quic_server_id.h" +#include "net/test/gtest_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using net::test::IsError; +using net::test::IsOk; + +using std::string; + +namespace net { +namespace { + +// This is an empty transaction, needed to register the URL and the test mode. +const MockTransaction kHostInfoTransaction1 = { + "quicserverinfo:https://www.google.com:443", + "", + base::Time(), + "", + LOAD_NORMAL, + "", + "", + base::Time(), + "", + TEST_MODE_NORMAL, + nullptr, + nullptr, + nullptr, + 0, + 0, + OK, +}; + +const MockTransaction kHostInfoTransaction2 = { + "quicserverinfo:https://www.google.com:80", + "", + base::Time(), + "", + LOAD_NORMAL, + "", + "", + base::Time(), + "", + TEST_MODE_NORMAL, + nullptr, + nullptr, + nullptr, + 0, + 0, + OK, +}; + +class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { + public: + explicit DeleteCacheCompletionCallback(QuicServerInfo* server_info) + : server_info_(server_info), + callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete, + base::Unretained(this))) {} + + const CompletionCallback& callback() const { return callback_; } + + private: + void OnComplete(int result) { + delete server_info_; + SetResult(result); + } + + QuicServerInfo* server_info_; + CompletionCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback); +}; + +} // namespace + +// Tests that we can delete a DiskCacheBasedQuicServerInfo object in a +// completion callback for DiskCacheBasedQuicServerInfo::WaitForDataReady. +TEST(DiskCacheBasedQuicServerInfo, DeleteInCallback) { + // Use the blocking mock backend factory to force asynchronous completion + // of quic_server_info->WaitForDataReady(), so that the callback will run. + MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); + MockHttpCache cache(base::WrapUnique(factory), true); + QuicServerId server_id("www.verisign.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + TestCompletionCallback callback; + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + // Now complete the backend creation and let the callback run. + factory->FinishCreation(); + EXPECT_THAT(callback.GetResult(rv), IsOk()); +} + +// Tests the basic logic of storing, retrieving and updating data. +TEST(DiskCacheBasedQuicServerInfo, Update) { + MockHttpCache cache(true); + AddMockTransaction(&kHostInfoTransaction1); + TestCompletionCallback callback; + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(state->certs.empty()); + const string server_config_a = "server_config_a"; + const string source_address_token_a = "source_address_token_a"; + const string cert_sct_a = "cert_sct_a"; + const string chlo_hash_a = "chlo_hash_a"; + const string server_config_sig_a = "server_config_sig_a"; + const string cert_a = "cert_a"; + const string cert_b = "cert_b"; + + state->server_config = server_config_a; + state->source_address_token = source_address_token_a; + state->cert_sct = cert_sct_a; + state->chlo_hash = chlo_hash_a; + state->server_config_sig = server_config_sig_a; + state->certs.push_back(cert_a); + quic_server_info->Persist(); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + // Open the stored QuicServerInfo. + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + + // And now update the data. + state = quic_server_info->mutable_state(); + state->certs.push_back(cert_b); + + // Fail instead of DCHECKing double creates. + cache.disk_cache()->set_double_create_check(false); + quic_server_info->Persist(); + base::RunLoop().RunUntilIdle(); + + // Verify that the state was updated. + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + const QuicServerInfo::State& state1 = quic_server_info->state(); + EXPECT_EQ(server_config_a, state1.server_config); + EXPECT_EQ(source_address_token_a, state1.source_address_token); + EXPECT_EQ(cert_sct_a, state1.cert_sct); + EXPECT_EQ(chlo_hash_a, state1.chlo_hash); + EXPECT_EQ(server_config_sig_a, state1.server_config_sig); + EXPECT_EQ(2U, state1.certs.size()); + EXPECT_EQ(cert_a, state1.certs[0]); + EXPECT_EQ(cert_b, state1.certs[1]); + + RemoveMockTransaction(&kHostInfoTransaction1); +} + +// Test that demonstrates different info is returned when the ports differ. +TEST(DiskCacheBasedQuicServerInfo, UpdateDifferentPorts) { + MockHttpCache cache(true); + AddMockTransaction(&kHostInfoTransaction1); + AddMockTransaction(&kHostInfoTransaction2); + TestCompletionCallback callback; + + // Persist data for port 443. + QuicServerId server_id1("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info1( + new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache())); + quic_server_info1->Start(); + int rv = quic_server_info1->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + + QuicServerInfo::State* state1 = quic_server_info1->mutable_state(); + EXPECT_TRUE(state1->certs.empty()); + const string server_config_a = "server_config_a"; + const string source_address_token_a = "source_address_token_a"; + const string cert_sct_a = "cert_sct_a"; + const string chlo_hash_a = "chlo_hash_a"; + const string server_config_sig_a = "server_config_sig_a"; + const string cert_a = "cert_a"; + + state1->server_config = server_config_a; + state1->source_address_token = source_address_token_a; + state1->cert_sct = cert_sct_a; + state1->chlo_hash = chlo_hash_a; + state1->server_config_sig = server_config_sig_a; + state1->certs.push_back(cert_a); + quic_server_info1->Persist(); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + // Persist data for port 80. + QuicServerId server_id2("www.google.com", 80, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info2( + new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache())); + quic_server_info2->Start(); + rv = quic_server_info2->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + + QuicServerInfo::State* state2 = quic_server_info2->mutable_state(); + EXPECT_TRUE(state2->certs.empty()); + const string server_config_b = "server_config_b"; + const string source_address_token_b = "source_address_token_b"; + const string cert_sct_b = "cert_sct_b"; + const string chlo_hash_b = "chlo_hash_b"; + const string server_config_sig_b = "server_config_sig_b"; + const string cert_b = "cert_b"; + + state2->server_config = server_config_b; + state2->source_address_token = source_address_token_b; + state2->cert_sct = cert_sct_b; + state2->chlo_hash = chlo_hash_b; + state2->server_config_sig = server_config_sig_b; + state2->certs.push_back(cert_b); + quic_server_info2->Persist(); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + // Verify the stored QuicServerInfo for port 443. + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + const QuicServerInfo::State& state_a = quic_server_info->state(); + EXPECT_EQ(server_config_a, state_a.server_config); + EXPECT_EQ(source_address_token_a, state_a.source_address_token); + EXPECT_EQ(cert_sct_a, state_a.cert_sct); + EXPECT_EQ(chlo_hash_a, state_a.chlo_hash); + EXPECT_EQ(server_config_sig_a, state_a.server_config_sig); + EXPECT_EQ(1U, state_a.certs.size()); + EXPECT_EQ(cert_a, state_a.certs[0]); + + // Verify the stored QuicServerInfo for port 80. + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + const QuicServerInfo::State& state_b = quic_server_info->state(); + EXPECT_EQ(server_config_b, state_b.server_config); + EXPECT_EQ(source_address_token_b, state_b.source_address_token); + EXPECT_EQ(cert_sct_b, state_b.cert_sct); + EXPECT_EQ(chlo_hash_b, state_b.chlo_hash); + EXPECT_EQ(server_config_sig_b, state_b.server_config_sig); + EXPECT_EQ(1U, state_b.certs.size()); + EXPECT_EQ(cert_b, state_b.certs[0]); + + RemoveMockTransaction(&kHostInfoTransaction2); + RemoveMockTransaction(&kHostInfoTransaction1); +} + +// Test IsReadyToPersist when there is a pending write. +TEST(DiskCacheBasedQuicServerInfo, IsReadyToPersist) { + MockHttpCache cache(true); + AddMockTransaction(&kHostInfoTransaction1); + TestCompletionCallback callback; + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(state->certs.empty()); + const string server_config_a = "server_config_a"; + const string source_address_token_a = "source_address_token_a"; + const string cert_sct_a = "cert_sct_a"; + const string chlo_hash_a = "chlo_hash_a"; + const string server_config_sig_a = "server_config_sig_a"; + const string cert_a = "cert_a"; + + state->server_config = server_config_a; + state->source_address_token = source_address_token_a; + state->cert_sct = cert_sct_a; + state->chlo_hash = chlo_hash_a; + state->server_config_sig = server_config_sig_a; + state->certs.push_back(cert_a); + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + quic_server_info->Persist(); + + // Once we call Persist, IsReadyToPersist should return false until Persist + // has completed. + EXPECT_FALSE(quic_server_info->IsReadyToPersist()); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + + // Verify that the state was updated. + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + const QuicServerInfo::State& state1 = quic_server_info->state(); + EXPECT_EQ(server_config_a, state1.server_config); + EXPECT_EQ(source_address_token_a, state1.source_address_token); + EXPECT_EQ(cert_sct_a, state1.cert_sct); + EXPECT_EQ(chlo_hash_a, state1.chlo_hash); + EXPECT_EQ(server_config_sig_a, state1.server_config_sig); + EXPECT_EQ(1U, state1.certs.size()); + EXPECT_EQ(cert_a, state1.certs[0]); + + RemoveMockTransaction(&kHostInfoTransaction1); +} + +// Test multiple calls to Persist. +TEST(DiskCacheBasedQuicServerInfo, MultiplePersist) { + MockHttpCache cache(true); + AddMockTransaction(&kHostInfoTransaction1); + TestCompletionCallback callback; + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + // Persist data once. + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(state->certs.empty()); + const string server_config_init = "server_config_init"; + const string source_address_token_init = "source_address_token_init"; + const string cert_sct_init = "cert_sct_init"; + const string chlo_hash_init = "chlo_hash_init"; + const string server_config_sig_init = "server_config_sig_init"; + const string cert_init = "cert_init"; + + state->server_config = server_config_init; + state->source_address_token = source_address_token_init; + state->cert_sct = cert_sct_init; + state->chlo_hash = chlo_hash_init; + state->server_config_sig = server_config_sig_init; + state->certs.push_back(cert_init); + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + quic_server_info->Persist(); + + // Once we call Persist, IsReadyToPersist should return false until Persist + // has completed. + EXPECT_FALSE(quic_server_info->IsReadyToPersist()); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + + // Persist one more time using the same |quic_server_info| object and without + // doing another Start() and WaitForDataReady. + const string server_config_a = "server_config_a"; + const string source_address_token_a = "source_address_token_a"; + const string cert_sct_a = "cert_sct_a"; + const string chlo_hash_a = "chlo_hash_a"; + const string server_config_sig_a = "server_config_sig_a"; + const string cert_a = "cert_a"; + + state->server_config = server_config_a; + state->source_address_token = source_address_token_a; + state->cert_sct = cert_sct_a; + state->chlo_hash = chlo_hash_a; + state->server_config_sig = server_config_sig_a; + state->certs.push_back(cert_a); + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + quic_server_info->Persist(); + + // Once we call Persist, IsReadyToPersist should return false until Persist + // has completed. + EXPECT_FALSE(quic_server_info->IsReadyToPersist()); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + + // Verify that the state was updated. + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + const QuicServerInfo::State& state1 = quic_server_info->state(); + EXPECT_EQ(server_config_a, state1.server_config); + EXPECT_EQ(source_address_token_a, state1.source_address_token); + EXPECT_EQ(cert_sct_a, state1.cert_sct); + EXPECT_EQ(chlo_hash_a, state1.chlo_hash); + EXPECT_EQ(server_config_sig_a, state1.server_config_sig); + EXPECT_EQ(1U, state1.certs.size()); + EXPECT_EQ(cert_a, state1.certs[0]); + + RemoveMockTransaction(&kHostInfoTransaction1); +} + +TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReady) { + MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); + MockHttpCache cache(base::WrapUnique(factory), true); + TestCompletionCallback callback; + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + // Now cancel the callback. + quic_server_info->CancelWaitForDataReadyCallback(); + EXPECT_FALSE(quic_server_info->IsDataReady()); + // Now complete the backend creation and let the callback run. + factory->FinishCreation(); + EXPECT_TRUE(quic_server_info->IsDataReady()); +} + +TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyButDataIsReady) { + MockHttpCache cache(true); + AddMockTransaction(&kHostInfoTransaction1); + TestCompletionCallback callback; + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + quic_server_info->CancelWaitForDataReadyCallback(); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + RemoveMockTransaction(&kHostInfoTransaction1); +} + +TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyAfterDeleteCache) { + std::unique_ptr<QuicServerInfo> quic_server_info; + { + MockHttpCache cache(true); + AddMockTransaction(&kHostInfoTransaction1); + TestCompletionCallback callback; + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + quic_server_info->CancelWaitForDataReadyCallback(); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + RemoveMockTransaction(&kHostInfoTransaction1); + } + // Cancel the callback after Cache is deleted. + quic_server_info->ResetWaitForDataReadyCallback(); +} + +// Test Start() followed by Persist() without calling WaitForDataReady. +TEST(DiskCacheBasedQuicServerInfo, StartAndPersist) { + MockHttpCache cache(true); + AddMockTransaction(&kHostInfoTransaction1); + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + quic_server_info->Start(); + // Wait until Start() does the work. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(quic_server_info->IsDataReady()); + + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(state->certs.empty()); + const string server_config_a = "server_config_a"; + const string source_address_token_a = "source_address_token_a"; + const string cert_sct_a = "cert_sct_a"; + const string chlo_hash_a = "chlo_hash_a"; + const string server_config_sig_a = "server_config_sig_a"; + const string cert_a = "cert_a"; + + state->server_config = server_config_a; + state->source_address_token = source_address_token_a; + state->cert_sct = cert_sct_a; + state->chlo_hash = chlo_hash_a; + state->server_config_sig = server_config_sig_a; + state->certs.push_back(cert_a); + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + quic_server_info->Persist(); + quic_server_info->OnExternalCacheHit(); + + // Once we call Persist, IsReadyToPersist should return false until Persist + // has completed. + EXPECT_FALSE(quic_server_info->IsReadyToPersist()); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + + // Verify that the state was updated. + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + TestCompletionCallback callback; + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + const QuicServerInfo::State& state1 = quic_server_info->state(); + EXPECT_EQ(server_config_a, state1.server_config); + EXPECT_EQ(source_address_token_a, state1.source_address_token); + EXPECT_EQ(cert_sct_a, state1.cert_sct); + EXPECT_EQ(chlo_hash_a, state1.chlo_hash); + EXPECT_EQ(server_config_sig_a, state1.server_config_sig); + EXPECT_EQ(1U, state1.certs.size()); + EXPECT_EQ(cert_a, state1.certs[0]); + + RemoveMockTransaction(&kHostInfoTransaction1); +} + +// Test Persisting data when we are not ready to persist and then verify it +// persists the data when Start() finishes. +TEST(DiskCacheBasedQuicServerInfo, PersistWhenNotReadyToPersist) { + MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); + MockHttpCache cache(base::WrapUnique(factory), true); + AddMockTransaction(&kHostInfoTransaction1); + TestCompletionCallback callback; + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + // We do a Start(), but don't call WaitForDataReady(). Because we haven't + // created the backend, we will wait and data wouldn't be ready. + quic_server_info->Start(); + EXPECT_FALSE(quic_server_info->IsDataReady()); + + // Persist data once, even though the backend is not ready. + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(state->certs.empty()); + const string server_config_init = "server_config_init"; + const string source_address_token_init = "source_address_token_init"; + const string cert_sct_init = "cert_sct_init"; + const string chlo_hash_init = "chlo_hash_init"; + const string server_config_sig_init = "server_config_sig_init"; + const string cert_init = "cert_init"; + + state->server_config = server_config_init; + state->source_address_token = source_address_token_init; + state->cert_sct = cert_sct_init; + state->chlo_hash = chlo_hash_init; + state->server_config_sig = server_config_sig_init; + state->certs.push_back(cert_init); + EXPECT_FALSE(quic_server_info->IsReadyToPersist()); + quic_server_info->Persist(); + EXPECT_FALSE(quic_server_info->IsReadyToPersist()); + + // Now complete the backend creation and let the callback run. + factory->FinishCreation(); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + // Verify that the state was updated. + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + const QuicServerInfo::State& state1 = quic_server_info->state(); + EXPECT_EQ(server_config_init, state1.server_config); + EXPECT_EQ(source_address_token_init, state1.source_address_token); + EXPECT_EQ(cert_sct_init, state1.cert_sct); + EXPECT_EQ(chlo_hash_init, state1.chlo_hash); + EXPECT_EQ(server_config_sig_init, state1.server_config_sig); + EXPECT_EQ(1U, state1.certs.size()); + EXPECT_EQ(cert_init, state1.certs[0]); + RemoveMockTransaction(&kHostInfoTransaction1); +} + +// Test multiple calls to Persist without waiting for the data to be written. +TEST(DiskCacheBasedQuicServerInfo, MultiplePersistsWithoutWaiting) { + MockHttpCache cache(true); + AddMockTransaction(&kHostInfoTransaction1); + TestCompletionCallback callback; + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + EXPECT_FALSE(quic_server_info->IsDataReady()); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + // Persist data once. + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(state->certs.empty()); + const string server_config_init = "server_config_init"; + const string source_address_token_init = "source_address_token_init"; + const string cert_sct_init = "cert_sct_init"; + const string chlo_hash_init = "chlo_hash_init"; + const string server_config_sig_init = "server_config_sig_init"; + const string cert_init = "cert_init"; + + state->server_config = server_config_init; + state->source_address_token = source_address_token_init; + state->cert_sct = cert_sct_init; + state->chlo_hash = chlo_hash_init; + state->server_config_sig = server_config_sig_init; + state->certs.push_back(cert_init); + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + quic_server_info->Persist(); + + // Once we call Persist, IsReadyToPersist should return false until Persist + // has completed. + EXPECT_FALSE(quic_server_info->IsReadyToPersist()); + + // Persist one more time using the same |quic_server_info| object and without + // doing another Start() and WaitForDataReady. + const string server_config_a = "server_config_a"; + const string source_address_token_a = "source_address_token_a"; + const string cert_sct_a = "cert_sct_a"; + const string chlo_hash_a = "chlo_hash_a"; + const string server_config_sig_a = "server_config_sig_a"; + const string cert_a = "cert_a"; + + state->server_config = server_config_a; + state->source_address_token = source_address_token_a; + state->cert_sct = cert_sct_a; + state->chlo_hash = chlo_hash_a; + state->server_config_sig = server_config_sig_a; + state->certs.push_back(cert_a); + EXPECT_FALSE(quic_server_info->IsReadyToPersist()); + quic_server_info->Persist(); + + // Wait until Persist() does the work. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(quic_server_info->IsReadyToPersist()); + + // Verify that the state was updated. + quic_server_info.reset( + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + EXPECT_TRUE(quic_server_info->IsDataReady()); + + // Verify the second time persisted data is persisted. + const QuicServerInfo::State& state1 = quic_server_info->state(); + EXPECT_EQ(server_config_a, state1.server_config); + EXPECT_EQ(source_address_token_a, state1.source_address_token); + EXPECT_EQ(cert_sct_a, state1.cert_sct); + EXPECT_EQ(chlo_hash_a, state1.chlo_hash); + EXPECT_EQ(server_config_sig_a, state1.server_config_sig); + EXPECT_EQ(1U, state1.certs.size()); + EXPECT_EQ(cert_a, state1.certs[0]); + + RemoveMockTransaction(&kHostInfoTransaction1); +} + +// crbug.com/439209: test deletion of QuicServerInfo object in the callback +// doesn't crash. +TEST(DiskCacheBasedQuicServerInfo, DeleteServerInfoInCallback) { + // Use the blocking mock backend factory to force asynchronous completion + // of quic_server_info->WaitForDataReady(), so that the callback will run. + MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); + MockHttpCache cache(base::WrapUnique(factory), true); + QuicServerId server_id("www.verisign.com", 443, PRIVACY_MODE_DISABLED); + QuicServerInfo* quic_server_info = + new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()); + // |cb| takes owndership and deletes |quic_server_info| when it is called. + DeleteCacheCompletionCallback cb(quic_server_info); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(cb.callback()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + // Now complete the backend creation and let the callback run. + factory->FinishCreation(); + EXPECT_THAT(cb.GetResult(rv), IsOk()); +} + +} // namespace net
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 968cffa..93d39cc 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc
@@ -37,6 +37,7 @@ #include "net/base/net_errors.h" #include "net/base/upload_data_stream.h" #include "net/disk_cache/disk_cache.h" +#include "net/http/disk_cache_based_quic_server_info.h" #include "net/http/http_cache_lookup_manager.h" #include "net/http/http_cache_transaction.h" #include "net/http/http_network_layer.h" @@ -302,6 +303,24 @@ } //----------------------------------------------------------------------------- + +class HttpCache::QuicServerInfoFactoryAdaptor : public QuicServerInfoFactory { + public: + explicit QuicServerInfoFactoryAdaptor(HttpCache* http_cache) + : http_cache_(http_cache) { + } + + std::unique_ptr<QuicServerInfo> GetForServer( + const QuicServerId& server_id) override { + return base::MakeUnique<DiskCacheBasedQuicServerInfo>(server_id, + http_cache_); + } + + private: + HttpCache* const http_cache_; +}; + +//----------------------------------------------------------------------------- HttpCache::HttpCache(HttpNetworkSession* session, std::unique_ptr<BackendFactory> backend_factory, bool is_main_cache) @@ -334,6 +353,12 @@ session->SetServerPushDelegate( base::MakeUnique<HttpCacheLookupManager>(this)); + + if (!session->quic_stream_factory()->has_quic_server_info_factory()) { + // QuicStreamFactory takes ownership of QuicServerInfoFactoryAdaptor. + session->quic_stream_factory()->set_quic_server_info_factory( + new QuicServerInfoFactoryAdaptor(this)); + } } HttpCache::~HttpCache() {
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 30fa1a0..9fdfc05 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -123,7 +123,10 @@ enable_quic(false), mark_quic_broken_when_network_blackholes(false), retry_without_alt_svc_on_quic_errors(false), + quic_load_server_info_timeout_srtt_multiplier(0.25f), + quic_enable_connection_racing(false), quic_enable_non_blocking_io(false), + quic_disable_disk_cache(false), quic_max_server_configs_stored_in_properties(0u), quic_clock(nullptr), quic_random(nullptr), @@ -187,8 +190,11 @@ params.quic_max_packet_length, params.quic_user_agent_id, params.quic_supported_versions, + params.quic_load_server_info_timeout_srtt_multiplier, + params.quic_enable_connection_racing, params.quic_enable_non_blocking_io, - params.quic_max_server_configs_stored_in_properties > 0, + params.quic_disable_disk_cache, + params.quic_max_server_configs_stored_in_properties, params.quic_close_sessions_on_ip_change, params.mark_quic_broken_when_network_blackholes, params.quic_idle_connection_timeout_seconds, @@ -320,6 +326,11 @@ } dict->Set("origins_to_force_quic_on", std::move(origins_to_force_quic_on)); + dict->SetDouble("load_server_info_timeout_srtt_multiplier", + params_.quic_load_server_info_timeout_srtt_multiplier); + dict->SetBoolean("enable_connection_racing", + params_.quic_enable_connection_racing); + dict->SetBoolean("disable_disk_cache", params_.quic_disable_disk_cache); dict->SetInteger("max_server_configs_stored_in_properties", params_.quic_max_server_configs_stored_in_properties); dict->SetInteger("idle_connection_timeout_seconds",
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index a2117e06..f9115f46 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h
@@ -122,8 +122,17 @@ // Retry requests which fail with QUIC_PROTOCOL_ERROR, and mark QUIC // broken if the retry succeeds. bool retry_without_alt_svc_on_quic_errors; + // If not zero, the task to load QUIC server configs from the disk cache + // will timeout after this value multiplied by the smoothed RTT for the + // server. + float quic_load_server_info_timeout_srtt_multiplier; + // Causes QUIC to race reading the server config from disk with + // sending an inchoate CHLO. + bool quic_enable_connection_racing; // Use non-blocking IO for UDP sockets. bool quic_enable_non_blocking_io; + // Disables using the disk cache to store QUIC server configs. + bool quic_disable_disk_cache; // Maximum number of server configs that are to be stored in // HttpServerProperties, instead of the disk cache. size_t quic_max_server_configs_stored_in_properties;
diff --git a/net/quic/chromium/properties_based_quic_server_info.cc b/net/quic/chromium/properties_based_quic_server_info.cc index 54d1b6da..e90331f 100644 --- a/net/quic/chromium/properties_based_quic_server_info.cc +++ b/net/quic/chromium/properties_based_quic_server_info.cc
@@ -14,6 +14,13 @@ namespace { +void RecordQuicServerInfoStatus( + net::QuicServerInfo::QuicServerInfoAPICall call) { + UMA_HISTOGRAM_ENUMERATION( + "Net.QuicDiskCache.APICall.PropertiesBasedCache", call, + net::QuicServerInfo::QUIC_SERVER_INFO_NUM_OF_API_CALLS); +} + void RecordQuicServerInfoFailure(net::QuicServerInfo::FailureReason failure) { UMA_HISTOGRAM_ENUMERATION( "Net.QuicDiskCache.FailureReason.PropertiesBasedCache", failure, @@ -34,33 +41,74 @@ PropertiesBasedQuicServerInfo::~PropertiesBasedQuicServerInfo() {} -bool PropertiesBasedQuicServerInfo::Load() { +void PropertiesBasedQuicServerInfo::Start() { + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_START); +} + +int PropertiesBasedQuicServerInfo::WaitForDataReady( + const CompletionCallback& callback) { + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY); const string* data = http_server_properties_->GetQuicServerInfo(server_id_); string decoded; if (!data) { RecordQuicServerInfoFailure(PARSE_NO_DATA_FAILURE); - return false; + return ERR_FAILED; } if (!base::Base64Decode(*data, &decoded)) { RecordQuicServerInfoFailure(PARSE_DATA_DECODE_FAILURE); - return false; + return ERR_FAILED; } + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_PARSE); if (!Parse(decoded)) { RecordQuicServerInfoFailure(PARSE_FAILURE); - return false; + return ERR_FAILED; } + return OK; +} + +void PropertiesBasedQuicServerInfo::ResetWaitForDataReadyCallback() { + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_RESET_WAIT_FOR_DATA_READY); +} + +void PropertiesBasedQuicServerInfo::CancelWaitForDataReadyCallback() { + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL); +} + +bool PropertiesBasedQuicServerInfo::IsDataReady() { return true; } +bool PropertiesBasedQuicServerInfo::IsReadyToPersist() { + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_READY_TO_PERSIST); + return true; +} void PropertiesBasedQuicServerInfo::Persist() { + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_PERSIST); string encoded; base::Base64Encode(Serialize(), &encoded); http_server_properties_->SetQuicServerInfo(server_id_, encoded); } +void PropertiesBasedQuicServerInfo::OnExternalCacheHit() { + RecordQuicServerInfoStatus(QUIC_SERVER_INFO_EXTERNAL_CACHE_HIT); +} + size_t PropertiesBasedQuicServerInfo::EstimateMemoryUsage() const { return 0; } +PropertiesBasedQuicServerInfoFactory::PropertiesBasedQuicServerInfoFactory( + HttpServerProperties* http_server_properties) + : http_server_properties_(http_server_properties) {} + +PropertiesBasedQuicServerInfoFactory::~PropertiesBasedQuicServerInfoFactory() {} + +std::unique_ptr<QuicServerInfo> +PropertiesBasedQuicServerInfoFactory::GetForServer( + const QuicServerId& server_id) { + return base::MakeUnique<PropertiesBasedQuicServerInfo>( + server_id, http_server_properties_); +} + } // namespace net
diff --git a/net/quic/chromium/properties_based_quic_server_info.h b/net/quic/chromium/properties_based_quic_server_info.h index df85a9d8..35ebb9b7 100644 --- a/net/quic/chromium/properties_based_quic_server_info.h +++ b/net/quic/chromium/properties_based_quic_server_info.h
@@ -30,8 +30,14 @@ ~PropertiesBasedQuicServerInfo() override; // QuicServerInfo implementation. - bool Load() override; + void Start() override; + int WaitForDataReady(const CompletionCallback& callback) override; + void ResetWaitForDataReadyCallback() override; + void CancelWaitForDataReadyCallback() override; + bool IsDataReady() override; + bool IsReadyToPersist() override; void Persist() override; + void OnExternalCacheHit() override; size_t EstimateMemoryUsage() const override; private: @@ -40,6 +46,22 @@ DISALLOW_COPY_AND_ASSIGN(PropertiesBasedQuicServerInfo); }; +class QUIC_EXPORT_PRIVATE PropertiesBasedQuicServerInfoFactory + : public QuicServerInfoFactory { + public: + explicit PropertiesBasedQuicServerInfoFactory( + HttpServerProperties* http_server_properties); + ~PropertiesBasedQuicServerInfoFactory() override; + + std::unique_ptr<QuicServerInfo> GetForServer( + const QuicServerId& server_id) override; + + private: + HttpServerProperties* http_server_properties_; + + DISALLOW_COPY_AND_ASSIGN(PropertiesBasedQuicServerInfoFactory); +}; + } // namespace net #endif // NET_QUIC_CHROMIUM_PROPERTIES_BASED_QUIC_SERVER_INFO_H_
diff --git a/net/quic/chromium/properties_based_quic_server_info_test.cc b/net/quic/chromium/properties_based_quic_server_info_test.cc index c4cc0638..aba7c635 100644 --- a/net/quic/chromium/properties_based_quic_server_info_test.cc +++ b/net/quic/chromium/properties_based_quic_server_info_test.cc
@@ -34,6 +34,8 @@ // Initialize |server_info_| object and persist it. void InitializeAndPersist() { + server_info_.Start(); + EXPECT_TRUE(server_info_.IsDataReady()); QuicServerInfo::State* state = server_info_.mutable_state(); EXPECT_TRUE(state->certs.empty()); @@ -43,7 +45,11 @@ state->cert_sct = kCertSCTA; state->chlo_hash = kChloHashA; state->certs.push_back(kCertA); + EXPECT_TRUE(server_info_.IsReadyToPersist()); server_info_.Persist(); + EXPECT_TRUE(server_info_.IsReadyToPersist()); + EXPECT_TRUE(server_info_.IsDataReady()); + server_info_.OnExternalCacheHit(); } // Verify the data that is persisted in InitializeAndPersist(). @@ -69,7 +75,10 @@ // Read the persisted data and verify we have read the data correctly. PropertiesBasedQuicServerInfo server_info1(server_id_, &http_server_properties_); - EXPECT_TRUE(server_info1.Load()); + server_info1.Start(); + EXPECT_THAT(server_info1.WaitForDataReady(callback_), + IsOk()); // Read the data. + EXPECT_TRUE(server_info1.IsDataReady()); // Verify the data. const QuicServerInfo::State& state1 = server_info1.state(); @@ -79,12 +88,16 @@ // Update the data, by adding another cert. QuicServerInfo::State* state2 = server_info1.mutable_state(); state2->certs.push_back(kCertB); + EXPECT_TRUE(server_info_.IsReadyToPersist()); server_info1.Persist(); // Read the persisted data and verify we have read the data correctly. PropertiesBasedQuicServerInfo server_info2(server_id_, &http_server_properties_); - EXPECT_TRUE(server_info2.Load()); + server_info2.Start(); + EXPECT_THAT(server_info2.WaitForDataReady(callback_), + IsOk()); // Read the data. + EXPECT_TRUE(server_info1.IsDataReady()); // Verify updated data. const QuicServerInfo::State& state3 = server_info2.state();
diff --git a/net/quic/chromium/quic_chromium_client_session.cc b/net/quic/chromium/quic_chromium_client_session.cc index 6913eb5..27818a5c 100644 --- a/net/quic/chromium/quic_chromium_client_session.cc +++ b/net/quic/chromium/quic_chromium_client_session.cc
@@ -375,8 +375,24 @@ round_trip_handshakes, 1, 3, 4); } } - const QuicConnectionStats stats = connection()->GetStats(); + if (server_info_ && stats.min_rtt_us > 0) { + base::TimeTicks wait_for_data_start_time = + server_info_->wait_for_data_start_time(); + base::TimeTicks wait_for_data_end_time = + server_info_->wait_for_data_end_time(); + if (!wait_for_data_start_time.is_null() && + !wait_for_data_end_time.is_null()) { + base::TimeDelta wait_time = + wait_for_data_end_time - wait_for_data_start_time; + const base::HistogramBase::Sample kMaxWaitToRtt = 1000; + base::HistogramBase::Sample wait_to_rtt = + static_cast<base::HistogramBase::Sample>( + 100 * wait_time.InMicroseconds() / stats.min_rtt_us); + UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicServerInfo.WaitForDataReadyToRtt", + wait_to_rtt, 1, kMaxWaitToRtt, 50); + } + } // The MTU used by QUIC is limited to a fairly small set of predefined values // (initial values and MTU discovery values), but does not fare well when @@ -846,6 +862,21 @@ UMA_HISTOGRAM_TIMES( "Net.QuicSession.HandshakeConfirmedTime", connect_timing_.connect_end - connect_timing_.connect_start); + + if (server_info_) { + // TODO(rtenneti): Should we delete this histogram? + // Track how long it has taken to finish handshake once we start waiting + // for reading of QUIC server information from disk cache. We could use + // this data to compare total time taken if we were to cancel the disk + // cache read vs waiting for the read to complete. + base::TimeTicks wait_for_data_start_time = + server_info_->wait_for_data_start_time(); + if (!wait_for_data_start_time.is_null()) { + UMA_HISTOGRAM_TIMES( + "Net.QuicServerInfo.WaitForDataReady.HandshakeConfirmedTime", + base::TimeTicks::Now() - wait_for_data_start_time); + } + } // Track how long it has taken to finish handshake after we have finished // DNS host resolution. if (!connect_timing_.dns_end.is_null()) { @@ -860,6 +891,8 @@ ++it; observer->OnCryptoHandshakeConfirmed(); } + if (server_info_) + server_info_->OnExternalCacheHit(); } QuicSpdySession::OnCryptoHandshakeEvent(event); }
diff --git a/net/quic/chromium/quic_server_info.cc b/net/quic/chromium/quic_server_info.cc index 3e53fa5..23f4cf8a 100644 --- a/net/quic/chromium/quic_server_info.cc +++ b/net/quic/chromium/quic_server_info.cc
@@ -146,4 +146,6 @@ return string(reinterpret_cast<const char*>(p.data()), p.size()); } +QuicServerInfoFactory::~QuicServerInfoFactory() {} + } // namespace net
diff --git a/net/quic/chromium/quic_server_info.h b/net/quic/chromium/quic_server_info.h index a818576..eab5366 100644 --- a/net/quic/chromium/quic_server_info.h +++ b/net/quic/chromium/quic_server_info.h
@@ -24,6 +24,20 @@ // crypto config. class QUIC_EXPORT_PRIVATE QuicServerInfo { public: + // Enum to track number of times data read/parse/write API calls of + // QuicServerInfo to and from disk cache is called. + enum QuicServerInfoAPICall { + QUIC_SERVER_INFO_START = 0, + QUIC_SERVER_INFO_WAIT_FOR_DATA_READY = 1, + QUIC_SERVER_INFO_PARSE = 2, + QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL = 3, + QUIC_SERVER_INFO_READY_TO_PERSIST = 4, + QUIC_SERVER_INFO_PERSIST = 5, + QUIC_SERVER_INFO_EXTERNAL_CACHE_HIT = 6, + QUIC_SERVER_INFO_RESET_WAIT_FOR_DATA_READY = 7, + QUIC_SERVER_INFO_NUM_OF_API_CALLS = 8, + }; + // Enum to track failure reasons to read/load/write of QuicServerInfo to // and from disk cache. enum FailureReason { @@ -45,13 +59,49 @@ explicit QuicServerInfo(const QuicServerId& server_id); virtual ~QuicServerInfo(); - // Fetches the server config from the backing store, and returns true - // if the server config was found. - virtual bool Load() = 0; + // Start will commence the lookup. This must be called before any other + // methods. By opportunistically calling this early, it may be possible to + // overlap this object's lookup and reduce latency. + virtual void Start() = 0; - // Persist allows for the server information to be updated for future uses. + // WaitForDataReady returns OK if the fetch of the requested data has + // completed. Otherwise it returns ERR_IO_PENDING and will call |callback| on + // the current thread when ready. + // + // Only a single callback can be outstanding at a given time and, in the + // event that WaitForDataReady returns OK, it's the caller's responsibility + // to delete |callback|. + // + // |callback| may be NULL, in which case ERR_IO_PENDING may still be returned + // but, obviously, a callback will never be made. + virtual int WaitForDataReady(const CompletionCallback& callback) = 0; + + // Reset's WaitForDataReady callback. This method shouldn't have any side + // effects (could be called even if HttpCache doesn't exist). + virtual void ResetWaitForDataReadyCallback() = 0; + + // Cancel's WaitForDataReady callback. |callback| passed in WaitForDataReady + // will not be called. + virtual void CancelWaitForDataReadyCallback() = 0; + + // Returns true if data is loaded from disk cache and ready (WaitForDataReady + // doesn't have a pending callback). + virtual bool IsDataReady() = 0; + + // Returns true if the object is ready to persist data, in other words, if + // data is loaded from disk cache and ready and there are no pending writes. + virtual bool IsReadyToPersist() = 0; + + // Persist allows for the server information to be updated for future users. + // This is a fire and forget operation: the caller may drop its reference + // from this object and the store operation will still complete. This can + // only be called once WaitForDataReady has returned OK or called its + // callback. virtual void Persist() = 0; + // Called whenever an external cache reuses quic server config. + virtual void OnExternalCacheHit() = 0; + // Returns the size of dynamically allocated memory in bytes. virtual size_t EstimateMemoryUsage() const = 0; @@ -79,6 +129,14 @@ const State& state() const; State* mutable_state(); + base::TimeTicks wait_for_data_start_time() const { + return wait_for_data_start_time_; + } + + base::TimeTicks wait_for_data_end_time() const { + return wait_for_data_end_time_; + } + protected: // Parse parses pickled data and fills out the public member fields of this // object. It returns true iff the parse was successful. The public member @@ -88,6 +146,10 @@ State state_; + // Time when WaitForDataReady was called and when it has finished. + base::TimeTicks wait_for_data_start_time_; + base::TimeTicks wait_for_data_end_time_; + // This is the QUIC server (hostname, port, is_https, privacy_mode) tuple for // which we restore the crypto_config. const QuicServerId server_id_; @@ -102,6 +164,20 @@ DISALLOW_COPY_AND_ASSIGN(QuicServerInfo); }; +class QUIC_EXPORT_PRIVATE QuicServerInfoFactory { + public: + QuicServerInfoFactory() {} + virtual ~QuicServerInfoFactory(); + + // GetForServer returns a fresh, allocated QuicServerInfo for the given + // |server_id| or NULL on failure. + virtual std::unique_ptr<QuicServerInfo> GetForServer( + const QuicServerId& server_id) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(QuicServerInfoFactory); +}; + } // namespace net #endif // NET_QUIC_CHROMIUM_QUIC_SERVER_INFO_H_
diff --git a/net/quic/chromium/quic_stream_factory.cc b/net/quic/chromium/quic_stream_factory.cc index e334ede4..ff9a91a 100644 --- a/net/quic/chromium/quic_stream_factory.cc +++ b/net/quic/chromium/quic_stream_factory.cc
@@ -331,8 +331,16 @@ const QuicSessionKey& key, bool was_alternative_service_recently_broken, int cert_verify_flags, + std::unique_ptr<QuicServerInfo> server_info, const NetLogWithSource& net_log); + // Creates a new job to handle the resumption of for connecting an + // existing session. + Job(QuicStreamFactory* factory, + HostResolver* host_resolver, + QuicChromiumClientSession* session, + const QuicSessionKey& key); + ~Job(); int Run(const CompletionCallback& callback); @@ -340,13 +348,19 @@ int DoLoop(int rv); int DoResolveHost(); int DoResolveHostComplete(int rv); + int DoLoadServerInfo(); + int DoLoadServerInfoComplete(int rv); int DoConnect(); int DoConnectComplete(int rv); void OnIOComplete(int rv); + void RunAuxilaryJob(); + void Cancel(); + void CancelWaitForDataReadyCallback(); + const QuicSessionKey& key() const { return key_; } const NetLogWithSource& net_log() const { return net_log_; } @@ -361,6 +375,8 @@ STATE_NONE, STATE_RESOLVE_HOST, STATE_RESOLVE_HOST_COMPLETE, + STATE_LOAD_SERVER_INFO, + STATE_LOAD_SERVER_INFO_COMPLETE, STATE_CONNECT, STATE_CONNECT_COMPLETE, }; @@ -372,6 +388,8 @@ const QuicSessionKey key_; const int cert_verify_flags_; const bool was_alternative_service_recently_broken_; + std::unique_ptr<QuicServerInfo> server_info_; + bool started_another_job_; const NetLogWithSource net_log_; int num_sent_client_hellos_; QuicChromiumClientSession* session_; @@ -388,6 +406,7 @@ const QuicSessionKey& key, bool was_alternative_service_recently_broken, int cert_verify_flags, + std::unique_ptr<QuicServerInfo> server_info, const NetLogWithSource& net_log) : io_state_(STATE_RESOLVE_HOST), factory_(factory), @@ -396,6 +415,8 @@ cert_verify_flags_(cert_verify_flags), was_alternative_service_recently_broken_( was_alternative_service_recently_broken), + server_info_(std::move(server_info)), + started_another_job_(false), net_log_( NetLogWithSource::Make(net_log.net_log(), NetLogSourceType::QUIC_STREAM_FACTORY_JOB)), @@ -417,6 +438,10 @@ QuicStreamFactory::Job::~Job() { net_log_.EndEvent(NetLogEventType::QUIC_STREAM_FACTORY_JOB); DCHECK(callback_.is_null()); + + // If disk cache has a pending WaitForDataReadyCallback, cancel that callback. + if (server_info_) + server_info_->ResetWaitForDataReadyCallback(); } int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { @@ -440,6 +465,13 @@ case STATE_RESOLVE_HOST_COMPLETE: rv = DoResolveHostComplete(rv); break; + case STATE_LOAD_SERVER_INFO: + CHECK_EQ(OK, rv); + rv = DoLoadServerInfo(); + break; + case STATE_LOAD_SERVER_INFO_COMPLETE: + rv = DoLoadServerInfoComplete(rv); + break; case STATE_CONNECT: CHECK_EQ(OK, rv); rv = DoConnect(); @@ -461,6 +493,13 @@ base::ResetAndReturn(&callback_).Run(rv); } +void QuicStreamFactory::Job::RunAuxilaryJob() { + int rv = Run(base::Bind(&QuicStreamFactory::OnJobComplete, + base::Unretained(factory_), this)); + if (rv != ERR_IO_PENDING) + factory_->OnJobComplete(this, rv); +} + void QuicStreamFactory::Job::Cancel() { callback_.Reset(); if (session_) @@ -469,12 +508,24 @@ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); } +void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { + // If we are waiting for WaitForDataReadyCallback, then cancel the callback. + if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) + return; + server_info_->CancelWaitForDataReadyCallback(); + OnIOComplete(OK); +} + size_t QuicStreamFactory::Job::EstimateMemoryUsage() const { - return base::trace_event::EstimateMemoryUsage(key_); + return base::trace_event::EstimateMemoryUsage(key_) + + base::trace_event::EstimateMemoryUsage(server_info_); } int QuicStreamFactory::Job::DoResolveHost() { dns_resolution_start_time_ = base::TimeTicks::Now(); + // Start loading the data now, and wait for it after we resolve the host. + if (server_info_) + server_info_->Start(); io_state_ = STATE_RESOLVE_HOST_COMPLETE; return host_resolver_->Resolve( @@ -496,6 +547,71 @@ if (factory_->OnResolution(key_, address_list_)) return OK; + if (server_info_) + io_state_ = STATE_LOAD_SERVER_INFO; + else + io_state_ = STATE_CONNECT; + return OK; +} + +int QuicStreamFactory::Job::DoLoadServerInfo() { + net_log_.BeginEvent( + NetLogEventType::QUIC_STREAM_FACTORY_JOB_LOAD_SERVER_INFO); + + io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; + + DCHECK(server_info_); + + // To mitigate the effects of disk cache taking too long to load QUIC server + // information, set up a timer to cancel WaitForDataReady's callback. + if (factory_->load_server_info_timeout_srtt_multiplier_ > 0) { + const int kMaxLoadServerInfoTimeoutMs = 50; + // Wait for DiskCache a maximum of 50ms. + int64_t load_server_info_timeout_ms = + std::min(static_cast<int>( + (factory_->load_server_info_timeout_srtt_multiplier_ * + factory_->GetServerNetworkStatsSmoothedRttInMicroseconds( + key_.server_id())) / + 1000), + kMaxLoadServerInfoTimeoutMs); + if (load_server_info_timeout_ms > 0) { + factory_->task_runner_->PostDelayedTask( + FROM_HERE, + base::Bind(&QuicStreamFactory::Job::CancelWaitForDataReadyCallback, + GetWeakPtr()), + base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); + } + } + + int rv = server_info_->WaitForDataReady( + base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); + if (rv == ERR_IO_PENDING && factory_->enable_connection_racing()) { + // If we are waiting to load server config from the disk cache, then start + // another job. + started_another_job_ = true; + factory_->CreateAuxilaryJob(key_, cert_verify_flags_, net_log_); + } + return rv; +} + +int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { + net_log_.EndEvent(NetLogEventType::QUIC_STREAM_FACTORY_JOB_LOAD_SERVER_INFO); + UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", + base::TimeTicks::Now() - dns_resolution_end_time_); + + if (rv != OK) + server_info_.reset(); + + if (started_another_job_ && + (!server_info_ || server_info_->state().server_config.empty() || + !factory_->CryptoConfigCacheIsEmpty(key_.server_id()))) { + // If we have started another job and if we didn't load the server config + // from the disk cache or if we have received a new server config from the + // server, then cancel the current job. + io_state_ = STATE_NONE; + return ERR_CONNECTION_CLOSED; + } + io_state_ = STATE_CONNECT; return OK; } @@ -509,10 +625,10 @@ NetLogEventType::QUIC_STREAM_FACTORY_JOB_CONNECT, NetLog::BoolCallback("require_confirmation", require_confirmation)); - int rv = - factory_->CreateSession(key_, cert_verify_flags_, require_confirmation, - address_list_, dns_resolution_start_time_, - dns_resolution_end_time_, net_log_, &session_); + int rv = factory_->CreateSession( + key_, cert_verify_flags_, std::move(server_info_), require_confirmation, + address_list_, dns_resolution_start_time_, dns_resolution_end_time_, + net_log_, &session_); if (rv != OK) { DCHECK(rv != ERR_IO_PENDING); DCHECK(!session_); @@ -655,8 +771,11 @@ size_t max_packet_length, const std::string& user_agent_id, const QuicVersionVector& supported_versions, + float load_server_info_timeout_srtt_multiplier, + bool enable_connection_racing, bool enable_non_blocking_io, - bool store_server_configs_in_properties, + bool disable_disk_cache, + int max_server_configs_stored_in_properties, bool close_sessions_on_ip_change, bool mark_quic_broken_when_network_blackholes, int idle_connection_timeout_seconds, @@ -694,10 +813,13 @@ transport_security_state, cert_transparency_verifier))), supported_versions_(supported_versions), + load_server_info_timeout_srtt_multiplier_( + load_server_info_timeout_srtt_multiplier), + enable_connection_racing_(enable_connection_racing), enable_non_blocking_io_(enable_non_blocking_io), + disable_disk_cache_(disable_disk_cache), mark_quic_broken_when_network_blackholes_( mark_quic_broken_when_network_blackholes), - store_server_configs_in_properties_(store_server_configs_in_properties), ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)), reduced_ping_timeout_( QuicTime::Delta::FromSeconds(reduced_ping_timeout_seconds)), @@ -716,6 +838,7 @@ do_not_fragment_(do_not_fragment), estimate_initial_rtt(estimate_initial_rtt), check_persisted_supports_quic_(true), + has_initialized_data_(false), num_push_streams_created_(0), task_runner_(nullptr), ssl_config_service_(ssl_config_service), @@ -743,6 +866,13 @@ has_aes_hardware_support); if (has_aes_hardware_support) crypto_config_.PreferAesGcm(); + // When disk cache is used to store the server configs, HttpCache code calls + // |set_quic_server_info_factory| if |quic_server_info_factory_| wasn't + // created. + if (max_server_configs_stored_in_properties > 0) { + quic_server_info_factory_.reset( + new PropertiesBasedQuicServerInfoFactory(http_server_properties_)); + } // migrate_sessions_early should only be set to true if // migrate_sessions_on_network_change is set to true. @@ -800,6 +930,11 @@ return base::TimeDelta::FromMicroseconds(srtt); } +void QuicStreamFactory::set_quic_server_info_factory( + QuicServerInfoFactory* quic_server_info_factory) { + quic_server_info_factory_.reset(quic_server_info_factory); +} + void QuicStreamFactory::DumpMemoryStats( base::trace_event::ProcessMemoryDump* pmd, const std::string& parent_absolute_name) const { @@ -934,12 +1069,25 @@ if (!task_runner_) task_runner_ = base::ThreadTaskRunnerHandle::Get().get(); + std::unique_ptr<QuicServerInfo> quic_server_info; + if (quic_server_info_factory_.get()) { + bool load_from_disk_cache = !disable_disk_cache_; + MaybeInitialize(); + if (!base::ContainsKey(quic_supported_servers_at_startup_, destination)) { + // If there is no entry for QUIC, consider that as a new server and + // don't wait for Cache thread to load the data for that server. + load_from_disk_cache = false; + } + if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) + quic_server_info = quic_server_info_factory_->GetForServer(server_id); + } + ignore_result(StartCertVerifyJob(server_id, cert_verify_flags, net_log)); QuicSessionKey key(destination, server_id); std::unique_ptr<Job> job = base::MakeUnique<Job>( this, host_resolver_, key, WasQuicRecentlyBroken(server_id), - cert_verify_flags, net_log); + cert_verify_flags, std::move(quic_server_info), net_log); int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, base::Unretained(this), job.get())); if (rv == ERR_IO_PENDING) { @@ -985,6 +1133,18 @@ EstimateServerIdMemoryUsage(server_id_); } +void QuicStreamFactory::CreateAuxilaryJob(const QuicSessionKey& key, + int cert_verify_flags, + const NetLogWithSource& net_log) { + Job* aux_job = + new Job(this, host_resolver_, key, WasQuicRecentlyBroken(key.server_id()), + cert_verify_flags, nullptr, net_log); + active_jobs_[key.server_id()][aux_job] = base::WrapUnique(aux_job); + task_runner_->PostTask(FROM_HERE, + base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, + aux_job->GetWeakPtr())); +} + bool QuicStreamFactory::OnResolution(const QuicSessionKey& key, const AddressList& address_list) { const QuicServerId& server_id(key.server_id()); @@ -1483,6 +1643,7 @@ int QuicStreamFactory::CreateSession( const QuicSessionKey& key, int cert_verify_flags, + std::unique_ptr<QuicServerInfo> server_info, bool require_confirmation, const AddressList& address_list, base::TimeTicks dns_resolution_start_time, @@ -1511,13 +1672,7 @@ alarm_factory_.reset(new QuicChromiumAlarmFactory( base::ThreadTaskRunnerHandle::Get().get(), clock_)); } - QuicConnectionId connection_id = random_generator_->RandUint64(); - std::unique_ptr<QuicServerInfo> server_info; - if (store_server_configs_in_properties_) { - server_info = base::MakeUnique<PropertiesBasedQuicServerInfo>( - server_id, http_server_properties_); - } InitializeCachedStateInCryptoConfig(server_id, server_info, &connection_id); QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(socket.get()); @@ -1539,6 +1694,14 @@ if (force_hol_blocking_) config.SetForceHolBlocking(); + if (quic_server_info_factory_.get() && !server_info) { + // Start the disk cache loading so that we can persist the newer QUIC server + // information and/or inform the disk cache that we have reused + // |server_info|. + server_info = quic_server_info_factory_->GetForServer(server_id); + server_info->Start(); + } + // Use the factory to create a new socket performance watcher, and pass the // ownership to QuicChromiumClientSession. std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher; @@ -1681,9 +1844,20 @@ if (!cached->IsEmpty()) return; - if (!server_info || !server_info->Load()) + // |server_info| will be NULL, if a non-empty server config already exists in + // the memory cache. + if (!server_info) return; + // TODO(rtenneti): Delete the following histogram after collecting stats. + // If the AlternativeServiceMap contained an entry for this host, check if + // the disk cache contained an entry for it. + if (base::ContainsKey(quic_supported_servers_at_startup_, + server_id.host_port_pair())) { + UMA_HISTOGRAM_BOOLEAN("Net.QuicServerInfo.ExpectConfigMissingFromDiskCache", + server_info->state().server_config.empty()); + } + cached->Initialize(server_info->state().server_config, server_info->state().source_address_token, server_info->state().certs, server_info->state().cert_sct, @@ -1692,6 +1866,60 @@ QuicWallTime::Zero()); } +void QuicStreamFactory::MaybeInitialize() { + // We don't initialize data from HttpServerProperties in the constructor + // because HttpServerProperties has not yet initialized. We're guaranteed + // HttpServerProperties has been initialized by the first time a request is + // made. + if (has_initialized_data_) + return; + + has_initialized_data_ = true; + + // Query the proxy delegate for the default alternative proxy server. + ProxyServer default_alternative_proxy_server = + proxy_delegate_ ? proxy_delegate_->GetDefaultAlternativeProxy() + : ProxyServer(); + if (default_alternative_proxy_server.is_quic()) { + quic_supported_servers_at_startup_.insert( + default_alternative_proxy_server.host_port_pair()); + } + + for (const std::pair<const url::SchemeHostPort, AlternativeServiceInfoVector>& + key_value : http_server_properties_->alternative_service_map()) { + HostPortPair host_port_pair(key_value.first.host(), key_value.first.port()); + for (const AlternativeServiceInfo& alternative_service_info : + key_value.second) { + if (alternative_service_info.alternative_service.protocol == kProtoQUIC) { + quic_supported_servers_at_startup_.insert(host_port_pair); + break; + } + } + } + + if (http_server_properties_->max_server_configs_stored_in_properties() == 0) + return; + // Create a temporary QuicServerInfo object to deserialize and to populate the + // in-memory crypto server config cache in the MRU order. + std::unique_ptr<QuicServerInfo> server_info; + CompletionCallback callback; + // Get the list of servers to be deserialized first because WaitForDataReady + // touches quic_server_info_map. + const QuicServerInfoMap& quic_server_info_map = + http_server_properties_->quic_server_info_map(); + std::vector<QuicServerId> server_list; + for (const auto& key_value : quic_server_info_map) + server_list.push_back(key_value.first); + for (auto it = server_list.rbegin(); it != server_list.rend(); ++it) { + const QuicServerId& server_id = *it; + server_info = quic_server_info_factory_->GetForServer(server_id); + if (server_info->WaitForDataReady(callback) == OK) { + DVLOG(1) << "Initialized server config for: " << server_id.ToString(); + InitializeCachedStateInCryptoConfig(server_id, server_info, nullptr); + } + } +} + void QuicStreamFactory::ProcessGoingAwaySession( QuicChromiumClientSession* session, const QuicServerId& server_id,
diff --git a/net/quic/chromium/quic_stream_factory.h b/net/quic/chromium/quic_stream_factory.h index 661cfeb..f0addeac 100644 --- a/net/quic/chromium/quic_stream_factory.h +++ b/net/quic/chromium/quic_stream_factory.h
@@ -66,6 +66,7 @@ class QuicCryptoClientStreamFactory; class QuicRandom; class QuicServerInfo; +class QuicServerInfoFactory; class QuicStreamFactory; class SocketPerformanceWatcherFactory; class TransportSecurityState; @@ -207,8 +208,11 @@ size_t max_packet_length, const std::string& user_agent_id, const QuicVersionVector& supported_versions, + float load_server_info_timeout_srtt_multiplier, + bool enable_connection_racing, bool enable_non_blocking_io, - bool store_server_configs_in_properties, + bool disable_disk_cache, + int max_server_configs_stored_in_properties, bool close_sessions_on_ip_change, bool mark_quic_broken_when_network_blackholes, int idle_connection_timeout_seconds, @@ -364,10 +368,26 @@ QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); } + bool has_quic_server_info_factory() const { + return quic_server_info_factory_.get() != nullptr; + } + + QuicServerInfoFactory* quic_server_info_factory() const { + return quic_server_info_factory_.get(); + } + + void set_quic_server_info_factory( + QuicServerInfoFactory* quic_server_info_factory); + void set_server_push_delegate(ServerPushDelegate* push_delegate) { push_delegate_ = push_delegate; } + bool enable_connection_racing() const { return enable_connection_racing_; } + void set_enable_connection_racing(bool enable_connection_racing) { + enable_connection_racing_ = enable_connection_racing; + } + bool migrate_sessions_on_network_change() const { return migrate_sessions_on_network_change_; } @@ -400,6 +420,12 @@ typedef std::map<QuicServerId, std::unique_ptr<CertVerifierJob>> CertVerifierJobMap; + // Creates a job which doesn't wait for server config to be loaded from the + // disk cache. This job is started via a PostTask. + void CreateAuxilaryJob(const QuicSessionKey& key, + int cert_verify_flags, + const NetLogWithSource& net_log); + // Returns a newly created QuicHttpStream owned by the caller. std::unique_ptr<QuicHttpStream> CreateFromSession( QuicChromiumClientSession* session); @@ -412,6 +438,7 @@ bool HasActiveCertVerifierJob(const QuicServerId& server_id) const; int CreateSession(const QuicSessionKey& key, int cert_verify_flags, + std::unique_ptr<QuicServerInfo> quic_server_info, bool require_confirmation, const AddressList& address_list, base::TimeTicks dns_resolution_start_time, @@ -457,6 +484,11 @@ const std::unique_ptr<QuicServerInfo>& server_info, QuicConnectionId* connection_id); + // Initialize |quic_supported_servers_at_startup_| with the list of servers + // that supported QUIC at start up and also initialize in-memory cache of + // QuicServerInfo objects from HttpServerProperties. + void MaybeInitialize(); + void ProcessGoingAwaySession(QuicChromiumClientSession* session, const QuicServerId& server_id, bool was_session_active); @@ -481,6 +513,7 @@ ProxyDelegate* proxy_delegate_; TransportSecurityState* transport_security_state_; CTVerifier* cert_transparency_verifier_; + std::unique_ptr<QuicServerInfoFactory> quic_server_info_factory_; QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory_; QuicRandom* random_generator_; // Unowned. QuicClock* clock_; // Unowned. @@ -525,16 +558,27 @@ const QuicVersionVector supported_versions_; + // Specifies the ratio between time to load QUIC server information from disk + // cache to 'smoothed RTT'. This ratio is used to calculate the timeout in + // milliseconds to wait for loading of QUIC server information. If we don't + // want to timeout, set |load_server_info_timeout_srtt_multiplier_| to 0. + float load_server_info_timeout_srtt_multiplier_; + + // Set if we want to race connections - one connection that sends + // INCHOATE_HELLO and another connection that sends CHLO after loading server + // config from the disk cache. + bool enable_connection_racing_; + // Set if experimental non-blocking IO should be used on windows sockets. bool enable_non_blocking_io_; + // Set if we do not want to load server config from the disk cache. + bool disable_disk_cache_; + // True if QUIC should be marked as broken when a connection blackholes after // the handshake is confirmed. bool mark_quic_broken_when_network_blackholes_; - // Set if QUIC server configs should be stored in HttpServerProperties. - bool store_server_configs_in_properties_; - // PING timeout for connections. QuicTime::Delta ping_timeout_; QuicTime::Delta reduced_ping_timeout_; @@ -575,6 +619,8 @@ // Local address of socket that was created in CreateSession. IPEndPoint local_address_; bool check_persisted_supports_quic_; + bool has_initialized_data_; + std::set<HostPortPair> quic_supported_servers_at_startup_; NetworkConnection network_connection_;
diff --git a/net/quic/chromium/quic_stream_factory_peer.cc b/net/quic/chromium/quic_stream_factory_peer.cc index d5f4b5c..ff05043 100644 --- a/net/quic/chromium/quic_stream_factory_peer.cc +++ b/net/quic/chromium/quic_stream_factory_peer.cc
@@ -119,6 +119,20 @@ return it->second.size(); } +void QuicStreamFactoryPeer::MaybeInitialize(QuicStreamFactory* factory) { + factory->MaybeInitialize(); +} + +bool QuicStreamFactoryPeer::HasInitializedData(QuicStreamFactory* factory) { + return factory->has_initialized_data_; +} + +bool QuicStreamFactoryPeer::SupportsQuicAtStartUp(QuicStreamFactory* factory, + HostPortPair host_port_pair) { + return base::ContainsKey(factory->quic_supported_servers_at_startup_, + host_port_pair); +} + bool QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty( QuicStreamFactory* factory, const QuicServerId& quic_server_id) {
diff --git a/net/quic/chromium/quic_stream_factory_peer.h b/net/quic/chromium/quic_stream_factory_peer.h index c2d3be9e..d9b8d1d 100644 --- a/net/quic/chromium/quic_stream_factory_peer.h +++ b/net/quic/chromium/quic_stream_factory_peer.h
@@ -79,6 +79,13 @@ static size_t GetNumberOfActiveJobs(QuicStreamFactory* factory, const QuicServerId& server_id); + static void MaybeInitialize(QuicStreamFactory* factory); + + static bool HasInitializedData(QuicStreamFactory* factory); + + static bool SupportsQuicAtStartUp(QuicStreamFactory* factory, + HostPortPair host_port_pair); + static bool CryptoConfigCacheIsEmpty(QuicStreamFactory* factory, const QuicServerId& quic_server_id);
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index a426a10..f3acc60 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -101,18 +101,23 @@ // and enable_connection_racting. struct TestParams { friend std::ostream& operator<<(std::ostream& os, const TestParams& p) { - os << "{ version: " << QuicVersionToString(p.version) << " }"; + os << "{ version: " << QuicVersionToString(p.version) + << ", enable_connection_racing: " + << (p.enable_connection_racing ? "true" : "false") << " }"; return os; } QuicVersion version; + bool enable_connection_racing; }; std::vector<TestParams> GetTestParams() { std::vector<TestParams> params; QuicVersionVector all_supported_versions = AllSupportedVersions(); - for (const auto& version : all_supported_versions) - params.push_back(TestParams{version}); + for (const QuicVersion version : all_supported_versions) { + params.push_back(TestParams{version, false}); + params.push_back(TestParams{version, true}); + } return params; } @@ -122,6 +127,8 @@ friend std::ostream& operator<<(std::ostream& os, const PoolingTestParams& p) { os << "{ version: " << QuicVersionToString(p.version) + << ", enable_connection_racing: " + << (p.enable_connection_racing ? "true" : "false") << ", destination_type: "; switch (p.destination_type) { case SAME_AS_FIRST: @@ -139,6 +146,7 @@ } QuicVersion version; + bool enable_connection_racing; DestinationType destination_type; }; @@ -146,9 +154,12 @@ std::vector<PoolingTestParams> params; QuicVersionVector all_supported_versions = AllSupportedVersions(); for (const QuicVersion version : all_supported_versions) { - params.push_back(PoolingTestParams{version, SAME_AS_FIRST}); - params.push_back(PoolingTestParams{version, SAME_AS_SECOND}); - params.push_back(PoolingTestParams{version, DIFFERENT}); + params.push_back(PoolingTestParams{version, false, SAME_AS_FIRST}); + params.push_back(PoolingTestParams{version, false, SAME_AS_SECOND}); + params.push_back(PoolingTestParams{version, false, DIFFERENT}); + params.push_back(PoolingTestParams{version, true, SAME_AS_FIRST}); + params.push_back(PoolingTestParams{version, true, SAME_AS_SECOND}); + params.push_back(PoolingTestParams{version, true, DIFFERENT}); } return params; } @@ -162,9 +173,50 @@ } }; +class MockQuicServerInfo : public QuicServerInfo { + public: + explicit MockQuicServerInfo(const QuicServerId& server_id) + : QuicServerInfo(server_id) {} + ~MockQuicServerInfo() override {} + + void Start() override {} + + int WaitForDataReady(const CompletionCallback& callback) override { + return ERR_IO_PENDING; + } + + void ResetWaitForDataReadyCallback() override {} + + void CancelWaitForDataReadyCallback() override {} + + bool IsDataReady() override { return false; } + + bool IsReadyToPersist() override { return false; } + + void Persist() override {} + + void OnExternalCacheHit() override {} + + size_t EstimateMemoryUsage() const override { + NOTREACHED(); + return 0; + } +}; + +class MockQuicServerInfoFactory : public QuicServerInfoFactory { + public: + MockQuicServerInfoFactory() {} + ~MockQuicServerInfoFactory() override {} + + std::unique_ptr<QuicServerInfo> GetForServer( + const QuicServerId& server_id) override { + return base::MakeUnique<MockQuicServerInfo>(server_id); + } +}; + class QuicStreamFactoryTestBase { protected: - explicit QuicStreamFactoryTestBase(QuicVersion version) + QuicStreamFactoryTestBase(QuicVersion version, bool enable_connection_racing) : ssl_config_service_(new MockSSLConfigService), random_generator_(0), runner_(new TestTaskRunner(&clock_)), @@ -191,7 +243,10 @@ url3_(kServer3Url), url4_(kServer4Url), privacy_mode_(PRIVACY_MODE_DISABLED), + load_server_info_timeout_srtt_multiplier_(0.0f), + enable_connection_racing_(enable_connection_racing), enable_non_blocking_io_(true), + disable_disk_cache_(false), close_sessions_on_ip_change_(false), idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds), reduced_ping_timeout_seconds_(kPingTimeoutSecs), @@ -216,7 +271,9 @@ /*SocketPerformanceWatcherFactory*/ nullptr, &crypto_client_stream_factory_, &random_generator_, &clock_, kDefaultMaxPacketSize, string(), SupportedVersions(version_), - enable_non_blocking_io_, store_server_configs_in_properties_, + load_server_info_timeout_srtt_multiplier_, enable_connection_racing_, + enable_non_blocking_io_, disable_disk_cache_, + /*max_server_configs_stored_in_properties*/ 0, close_sessions_on_ip_change_, /*mark_quic_broken_when_network_blackholes*/ false, idle_connection_timeout_seconds_, reduced_ping_timeout_seconds_, @@ -226,6 +283,9 @@ /*do_not_fragment*/ true, estimate_initial_rtt_, QuicTagVector(), /*enable_token_binding*/ false)); factory_->set_require_confirmation(false); + EXPECT_FALSE(factory_->has_quic_server_info_factory()); + factory_->set_quic_server_info_factory(new MockQuicServerInfoFactory()); + EXPECT_TRUE(factory_->has_quic_server_info_factory()); } void InitializeConnectionMigrationTest( @@ -481,14 +541,10 @@ // a non proxy server that support alternative services is added to the // HttpServerProperties map. void VerifyInitialization(bool proxy_delegate_provides_quic_supported_proxy) { - store_server_configs_in_properties_ = true; idle_connection_timeout_seconds_ = 500; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - crypto_client_stream_factory_.set_handshake_mode( - MockCryptoClientStream::ZERO_RTT); const QuicConfig* config = QuicStreamFactoryPeer::GetConfig(factory_.get()); EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds()); @@ -528,11 +584,14 @@ http_server_properties_.SetMaxServerConfigsStoredInProperties( kMaxQuicServersToPersist); - QuicServerId quic_server_id(kDefaultServerHostName, 443, + QuicServerId quic_server_id(kDefaultServerHostName, 80, PRIVACY_MODE_DISABLED); - std::unique_ptr<QuicServerInfo> quic_server_info = - base::MakeUnique<PropertiesBasedQuicServerInfo>( - quic_server_id, &http_server_properties_); + QuicServerInfoFactory* quic_server_info_factory = + new PropertiesBasedQuicServerInfoFactory(&http_server_properties_); + factory_->set_quic_server_info_factory(quic_server_info_factory); + + std::unique_ptr<QuicServerInfo> quic_server_info( + quic_server_info_factory->GetForServer(quic_server_id)); // Update quic_server_info's server_config and persist it. QuicServerInfo::State* state = quic_server_info->mutable_state(); @@ -568,10 +627,10 @@ quic_server_info->Persist(); - QuicServerId quic_server_id2(kServer2HostName, 443, PRIVACY_MODE_DISABLED); - std::unique_ptr<QuicServerInfo> quic_server_info2 = - base::MakeUnique<PropertiesBasedQuicServerInfo>( - quic_server_id2, &http_server_properties_); + QuicServerId quic_server_id2(kServer2HostName, 80, PRIVACY_MODE_DISABLED); + std::unique_ptr<QuicServerInfo> quic_server_info2( + quic_server_info_factory->GetForServer(quic_server_id2)); + // Update quic_server_info2's server_config and persist it. QuicServerInfo::State* state2 = quic_server_info2->mutable_state(); @@ -608,6 +667,9 @@ quic_server_info2->Persist(); + QuicStreamFactoryPeer::MaybeInitialize(factory_.get()); + EXPECT_TRUE(QuicStreamFactoryPeer::HasInitializedData(factory_.get())); + // Verify the MRU order is maintained. const QuicServerInfoMap& quic_server_info_map = http_server_properties_.quic_server_info_map(); @@ -618,21 +680,8 @@ ++quic_server_info_map_it; EXPECT_EQ(quic_server_info_map_it->first, quic_server_id); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); - - // Create a session and verify that the cached state is loaded. - MockQuicData socket_data; - socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddSocketDataToFactory(&socket_factory_); - - QuicStreamRequest request(factory_.get(), &http_server_properties_); - EXPECT_EQ(ERR_IO_PENDING, - request.Request(quic_server_id.host_port_pair(), privacy_mode_, - /*cert_verify_flags=*/0, url_, "GET", net_log_, - callback_.callback())); - EXPECT_THAT(callback_.WaitForResult(), IsOk()); - + EXPECT_TRUE(QuicStreamFactoryPeer::SupportsQuicAtStartUp(factory_.get(), + host_port_pair_)); EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty( factory_.get(), quic_server_id)); QuicCryptoClientConfig* crypto_config = @@ -649,24 +698,8 @@ ASSERT_EQ(1U, cached->certs().size()); EXPECT_EQ(test_cert, cached->certs()[0]); - EXPECT_TRUE(socket_data.AllWriteDataConsumed()); - - // Create a session and verify that the cached state is loaded. - MockQuicData socket_data2; - socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddSocketDataToFactory(&socket_factory_); - - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.2", ""); - - QuicStreamRequest request2(factory_.get(), &http_server_properties_); - EXPECT_EQ(ERR_IO_PENDING, - request2.Request(quic_server_id2.host_port_pair(), privacy_mode_, - /*cert_verify_flags=*/0, - GURL("https://mail.example.org/"), "GET", - net_log_, callback_.callback())); - EXPECT_THAT(callback_.WaitForResult(), IsOk()); - + EXPECT_TRUE(QuicStreamFactoryPeer::SupportsQuicAtStartUp(factory_.get(), + host_port_pair2)); EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty( factory_.get(), quic_server_id2)); QuicCryptoClientConfig::CachedState* cached2 = @@ -736,8 +769,10 @@ TestCompletionCallback callback_; // Variables to configure QuicStreamFactory. + double load_server_info_timeout_srtt_multiplier_; + bool enable_connection_racing_; bool enable_non_blocking_io_; - bool store_server_configs_in_properties_; + bool disable_disk_cache_; bool close_sessions_on_ip_change_; int idle_connection_timeout_seconds_; int reduced_ping_timeout_seconds_; @@ -753,7 +788,9 @@ class QuicStreamFactoryTest : public QuicStreamFactoryTestBase, public ::testing::TestWithParam<TestParams> { protected: - QuicStreamFactoryTest() : QuicStreamFactoryTestBase(GetParam().version) {} + QuicStreamFactoryTest() + : QuicStreamFactoryTestBase(GetParam().version, + GetParam().enable_connection_racing) {} }; INSTANTIATE_TEST_CASE_P(Version, @@ -4380,7 +4417,62 @@ } } +TEST_P(QuicStreamFactoryTest, RacingConnections) { + disable_disk_cache_ = false; + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + if (!enable_connection_racing_) + return; + + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get()); + + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data.AddSocketDataToFactory(&socket_factory_); + + MockQuicData socket_data2; + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data2.AddSocketDataToFactory(&socket_factory_); + + const AlternativeService alternative_service1( + kProtoQUIC, host_port_pair_.host(), host_port_pair_.port()); + AlternativeServiceInfoVector alternative_service_info_vector; + base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); + alternative_service_info_vector.push_back( + AlternativeServiceInfo(alternative_service1, expiration)); + + http_server_properties_.SetAlternativeServices( + url::SchemeHostPort(url_), alternative_service_info_vector); + + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_.set_synchronous_mode(true); + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); + + QuicStreamRequest request(factory_.get(), &http_server_properties_); + QuicServerId server_id(host_port_pair_, privacy_mode_); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + EXPECT_EQ(2u, QuicStreamFactoryPeer::GetNumberOfActiveJobs(factory_.get(), + server_id)); + + runner_->RunNextTask(); + + std::unique_ptr<QuicHttpStream> stream = request.CreateStream(); + EXPECT_TRUE(stream.get()); + EXPECT_TRUE(socket_data.AllReadDataConsumed()); + EXPECT_TRUE(socket_data.AllWriteDataConsumed()); + EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumberOfActiveJobs(factory_.get(), + server_id)); +} + TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) { + disable_disk_cache_ = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -4414,6 +4506,7 @@ TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) { reduced_ping_timeout_seconds_ = 10; + disable_disk_cache_ = true; Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -4505,6 +4598,50 @@ EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); } +TEST_P(QuicStreamFactoryTest, DelayTcpRace) { + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data.AddWrite( + ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, + kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddSocketDataToFactory(&socket_factory_); + + ServerNetworkStats stats1; + stats1.srtt = base::TimeDelta::FromMicroseconds(10); + http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_), + stats1); + + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::COLD_START); + host_resolver_.set_synchronous_mode(true); + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); + + QuicStreamRequest request(factory_.get(), &http_server_properties_); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "POST", net_log_, + callback_.callback())); + + // Verify delay is one RTT and that server supports QUIC. + EXPECT_EQ(base::TimeDelta::FromMicroseconds(15), + request.GetTimeDelayForWaitingJob()); + + // Confirm the handshake and verify that the stream is created. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + QuicSession::HANDSHAKE_CONFIRMED); + + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<QuicHttpStream> stream = request.CreateStream(); + EXPECT_TRUE(stream.get()); + EXPECT_TRUE(socket_data.AllReadDataConsumed()); + EXPECT_TRUE(socket_data.AllWriteDataConsumed()); +} + // Verifies that the QUIC stream factory is initialized correctly. TEST_P(QuicStreamFactoryTest, MaybeInitialize) { VerifyInitialization(false); @@ -4856,7 +4993,8 @@ public ::testing::TestWithParam<PoolingTestParams> { protected: QuicStreamFactoryWithDestinationTest() - : QuicStreamFactoryTestBase(GetParam().version), + : QuicStreamFactoryTestBase(GetParam().version, + GetParam().enable_connection_racing), destination_type_(GetParam().destination_type), hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
diff --git a/net/test/scoped_disable_exit_on_dfatal.cc b/net/test/scoped_disable_exit_on_dfatal.cc index f909126..14821db 100644 --- a/net/test/scoped_disable_exit_on_dfatal.cc +++ b/net/test/scoped_disable_exit_on_dfatal.cc
@@ -4,28 +4,24 @@ #include "net/test/scoped_disable_exit_on_dfatal.h" +#include "base/bind.h" #include "base/logging.h" +#include "base/strings/string_piece.h" namespace net { namespace test { -// static -ScopedDisableExitOnDFatal* ScopedDisableExitOnDFatal::g_instance_ = NULL; +ScopedDisableExitOnDFatal::ScopedDisableExitOnDFatal() + : assert_handler_(base::Bind(LogAssertHandler)) {} -ScopedDisableExitOnDFatal::ScopedDisableExitOnDFatal() { - CHECK(!g_instance_); - g_instance_ = this; - logging::SetLogAssertHandler(LogAssertHandler); -} - -ScopedDisableExitOnDFatal::~ScopedDisableExitOnDFatal() { - CHECK_EQ(g_instance_, this); - logging::SetLogAssertHandler(NULL); - g_instance_ = NULL; -} +ScopedDisableExitOnDFatal::~ScopedDisableExitOnDFatal() {} // static -void ScopedDisableExitOnDFatal::LogAssertHandler(const std::string& str) { +void ScopedDisableExitOnDFatal::LogAssertHandler( + const char* file, + int line, + const base::StringPiece message, + const base::StringPiece stack_trace) { // Simply swallow the assert. }
diff --git a/net/test/scoped_disable_exit_on_dfatal.h b/net/test/scoped_disable_exit_on_dfatal.h index 33f06e3..5bb7643 100644 --- a/net/test/scoped_disable_exit_on_dfatal.h +++ b/net/test/scoped_disable_exit_on_dfatal.h
@@ -23,12 +23,14 @@ ~ScopedDisableExitOnDFatal(); private: - // Currently active instance. - static ScopedDisableExitOnDFatal* g_instance_; - // Static function which is set as the logging assert handler. // Called when there is a check failure. - static void LogAssertHandler(const std::string& msg); + static void LogAssertHandler(const char* file, + int line, + const base::StringPiece message, + const base::StringPiece stack_trace); + + logging::ScopedLogAssertHandler assert_handler_; DISALLOW_COPY_AND_ASSIGN(ScopedDisableExitOnDFatal); };
diff --git a/net/tools/stress_cache/stress_cache.cc b/net/tools/stress_cache/stress_cache.cc index fefcd72f..3d49fda 100644 --- a/net/tools/stress_cache/stress_cache.cc +++ b/net/tools/stress_cache/stress_cache.cc
@@ -379,7 +379,10 @@ return true; } -void CrashHandler(const std::string& str) { +void CrashHandler(const char* file, + int line, + const base::StringPiece str, + const base::StringPiece stack_trace) { g_crashing = true; base::debug::BreakDebugger(); } @@ -414,7 +417,8 @@ if (argc < 2) return MasterCode(); - logging::SetLogAssertHandler(CrashHandler); + logging::ScopedLogAssertHandler scoped_assert_handler( + base::Bind(CrashHandler)); logging::SetLogMessageHandler(MessageHandler); #if defined(OS_WIN)
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 7282a0e5..1eb9711 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -7868,6 +7868,127 @@ EXPECT_EQ(LOW, job_priority); } +TEST_F(URLRequestTest, QuicServerInfoFactoryTest) { + HttpNetworkSession::Params params; + + MockClientSocketFactory socket_factory; + MockCryptoClientStreamFactory crypto_client_stream_factory; + MockHostResolver host_resolver; + MockCertVerifier cert_verifier; + CTPolicyEnforcer ct_policy_enforcer; + TransportSecurityState transport_security_state; + std::unique_ptr<CTVerifier> cert_transparency_verifier( + new MultiLogCTVerifier()); + std::unique_ptr<ProxyService> proxy_service = ProxyService::CreateDirect(); + scoped_refptr<SSLConfigServiceDefaults> ssl_config_service( + new SSLConfigServiceDefaults); + HttpServerPropertiesImpl http_server_properties; + // Set up the quic stream factory. + params.enable_quic = true; + params.client_socket_factory = &socket_factory; + params.quic_crypto_client_stream_factory = &crypto_client_stream_factory; + params.host_resolver = &host_resolver; + params.cert_verifier = &cert_verifier; + params.ct_policy_enforcer = &ct_policy_enforcer; + params.transport_security_state = &transport_security_state; + params.cert_transparency_verifier = cert_transparency_verifier.get(); + + params.proxy_service = proxy_service.get(); + params.ssl_config_service = ssl_config_service.get(); + params.http_server_properties = &http_server_properties; + + HttpNetworkSession session(params); + DCHECK(session.quic_stream_factory()); + + std::unique_ptr<HttpNetworkLayer> network_layer1( + new HttpNetworkLayer(&session)); + + HttpCache main_cache(std::move(network_layer1), + HttpCache::DefaultBackend::InMemory(0), + true /* is_main_cache */); + + EXPECT_TRUE(session.quic_stream_factory()->has_quic_server_info_factory()); + + default_context_.set_http_transaction_factory(&main_cache); + + QuicServerInfoFactory* quic_server_info_factory = + session.quic_stream_factory()->quic_server_info_factory(); + DCHECK(quic_server_info_factory); + + QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); + const string server_config_a = "server_config_a"; + const string source_address_token_a = "source_address_token_a"; + const string cert_sct_a = "cert_sct_a"; + const string chlo_hash_a = "chlo_hash_a"; + const string server_config_sig_a = "server_config_sig_a"; + const string cert_a = "cert_a"; + const string cert_b = "cert_b"; + + { + // Store a QuicServerInfo to the quic server info factory. + TestCompletionCallback cb; + std::unique_ptr<QuicServerInfo> quic_server_info = + quic_server_info_factory->GetForServer(server_id); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(cb.callback()); + EXPECT_THAT(cb.GetResult(rv), IsOk()); + + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(state->certs.empty()); + + state->server_config = server_config_a; + state->source_address_token = source_address_token_a; + state->cert_sct = cert_sct_a; + state->chlo_hash = chlo_hash_a; + state->server_config_sig = server_config_sig_a; + state->certs.push_back(cert_a); + quic_server_info->Persist(); + base::RunLoop().RunUntilIdle(); + } + + // Retrieve the QuicServerInfo from the quic server info factory and verify + // the data is correct. + { + TestCompletionCallback cb; + std::unique_ptr<QuicServerInfo> quic_server_info = + quic_server_info_factory->GetForServer(server_id); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(cb.callback()); + EXPECT_THAT(cb.GetResult(rv), IsOk()); + + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(quic_server_info->IsDataReady()); + EXPECT_EQ(server_config_a, state->server_config); + EXPECT_EQ(source_address_token_a, state->source_address_token); + EXPECT_EQ(cert_sct_a, state->cert_sct); + EXPECT_EQ(chlo_hash_a, state->chlo_hash); + EXPECT_EQ(server_config_sig_a, state->server_config_sig); + EXPECT_EQ(1U, state->certs.size()); + EXPECT_EQ(cert_a, state->certs[0]); + + // Update the data. + state->certs.push_back(cert_b); + quic_server_info->Persist(); + base::RunLoop().RunUntilIdle(); + } + + { + // Verify data has been successfully updated. + TestCompletionCallback cb; + std::unique_ptr<QuicServerInfo> quic_server_info = + quic_server_info_factory->GetForServer(server_id); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(cb.callback()); + EXPECT_THAT(cb.GetResult(rv), IsOk()); + + QuicServerInfo::State* state = quic_server_info->mutable_state(); + EXPECT_TRUE(quic_server_info->IsDataReady()); + EXPECT_EQ(2U, state->certs.size()); + EXPECT_EQ(cert_a, state->certs[0]); + EXPECT_EQ(cert_b, state->certs[1]); + } +} + // Check that creating a network request while entering/exiting suspend mode // fails as it should. This is the only case where an HttpTransactionFactory // does not return an HttpTransaction.
diff --git a/sandbox/linux/tests/main.cc b/sandbox/linux/tests/main.cc index caeddee..223a320 100644 --- a/sandbox/linux/tests/main.cc +++ b/sandbox/linux/tests/main.cc
@@ -4,6 +4,7 @@ #include "base/at_exit.h" #include "base/base_switches.h" +#include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -37,7 +38,10 @@ } // namespace sandbox #if !defined(SANDBOX_USES_BASE_TEST_SUITE) -void UnitTestAssertHandler(const std::string& str) { +void UnitTestAssertHandler(const char* file, + int line, + const base::StringPiece message, + const base::StringPiece stack_trace) { _exit(1); } #endif @@ -64,7 +68,8 @@ // Death tests rely on LOG(FATAL) triggering an exit (the default behavior is // SIGABRT). The normal test launcher does this at initialization, but since // we still do not use this on Android, we must install the handler ourselves. - logging::SetLogAssertHandler(UnitTestAssertHandler); + logging::ScopedLogAssertHandler scoped_assert_handler( + base::Bind(UnitTestAssertHandler)); #endif // Always go through re-execution for death tests. // This makes gtest only marginally slower for us and has the
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn index 68537a8..b4658f9 100644 --- a/storage/browser/BUILD.gn +++ b/storage/browser/BUILD.gn
@@ -236,16 +236,18 @@ "blob/blob_transport_request_builder_unittest.cc", "blob/blob_url_request_job_unittest.cc", "database/database_quota_client_unittest.cc", + "database/database_tracker_unittest.cc", "database/database_util_unittest.cc", "database/databases_table_unittest.cc", - "fileapi/copy_or_move_operation_delegate_unittest.cc", "fileapi/copy_or_move_file_validator_unittest.cc", + "fileapi/copy_or_move_operation_delegate_unittest.cc", "fileapi/dragged_file_util_unittest.cc", "fileapi/external_mount_points_unittest.cc", "fileapi/file_system_context_unittest.cc", "fileapi/file_system_dir_url_request_job_unittest.cc", "fileapi/file_system_file_stream_reader_unittest.cc", "fileapi/file_system_operation_impl_unittest.cc", + "fileapi/file_system_operation_impl_write_unittest.cc", "fileapi/file_system_quota_client_unittest.cc", "fileapi/file_system_url_request_job_unittest.cc", "fileapi/file_system_url_unittest.cc", @@ -257,13 +259,15 @@ "fileapi/local_file_util_unittest.cc", "fileapi/native_file_util_unittest.cc", "fileapi/obfuscated_file_util_unittest.cc", - "fileapi/recursive_operation_delegate_unittest.cc", "fileapi/plugin_private_file_system_backend_unittest.cc", "fileapi/quota/quota_backend_impl_unittest.cc", "fileapi/quota/quota_reservation_manager_unittest.cc", + "fileapi/recursive_operation_delegate_unittest.cc", + "fileapi/sandbox_directory_database_unittest.cc", "fileapi/sandbox_file_system_backend_delegate_unittest.cc", "fileapi/sandbox_file_system_backend_unittest.cc", "fileapi/sandbox_isolated_origin_database_unittest.cc", + "fileapi/sandbox_origin_database_unittest.cc", "fileapi/sandbox_prioritized_origin_database_unittest.cc", "fileapi/timed_task_helper_unittest.cc", "fileapi/transient_file_util_unittest.cc", @@ -295,6 +299,8 @@ "test/async_file_test_helper.h", "test/fileapi_test_file_set.cc", "test/fileapi_test_file_set.h", + "test/mock_blob_url_request_context.cc", + "test/mock_blob_url_request_context.h", "test/mock_file_change_observer.cc", "test/mock_file_change_observer.h", "test/mock_file_update_observer.cc", @@ -307,6 +313,8 @@ "test/mock_special_storage_policy.h", "test/mock_storage_client.cc", "test/mock_storage_client.h", + "test/sandbox_database_test_helper.cc", + "test/sandbox_database_test_helper.h", "test/sandbox_file_system_test_helper.cc", "test/sandbox_file_system_test_helper.h", "test/test_file_system_backend.cc", @@ -322,5 +330,6 @@ "//base/test:test_support", "//net:test_support", "//testing/gtest", + "//third_party/leveldatabase", ] }
diff --git a/content/browser/database_tracker_unittest.cc b/storage/browser/database/database_tracker_unittest.cc similarity index 86% rename from content/browser/database_tracker_unittest.cc rename to storage/browser/database/database_tracker_unittest.cc index 0ff0208b..53e53f3d 100644 --- a/content/browser/database_tracker_unittest.cc +++ b/storage/browser/database/database_tracker_unittest.cc
@@ -39,13 +39,11 @@ TestObserver() : new_notification_received_(false), observe_size_changes_(true), - observe_scheduled_deletions_(true) { - } + observe_scheduled_deletions_(true) {} TestObserver(bool observe_size_changes, bool observe_scheduled_deletions) : new_notification_received_(false), observe_size_changes_(observe_size_changes), - observe_scheduled_deletions_(observe_scheduled_deletions) { - } + observe_scheduled_deletions_(observe_scheduled_deletions) {} ~TestObserver() override {} void OnDatabaseSizeChanged(const std::string& origin_identifier, @@ -72,9 +70,7 @@ new_notification_received_ = false; return temp_new_notification_received; } - std::string GetNotificationOriginIdentifier() { - return origin_identifier_; - } + std::string GetNotificationOriginIdentifier() { return origin_identifier_; } base::string16 GetNotificationDatabaseName() { return database_name_; } int64_t GetNotificationDatabaseSize() { return database_size_; } @@ -94,18 +90,14 @@ EXPECT_TRUE(observer->DidReceiveNewNotification()); EXPECT_EQ(expected_origin_identifier, observer->GetNotificationOriginIdentifier()); - EXPECT_EQ(expected_database_name, - observer->GetNotificationDatabaseName()); - EXPECT_EQ(expected_database_size, - observer->GetNotificationDatabaseSize()); + EXPECT_EQ(expected_database_name, observer->GetNotificationDatabaseName()); + EXPECT_EQ(expected_database_size, observer->GetNotificationDatabaseSize()); } class TestQuotaManagerProxy : public storage::QuotaManagerProxy { public: TestQuotaManagerProxy() - : QuotaManagerProxy(NULL, NULL), - registered_client_(NULL) { - } + : QuotaManagerProxy(NULL, NULL), registered_client_(NULL) {} void RegisterClient(storage::QuotaClient* client) override { EXPECT_FALSE(registered_client_); @@ -149,9 +141,7 @@ } } - bool WasAccessNotified(const GURL& origin) { - return accesses_[origin] != 0; - } + bool WasAccessNotified(const GURL& origin) { return accesses_[origin] != 0; } bool WasModificationNotified(const GURL& origin, int64_t amount) { return modifications_[origin].first != 0 && @@ -216,12 +206,9 @@ const base::string16 kDB3 = ASCIIToUTF16("db3"); const base::string16 kDescription = ASCIIToUTF16("database_description"); - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, - &database_size); - tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, - &database_size); - tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); + tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, &database_size); + tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, 0, &database_size); EXPECT_TRUE(base::CreateDirectory( tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe( @@ -229,12 +216,12 @@ EXPECT_TRUE(base::CreateDirectory( tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe( tracker->GetOriginDirectory(kOrigin2))))); - EXPECT_EQ(1, base::WriteFile( - tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); - EXPECT_EQ(2, base::WriteFile( - tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2)); - EXPECT_EQ(3, base::WriteFile( - tracker->GetFullDBFilePath(kOrigin2, kDB3), "aaa", 3)); + EXPECT_EQ( + 1, base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); + EXPECT_EQ(2, base::WriteFile(tracker->GetFullDBFilePath(kOrigin2, kDB2), + "aa", 2)); + EXPECT_EQ(3, base::WriteFile(tracker->GetFullDBFilePath(kOrigin2, kDB3), + "aaa", 3)); tracker->DatabaseModified(kOrigin1, kDB1); tracker->DatabaseModified(kOrigin2, kDB2); tracker->DatabaseModified(kOrigin2, kDB3); @@ -252,26 +239,25 @@ tracker->DatabaseClosed(kOrigin1, kDB1); result = callback.GetResult(result); EXPECT_EQ(net::OK, result); - EXPECT_FALSE(base::PathExists( - tracker->DatabaseDirectory().AppendASCII(kOrigin1))); + EXPECT_FALSE( + base::PathExists(tracker->DatabaseDirectory().AppendASCII(kOrigin1))); // Recreate db1. - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); EXPECT_TRUE(base::CreateDirectory( tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe( tracker->GetOriginDirectory(kOrigin1))))); - EXPECT_EQ(1, base::WriteFile( - tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); + EXPECT_EQ( + 1, base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); tracker->DatabaseModified(kOrigin1, kDB1); // Setup file modification times. db1 and db2 are modified now, db3 three // days ago. base::Time now = base::Time::Now(); - EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), - now, now)); - EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB2), - now, now)); + EXPECT_TRUE( + base::TouchFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), now, now)); + EXPECT_TRUE( + base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB2), now, now)); base::Time three_days_ago = now - base::TimeDelta::FromDays(3); EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB3), three_days_ago, three_days_ago)); @@ -279,8 +265,7 @@ // Delete databases modified since yesterday. db2 is whitelisted. base::Time yesterday = base::Time::Now(); yesterday -= base::TimeDelta::FromDays(1); - result = tracker->DeleteDataModifiedSince( - yesterday, callback.callback()); + result = tracker->DeleteDataModifiedSince(yesterday, callback.callback()); EXPECT_EQ(net::ERR_IO_PENDING, result); ASSERT_FALSE(callback.have_result()); EXPECT_TRUE(observer.DidReceiveNewNotification()); @@ -288,12 +273,10 @@ tracker->DatabaseClosed(kOrigin2, kDB2); result = callback.GetResult(result); EXPECT_EQ(net::OK, result); - EXPECT_FALSE(base::PathExists( - tracker->DatabaseDirectory().AppendASCII(kOrigin1))); - EXPECT_TRUE( - base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); - EXPECT_TRUE( - base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3))); + EXPECT_FALSE( + base::PathExists(tracker->DatabaseDirectory().AppendASCII(kOrigin1))); + EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); + EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3))); tracker->DatabaseClosed(kOrigin2, kDB3); tracker->RemoveObserver(&observer); @@ -335,15 +318,11 @@ EXPECT_TRUE(origin1_info); EXPECT_TRUE(origin2_info); - - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); EXPECT_EQ(0, database_size); - tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, &database_size); EXPECT_EQ(0, database_size); - tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, &database_size); EXPECT_EQ(0, database_size); // Write some data to each file and check that the listeners are @@ -354,12 +333,12 @@ EXPECT_TRUE(base::CreateDirectory( tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe( tracker->GetOriginDirectory(kOrigin2))))); - EXPECT_EQ(1, base::WriteFile( - tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); - EXPECT_EQ(2, base::WriteFile( - tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2)); - EXPECT_EQ(4, base::WriteFile( - tracker->GetFullDBFilePath(kOrigin1, kDB3), "aaaa", 4)); + EXPECT_EQ( + 1, base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); + EXPECT_EQ(2, base::WriteFile(tracker->GetFullDBFilePath(kOrigin2, kDB2), + "aa", 2)); + EXPECT_EQ(4, base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB3), + "aaaa", 4)); tracker->DatabaseModified(kOrigin1, kDB1); CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1); CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1); @@ -376,8 +355,7 @@ tracker->DatabaseClosed(kOrigin1, kDB3); // Open an existing database and check the reported size - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); EXPECT_EQ(1, database_size); tracker->DatabaseClosed(kOrigin1, kDB1); @@ -387,8 +365,7 @@ // Close the tracker database and clear all caches. // Then make sure that DatabaseOpened() still returns the correct result. tracker->CloseTrackerDatabaseAndClearCaches(); - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); EXPECT_EQ(1, database_size); tracker->DatabaseClosed(kOrigin1, kDB1); @@ -396,8 +373,7 @@ tracker->RemoveObserver(&observer1); // Trying to delete a database in use should fail - tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, &database_size); EXPECT_FALSE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); origin1_info = tracker->GetCachedOriginInfo(kOrigin1); EXPECT_TRUE(origin1_info); @@ -424,8 +400,7 @@ EXPECT_EQ(2, origins_info[1].TotalSize()); // Trying to delete an origin with databases in use should fail - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); EXPECT_FALSE(tracker->DeleteOrigin(kOrigin1, false)); origin1_info = tracker->GetCachedOriginInfo(kOrigin1); EXPECT_TRUE(origin1_info); @@ -465,8 +440,7 @@ // then delete it. Observe the tracker notifies accordingly. int64_t database_size = 0; - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); test_quota_proxy->reset(); @@ -484,8 +458,8 @@ tracker->DatabaseClosed(kOriginId, kName); EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); - EXPECT_EQ(net::OK, tracker->DeleteDatabase( - kOriginId, kName, net::CompletionCallback())); + EXPECT_EQ(net::OK, tracker->DeleteDatabase(kOriginId, kName, + net::CompletionCallback())); EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100)); test_quota_proxy->reset(); @@ -493,8 +467,7 @@ // then close it (at which time deletion will actually occur). // Observe the tracker notifies accordingly. - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); test_quota_proxy->reset(); @@ -505,9 +478,9 @@ EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100)); test_quota_proxy->reset(); - EXPECT_EQ(net::ERR_IO_PENDING, - tracker->DeleteDatabase(kOriginId, kName, - net::CompletionCallback())); + EXPECT_EQ( + net::ERR_IO_PENDING, + tracker->DeleteDatabase(kOriginId, kName, net::CompletionCallback())); EXPECT_FALSE(test_quota_proxy->WasModificationNotified(kOrigin, -100)); tracker->DatabaseClosed(kOriginId, kName); @@ -520,8 +493,7 @@ // a renderer crash. // Observe the tracker notifies accordingly. - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin)); test_quota_proxy->reset(); db_file = tracker->GetFullDBFilePath(kOriginId, kName); @@ -563,11 +535,9 @@ base::ThreadTaskRunnerHandle::Get().get())); // Open two new databases. - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); EXPECT_EQ(0, database_size); - tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, &database_size); EXPECT_EQ(0, database_size); // Write some data to each file. @@ -605,8 +575,7 @@ // and it got deleted. EXPECT_EQ(size_t(1), origins_info.size()); EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier()); - EXPECT_TRUE( - base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1))); + EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1))); EXPECT_EQ(base::FilePath(), tracker->GetFullDBFilePath(kOrigin2, kDB2)); // The origin directory of kOrigin1 remains, but the origin directory of @@ -641,11 +610,9 @@ tracker->SetForceKeepSessionState(); // Open two new databases. - tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size); EXPECT_EQ(0, database_size); - tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, &database_size); EXPECT_EQ(0, database_size); // Write some data to each file. @@ -681,10 +648,8 @@ EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); // No origins were deleted. EXPECT_EQ(size_t(2), origins_info.size()); - EXPECT_TRUE( - base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1))); - EXPECT_TRUE( - base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); + EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1))); + EXPECT_TRUE(base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); EXPECT_TRUE(base::PathExists(origin1_db_dir)); EXPECT_TRUE(base::PathExists(origin2_db_dir)); @@ -763,8 +728,7 @@ // Create a record of a database in the tracker db and create // a spoof_db_file on disk in the expected location. int64_t database_size = 0; - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, - &database_size); + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); base::FilePath spoof_db_file = tracker->GetFullDBFilePath(kOriginId, kName); EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); EXPECT_TRUE(base::CreateDirectory(spoof_db_file.DirName())); @@ -791,10 +755,9 @@ // -------------------------------------------------------- // Create another record of a database in the tracker db and create // a spoof_db_file on disk in the expected location. - tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, - &database_size); - base::FilePath spoof_db_file2 = tracker->GetFullDBFilePath(kOriginId, - kName); + tracker->DatabaseOpened(kOriginId, kName, kDescription, 0, &database_size); + base::FilePath spoof_db_file2 = + tracker->GetFullDBFilePath(kOriginId, kName); EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty()); EXPECT_NE(spoof_db_file, spoof_db_file2); EXPECT_TRUE(base::CreateDirectory(spoof_db_file2.DirName()));
diff --git a/content/browser/fileapi/file_system_operation_impl_write_unittest.cc b/storage/browser/fileapi/file_system_operation_impl_write_unittest.cc similarity index 93% rename from content/browser/fileapi/file_system_operation_impl_write_unittest.cc rename to storage/browser/fileapi/file_system_operation_impl_write_unittest.cc index b3b255b..ebc48d74 100644 --- a/content/browser/fileapi/file_system_operation_impl_write_unittest.cc +++ b/storage/browser/fileapi/file_system_operation_impl_write_unittest.cc
@@ -13,7 +13,6 @@ #include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/threading/thread_task_runner_handle.h" -#include "content/public/test/mock_blob_url_request_context.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_job.h" @@ -25,6 +24,7 @@ #include "storage/browser/fileapi/file_system_operation_context.h" #include "storage/browser/fileapi/file_system_operation_runner.h" #include "storage/browser/fileapi/local_file_util.h" +#include "storage/browser/test/mock_blob_url_request_context.h" #include "storage/browser/test/mock_file_change_observer.h" #include "storage/browser/test/mock_quota_manager.h" #include "storage/browser/test/test_file_system_backend.h" @@ -46,15 +46,13 @@ const GURL kOrigin("http://example.com"); const storage::FileSystemType kFileSystemType = storage::kFileSystemTypeTest; -void AssertStatusEq(base::File::Error expected, - base::File::Error actual) { +void AssertStatusEq(base::File::Error expected, base::File::Error actual) { ASSERT_EQ(expected, actual); } } // namespace -class FileSystemOperationImplWriteTest - : public testing::Test { +class FileSystemOperationImplWriteTest : public testing::Test { public: FileSystemOperationImplWriteTest() : status_(base::File::FILE_OK), @@ -146,9 +144,7 @@ } } - void DidCancel(base::File::Error status) { - cancel_status_ = status; - } + void DidCancel(base::File::Error status) { cancel_status_ = status; } const MockBlobURLRequestContext& url_request_context() const { return *url_request_context_; @@ -179,13 +175,11 @@ }; TEST_F(FileSystemOperationImplWriteTest, TestWriteSuccess) { - ScopedTextBlob blob(url_request_context(), - "blob-id:success", + ScopedTextBlob blob(url_request_context(), "blob-id:success", "Hello, world!\n"); file_system_context_->operation_runner()->Write( &url_request_context(), URLForPath(virtual_path_), - blob.GetBlobDataHandle(), - 0, RecordWriteCallback()); + blob.GetBlobDataHandle(), 0, RecordWriteCallback()); base::RunLoop().Run(); EXPECT_EQ(14, bytes_written()); @@ -209,7 +203,6 @@ EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); } - TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidBlobUrl) { std::unique_ptr<storage::BlobDataHandle> null_handle; file_system_context_->operation_runner()->Write( @@ -243,15 +236,14 @@ TEST_F(FileSystemOperationImplWriteTest, TestWriteDir) { base::FilePath virtual_dir_path(FILE_PATH_LITERAL("d")); file_system_context_->operation_runner()->CreateDirectory( - URLForPath(virtual_dir_path), - true /* exclusive */, false /* recursive */, + URLForPath(virtual_dir_path), true /* exclusive */, false /* recursive */, base::Bind(&AssertStatusEq, base::File::FILE_OK)); ScopedTextBlob blob(url_request_context(), "blob:writedir", "It\'ll not be written, too."); file_system_context_->operation_runner()->Write( &url_request_context(), URLForPath(virtual_dir_path), - blob.GetBlobDataHandle(), 0, RecordWriteCallback()); + blob.GetBlobDataHandle(), 0, RecordWriteCallback()); base::RunLoop().Run(); EXPECT_EQ(0, bytes_written()); @@ -266,8 +258,7 @@ } TEST_F(FileSystemOperationImplWriteTest, TestWriteFailureByQuota) { - ScopedTextBlob blob(url_request_context(), "blob:success", - "Hello, world!\n"); + ScopedTextBlob blob(url_request_context(), "blob:success", "Hello, world!\n"); quota_manager_->SetQuota( kOrigin, FileSystemTypeToQuotaStorageType(kFileSystemType), 10); file_system_context_->operation_runner()->Write( @@ -283,8 +274,7 @@ } TEST_F(FileSystemOperationImplWriteTest, TestImmediateCancelSuccessfulWrite) { - ScopedTextBlob blob(url_request_context(), "blob:success", - "Hello, world!\n"); + ScopedTextBlob blob(url_request_context(), "blob:success", "Hello, world!\n"); FileSystemOperationRunner::OperationID id = file_system_context_->operation_runner()->Write( &url_request_context(), URLForPath(virtual_path_),
diff --git a/content/browser/fileapi/sandbox_directory_database_unittest.cc b/storage/browser/fileapi/sandbox_directory_database_unittest.cc similarity index 99% rename from content/browser/fileapi/sandbox_directory_database_unittest.cc rename to storage/browser/fileapi/sandbox_directory_database_unittest.cc index 77525f2..30df665 100644 --- a/content/browser/fileapi/sandbox_directory_database_unittest.cc +++ b/storage/browser/fileapi/sandbox_directory_database_unittest.cc
@@ -17,7 +17,7 @@ #include "base/macros.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "content/browser/fileapi/sandbox_database_test_helper.h" +#include "storage/browser/test/sandbox_database_test_helper.h" #include "storage/common/fileapi/file_system_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/leveldatabase/src/include/leveldb/db.h"
diff --git a/content/browser/fileapi/sandbox_origin_database_unittest.cc b/storage/browser/fileapi/sandbox_origin_database_unittest.cc similarity index 99% rename from content/browser/fileapi/sandbox_origin_database_unittest.cc rename to storage/browser/fileapi/sandbox_origin_database_unittest.cc index 8c92e4f..e2675a76 100644 --- a/content/browser/fileapi/sandbox_origin_database_unittest.cc +++ b/storage/browser/fileapi/sandbox_origin_database_unittest.cc
@@ -17,8 +17,8 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/stl_util.h" -#include "content/browser/fileapi/sandbox_database_test_helper.h" #include "storage/browser/fileapi/sandbox_origin_database.h" +#include "storage/browser/test/sandbox_database_test_helper.h" #include "storage/common/fileapi/file_system_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/leveldatabase/src/db/filename.h"
diff --git a/content/public/test/mock_blob_url_request_context.cc b/storage/browser/test/mock_blob_url_request_context.cc similarity index 78% rename from content/public/test/mock_blob_url_request_context.cc rename to storage/browser/test/mock_blob_url_request_context.cc index 515c1f3..0e4f67d 100644 --- a/content/public/test/mock_blob_url_request_context.cc +++ b/storage/browser/test/mock_blob_url_request_context.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/public/test/mock_blob_url_request_context.h" +#include "storage/browser/test/mock_blob_url_request_context.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -28,12 +28,10 @@ AssertNoURLRequests(); } -ScopedTextBlob::ScopedTextBlob( - const MockBlobURLRequestContext& request_context, - const std::string& blob_id, - const std::string& data) - : blob_id_(blob_id), - context_(request_context.blob_storage_context()) { +ScopedTextBlob::ScopedTextBlob(const MockBlobURLRequestContext& request_context, + const std::string& blob_id, + const std::string& data) + : blob_id_(blob_id), context_(request_context.blob_storage_context()) { DCHECK(context_); storage::BlobDataBuilder blob_builder(blob_id_); if (!data.empty()) @@ -41,8 +39,7 @@ handle_ = context_->AddFinishedBlob(&blob_builder); } -ScopedTextBlob::~ScopedTextBlob() { -} +ScopedTextBlob::~ScopedTextBlob() {} std::unique_ptr<storage::BlobDataHandle> ScopedTextBlob::GetBlobDataHandle() { return context_->GetBlobDataFromUUID(blob_id_);
diff --git a/content/public/test/mock_blob_url_request_context.h b/storage/browser/test/mock_blob_url_request_context.h similarity index 100% rename from content/public/test/mock_blob_url_request_context.h rename to storage/browser/test/mock_blob_url_request_context.h
diff --git a/content/browser/fileapi/sandbox_database_test_helper.cc b/storage/browser/test/sandbox_database_test_helper.cc similarity index 97% rename from content/browser/fileapi/sandbox_database_test_helper.cc rename to storage/browser/test/sandbox_database_test_helper.cc index 45dbaff7..2371fb1 100644 --- a/content/browser/fileapi/sandbox_database_test_helper.cc +++ b/storage/browser/test/sandbox_database_test_helper.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/fileapi/sandbox_database_test_helper.h" +#include "storage/browser/test/sandbox_database_test_helper.h" #include <stdint.h>
diff --git a/content/browser/fileapi/sandbox_database_test_helper.h b/storage/browser/test/sandbox_database_test_helper.h similarity index 100% rename from content/browser/fileapi/sandbox_database_test_helper.h rename to storage/browser/test/sandbox_database_test_helper.h
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index e5cb856..963eeca 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -901,57 +901,109 @@ Bug(none) fast/sub-pixel/sub-pixel-composited-layer-with-transform.html [ Failure ] Bug(none) fast/sub-pixel/transformed-iframe-copy-on-scroll.html [ Failure ] Bug(none) fast/table/023.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/023.html [ Failure ] Bug(none) fast/table/027-vertical.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/027-vertical.html [ Failure ] Bug(none) fast/table/040-vertical.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/040-vertical.html [ Failure ] Bug(none) fast/table/040.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/040.html [ Failure ] Bug(none) fast/table/border-collapsing/004.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/border-collapsing/004.html [ Failure ] Bug(none) fast/table/dynamic-caption-add-before-child.xhtml [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/dynamic-caption-add-before-child.xhtml [ Failure ] Bug(none) fast/table/empty-cells.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/empty-cells.html [ Failure ] Bug(none) fast/table/frame-and-rules.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/frame-and-rules.html [ Failure ] Bug(none) fast/table/height-percent-test.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/height-percent-test.html [ Failure ] Bug(none) fast/table/multiple-captions-display.xhtml [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/multiple-captions-display.xhtml [ Failure ] Bug(none) fast/table/overflowHidden.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/overflowHidden.html [ Failure ] Bug(none) fast/table/prepend-in-anonymous-table.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/prepend-in-anonymous-table.html [ Failure ] Bug(none) fast/table/table-display-types-vertical.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/table-display-types-vertical.html [ Failure ] Bug(none) fast/table/backgr_border-table-cell-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-cell-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_border-table-cell.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-cell.html [ Failure ] Bug(none) fast/table/backgr_border-table-column-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-column-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_border-table-column-group-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-column-group-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_border-table-column-group.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-column-group.html [ Failure ] Bug(none) fast/table/backgr_border-table-column.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-column.html [ Failure ] Bug(none) fast/table/backgr_border-table-row-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-row-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_border-table-row-group-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-row-group-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_border-table-row-group.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-row-group.html [ Failure ] Bug(none) fast/table/backgr_border-table-row.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table-row.html [ Failure ] Bug(none) fast/table/backgr_border-table.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_border-table.html [ Failure ] Bug(none) fast/table/backgr_layers-hide.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_layers-hide.html [ Failure ] Bug(none) fast/table/backgr_layers-opacity-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_layers-opacity-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_layers-opacity.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_layers-opacity.html [ Failure ] Bug(none) fast/table/backgr_layers-show-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_layers-show-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_layers-show.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_layers-show.html [ Failure ] Bug(none) fast/table/backgr_position-table-cell-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-cell-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_position-table-cell.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-cell.html [ Failure ] Bug(none) fast/table/backgr_position-table-column-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-column-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_position-table-column-group-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-column-group-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_position-table-column-group.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-column-group.html [ Failure ] Bug(none) fast/table/backgr_position-table-column.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-column.html [ Failure ] Bug(none) fast/table/backgr_position-table-row-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-row-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_position-table-row-group-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-row-group-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_position-table-row-group.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-row-group.html [ Failure ] Bug(none) fast/table/backgr_position-table-row.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table-row.html [ Failure ] Bug(none) fast/table/backgr_position-table.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_position-table.html [ Failure ] Bug(none) fast/table/backgr_simple-table-cell-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_simple-table-cell.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-cell.html [ Failure ] Bug(none) fast/table/backgr_simple-table-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_simple-table-column-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_simple-table-column-group-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_simple-table-column-group.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-column-group.html [ Failure ] Bug(none) fast/table/backgr_simple-table-column.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-column.html [ Failure ] Bug(none) fast/table/backgr_simple-table-row-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_simple-table-row-group-collapsed-border.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border.html [ Failure ] Bug(none) fast/table/backgr_simple-table-row-group.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-row-group.html [ Failure ] Bug(none) fast/table/backgr_simple-table-row.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table-row.html [ Failure ] Bug(none) fast/table/backgr_simple-table.html [ Failure ] +Bug(none) virtual/mojo-loading/fast/table/backgr_simple-table.html [ Failure ] Bug(none) fast/text-autosizing/hackernews-comments.html [ Failure ] Bug(none) fast/text/capitalize-boundaries.html [ Failure ] Bug(none) fast/text/descent-clip-in-scaled-page.html [ Crash Timeout ]
diff --git a/third_party/WebKit/LayoutTests/ImageFirstTests b/third_party/WebKit/LayoutTests/ImageFirstTests index ab1c8c0..58d0727 100644 --- a/third_party/WebKit/LayoutTests/ImageFirstTests +++ b/third_party/WebKit/LayoutTests/ImageFirstTests
@@ -78,3 +78,4 @@ virtual/layout_ng/fast/block/margin-collapse virtual/layout_ng/fast/block/float virtual/layout_ng/external/wpt/css/CSS2/linebox +virtual/mojo-loading/fast/table
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests index 58e3340..af54bb9 100644 --- a/third_party/WebKit/LayoutTests/NeverFixTests +++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -204,7 +204,9 @@ crbug.com/606302 [ Win7 Debug ] transforms/3d/point-mapping/3d-point-mapping-preserve-3d.html [ WontFix ] crbug.com/606302 [ Win7 Debug ] transforms/3d/point-mapping/3d-point-mapping-deep.html [ WontFix ] crbug.com/702176 [ Win7 Debug ] fast/table/border-collapsing/001-vertical.html [ WontFix ] +crbug.com/702176 [ Win7 Debug ] virtual/mojo-loading/fast/table/border-collapsing/001-vertical.html [ WontFix ] crbug.com/702176 [ Win7 Debug ] fast/table/border-collapsing/001.html [ WontFix ] +crbug.com/702176 [ Win7 Debug ] virtual/mojo-loading/fast/table/border-collapsing/001.html [ WontFix ] # Rendering issue only seen in Layout Tests on Android. # R and B color channels switched on decoded images.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 7244db8f..c40c96b 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -758,6 +758,8 @@ crbug.com/636207 [ Win Debug ] fast/dom/HTMLImageElement/image-srcset-w-onerror.html [ Failure Pass ] crbug.com/636207 [ Win Debug ] virtual/sharedarraybuffer/fast/dom/HTMLImageElement/image-srcset-w-onerror.html [ Failure Pass ] +crbug.com/v8/6206 fast/js/string-prototype-properties.html [ NeedsManualRebaseline ] + crbug.com/569139 fast/js/string-replace-2.html [ Failure ] crbug.com/569139 fast/js/regexp-caching.html [ Failure ] crbug.com/597221 fast/dom/Window/window-postmessage-clone-deep-array.html [ Failure ] @@ -787,6 +789,7 @@ crbug.com/264138 dom/legacy_dom_conformance/xhtml/level3/core/nodecomparedocumentposition38.xhtml [ Failure ] crbug.com/410145 [ Win ] fast/table/column-in-inline.html [ Failure ] +crbug.com/410145 [ Win ] virtual/mojo-loading/fast/table/column-in-inline.html [ Failure ] crbug.com/411164 [ Win ] http/tests/security/powerfulFeatureRestrictions/serviceworker-on-insecure-origin.html [ Pass ] crbug.com/411164 [ Win ] virtual/mojo-loading/http/tests/security/powerfulFeatureRestrictions/serviceworker-on-insecure-origin.html [ Pass ] @@ -1811,7 +1814,6 @@ crbug.com/711529 virtual/mojo-loading/http/tests/notifications/update-shared-worker.html [ Timeout ] crbug.com/711529 virtual/mojo-loading/http/tests/notifications/close-shared-worker.html [ Timeout ] crbug.com/711529 virtual/mojo-loading/http/tests/notifications/click-shared-worker.html [ Timeout ] -crbug.com/711529 virtual/mojo-loading/http/tests/streams/piping/multiple-propagation.https.html [ Timeout ] crbug.com/711529 virtual/mojo-loading/http/tests/permissions/test-api-surface.html [ Timeout ] crbug.com/711529 virtual/mojo-loading/http/tests/permissions/test-query.html [ Timeout ] crbug.com/711529 http/tests/origin_trials/sample-api-workers.html [ Timeout ] @@ -1821,7 +1823,6 @@ crbug.com/711529 http/tests/notifications/click-shared-worker.html [ Timeout ] crbug.com/711529 http/tests/permissions/test-api-surface.html [ Timeout ] crbug.com/711529 http/tests/permissions/test-query.html [ Timeout ] -crbug.com/711529 http/tests/streams/piping/multiple-propagation.https.html [ Timeout ] # ====== New tests from wpt-importer added here ====== crbug.com/626703 external/wpt/XMLHttpRequest/getresponseheader-chunked-trailer.htm [ Failure ] @@ -1873,15 +1874,6 @@ crbug.com/626703 external/wpt/streams/readable-streams/pipe-through.sharedworker.html [ Timeout ] crbug.com/626703 external/wpt/streams/readable-streams/tee.sharedworker.html [ Timeout ] crbug.com/626703 external/wpt/streams/readable-streams/templated.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/bad-strategies.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/bad-underlying-sinks.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/brand-checks.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/byte-length-queuing-strategy.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/count-queuing-strategy.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/general.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/reentrant-strategy.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/start.sharedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/write.sharedworker.html [ Timeout ] crbug.com/626703 external/wpt/css/CSS2/linebox/inline-formatting-context-010b.xht [ Skip ] crbug.com/626703 external/wpt/css/CSS2/linebox/inline-formatting-context-012.xht [ Failure ] crbug.com/626703 [ Android Linux Win ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-item-vert-001b.html [ Failure ] @@ -1993,8 +1985,6 @@ crbug.com/626703 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Timeout ] crbug.com/626703 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html [ Timeout ] crbug.com/626703 [ Android Mac ] external/wpt/pointerevents/pointerevent_disabled_form_control-manual.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/floating-point-total-queue-size.dedicatedworker.html [ Timeout ] -crbug.com/626703 external/wpt/streams/writable-streams/floating-point-total-queue-size.sharedworker.html [ Timeout ] crbug.com/626703 external/wpt/mediacapture-streams/MediaStreamTrack-end-manual.https.html [ Timeout ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element.html [ Failure ] @@ -2558,6 +2548,7 @@ crbug.com/652536 fast/events/mouse-cursor.html [ Pass Failure ] crbug.com/671478 fast/table/percent-height-replaced-content-in-cell.html [ Pass Failure ] +crbug.com/671478 virtual/mojo-loading/fast/table/percent-height-replaced-content-in-cell.html [ Pass Failure ] crbug.com/663858 fast/text/emphasis.html [ Pass Failure ] crbug.com/663858 fast/text/emphasis-vertical.html [ Pass Failure ] crbug.com/663876 http/tests/loading/doc-write-sync-third-party-script-block-effectively-2g.html [ Pass Failure ] @@ -2673,10 +2664,6 @@ # Flaky on trybots crbug.com/688486 external/wpt/service-workers/service-worker/fetch-request-resources.https.html [ Failure Pass ] -# Flaky when run in parallel -crbug.com/712332 accessibility/aom.html [ Failure Pass ] -crbug.com/712332 accessibility/aom-string-properties.html [ Failure Pass ] - # Sheriff failures 2017-02-21 crbug.com/73609 http/tests/media/video-play-stall.html [ Pass Timeout ] crbug.com/73609 virtual/mojo-loading/http/tests/media/video-play-stall.html [ Pass Timeout ] @@ -2719,5 +2706,3 @@ # Tests to be run only under virtual/experimental-canvas-features/ crbug.com/682753 fast/canvas-experimental [ Skip ] - -crbug.com/712264 external/wpt/service-workers/service-worker/fetch-event.https.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index f018d97b..14cf539 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -408,6 +408,11 @@ "args": ["--enable-blink-features=LoadingWithMojo"] }, { + "prefix": "mojo-loading", + "base": "fast/table", + "args": ["--enable-blink-features=LoadingWithMojo"] + }, + { "prefix": "scalefactor150", "base": "fast/events/synthetic-events", "args": ["--force-device-scale-factor=1.5"]
diff --git a/third_party/WebKit/LayoutTests/accessibility/aom-string-properties.html b/third_party/WebKit/LayoutTests/accessibility/aom-string-properties.html index ea3fac33..3e17d31 100644 --- a/third_party/WebKit/LayoutTests/accessibility/aom-string-properties.html +++ b/third_party/WebKit/LayoutTests/accessibility/aom-string-properties.html
@@ -12,8 +12,9 @@ --> <script> -if (window.internals) - internals.runtimeFlags.accessibilityObjectModelEnabled = true; +test(function(t) { + assert_true(internals.runtimeFlags.accessibilityObjectModelEnabled); +}, "Make sure that Accessibility Object Model is enabled"); </script> <div role="combobox" id="autocomplete"></div> @@ -34,18 +35,22 @@ test(function(t) { var node = document.getElementById("checked"); var axNode = accessibilityController.accessibleElementById("checked"); - assert_equals(axNode.checkedState, 0); + assert_equals(axNode.isChecked, false); + assert_equals(axNode.isButtonStateMixed, false); node.accessibleNode.checked = "true"; - assert_equals(axNode.checkedState, 1); + assert_equals(axNode.isChecked, true); + assert_equals(axNode.isButtonStateMixed, false); node.accessibleNode.checked = "mixed"; - assert_equals(axNode.checkedState, 2); + assert_equals(axNode.isChecked, true); assert_equals(axNode.isButtonStateMixed, true); // It also works to set it to just true or false (no quotes). node.accessibleNode.checked = true; - assert_equals(axNode.checkedState, 1); + assert_equals(axNode.isChecked, true); + assert_equals(axNode.isButtonStateMixed, false); node.accessibleNode.checked = false; - assert_equals(axNode.checkedState, 0); + assert_equals(axNode.isChecked, false); + assert_equals(axNode.isButtonStateMixed, false); }, "AccessibleNode.checked"); </script>
diff --git a/third_party/WebKit/LayoutTests/accessibility/aom.html b/third_party/WebKit/LayoutTests/accessibility/aom.html index c77de58..bb19384 100644 --- a/third_party/WebKit/LayoutTests/accessibility/aom.html +++ b/third_party/WebKit/LayoutTests/accessibility/aom.html
@@ -14,8 +14,9 @@ <button id="button">Click Me</button> <script> -if (window.internals) - internals.runtimeFlags.accessibilityObjectModelEnabled = true; +test(function(t) { + assert_true(internals.runtimeFlags.accessibilityObjectModelEnabled); +}, "Make sure that Accessibility Object Model is enabled"); test(function(t) { var button = document.getElementById("button");
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/combine-motion-translation-and-rotation-expected.html b/third_party/WebKit/LayoutTests/css3/motion-path/combine-motion-translation-and-rotation-expected.html deleted file mode 100644 index 6743e04..0000000 --- a/third_party/WebKit/LayoutTests/css3/motion-path/combine-motion-translation-and-rotation-expected.html +++ /dev/null
@@ -1,18 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<style> -#div1 { - position: absolute; - left: 100; - top: 200; - transform-origin: 60% 20%; - transform: translate(70px, 80px) rotate(30deg) translate(80px, 60px) rotate(-90deg); - transform-origin: 0% 0%; -} -</style> -</head> -<body> -<div id="div1">div1</div> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/combine-motion-translation-and-rotation.html b/third_party/WebKit/LayoutTests/css3/motion-path/combine-motion-translation-and-rotation.html deleted file mode 100644 index 982e39e0..0000000 --- a/third_party/WebKit/LayoutTests/css3/motion-path/combine-motion-translation-and-rotation.html +++ /dev/null
@@ -1,19 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<style> -#div1 { - position: absolute; - left: 100; - top: 200; - motion: path('M 20 30 l 100 100') auto -15deg 50%; - transform: translate(80px, 60px) rotate(-90deg); - transform-origin: 0% 0%; - offset-anchor: 0% 0%; -} -</style> -</head> -<body> -<div id="div1">div1</div> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated-expected.txt b/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated-expected.txt deleted file mode 100644 index 9aeb8308..0000000 --- a/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CONSOLE WARNING: motion is deprecated and will be removed in M58, around April 2017. Please use offset instead. See https://www.chromestatus.com/features/6390764217040896 for more details. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated.html b/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated.html deleted file mode 100644 index 94f1572e..0000000 --- a/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/js-test.js"></script> -<style> -.foo { - motion: path('m 0 0 v 1'); -} -</style>
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/motion.html b/third_party/WebKit/LayoutTests/css3/motion-path/motion.html deleted file mode 100644 index 7d6a79b..0000000 --- a/third_party/WebKit/LayoutTests/css3/motion-path/motion.html +++ /dev/null
@@ -1,69 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<style> -#div2 { - motion: none 50% auto 400grad; -} -#div3 { - motion: path('M 10 20 h 30 v 150') 0rad 70px; -} -#div4 { - motion: 10px 90deg reverse none; -} -</style> -</head> -<body> -<div id="div1"></div> -<div id="div2"></div> -<div id="div3"></div> -<div id="div4"></div> -<span id="span1" style="motion: path('M 1 2 V 3') 4px 5deg"></span> -<script> -"use strict"; - -test(function() { - assert_equals(getComputedStyle(div1, null).motionPath, 'none'); - assert_equals(getComputedStyle(div1, null).motionOffset, '0px'); - assert_equals(getComputedStyle(div1, null).motionRotation, 'auto 0deg'); - assert_equals(getComputedStyle(div1, null).motion, 'none 0px auto 0deg'); - assert_equals(getComputedStyle(div1, null).transform, 'none'); -}, 'motion default is none 0px auto 0deg'); - -test(function() { - assert_equals(getComputedStyle(div2, null).motionPath, 'none'); - assert_equals(getComputedStyle(div2, null).motionOffset, '50%'); - assert_equals(getComputedStyle(div2, null).motionRotation, 'auto 360deg'); - assert_equals(getComputedStyle(div2, null).motion, 'none 50% auto 360deg'); - assert_equals(getComputedStyle(div2, null).transform, 'none'); -}, 'motion supports various angle units'); - -test(function() { - assert_equals(getComputedStyle(div3, null).motionPath, "path('M 10 20 h 30 v 150')"); - assert_equals(getComputedStyle(div3, null).motionOffset, '70px'); - assert_equals(getComputedStyle(div3, null).motionRotation, '0deg'); - assert_equals(getComputedStyle(div3, null).motion, "path('M 10 20 h 30 v 150') 70px 0deg"); - assert_equals(getComputedStyle(div3, null).transform, 'matrix(1, 0, 0, 1, 0, 0)'); -}, 'motion supports SVG path data'); - -test(function() { - assert_equals(getComputedStyle(div4, null).motionPath, 'none'); - assert_equals(getComputedStyle(div4, null).motionOffset, '10px'); - assert_equals(getComputedStyle(div4, null).motionRotation, 'auto 270deg'); - assert_equals(getComputedStyle(div4, null).motion, 'none 10px auto 270deg'); - assert_equals(getComputedStyle(div4, null).transform, 'none'); -}, 'motion property data can be supplied in any order'); - -test(function() { - assert_equals(span1.style.motionPath, "path('M 1 2 V 3')"); - assert_equals(span1.style.motionOffset, '4px'); - assert_equals(span1.style.motionRotation, '5deg'); - assert_equals(span1.style.motion, "path('M 1 2 V 3') 4px 5deg"); - assert_equals(span1.style.transform, ''); -}, 'motion style can be set inline'); - -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/use-count-motion.html b/third_party/WebKit/LayoutTests/css3/motion-path/use-count-motion.html deleted file mode 100644 index 51d63f3..0000000 --- a/third_party/WebKit/LayoutTests/css3/motion-path/use-count-motion.html +++ /dev/null
@@ -1,26 +0,0 @@ -<!DOCTYPE html> -<head> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <style> - .n { motion: none; } - </style> -</head> - -<div id="target"></div> -<script> -var CSSMotionInEffect = 1616; // From UseCounter.h -var CSSOffsetInEffect = 1617; // From UseCounter.h - -test(function() { - assert_false(internals.isUseCounted(document, CSSMotionInEffect)); - - var styleElement = document.createElement('style'); - styleElement.textContent = ".p { motion: path('m 0 0 h 1'); }"; - document.head.appendChild(styleElement); - - assert_true(internals.isUseCounted(document, CSSMotionInEffect)); - - assert_false(internals.isUseCounted(document, CSSOffsetInEffect)); -}); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 0169b6d3..e174aae3 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -75715,6 +75715,11 @@ {} ] ], + "html/browsers/the-window-object/window-indexed-properties-expected.txt": [ + [ + {} + ] + ], "html/browsers/the-window-object/window-indexed-properties-strict-expected.txt": [ [ {} @@ -176399,6 +176404,10 @@ "d2821f3c4c01cb0dde1ec892d90e7309bbe842a7", "testharness" ], + "html/browsers/the-window-object/window-indexed-properties-expected.txt": [ + "993d4ee44994a8a0d06d354abe3aa596946dd72a", + "support" + ], "html/browsers/the-window-object/window-indexed-properties-strict-expected.txt": [ "624baff00a9efae0597ae657ed81dfd2403248d4", "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-combine-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-combine-expected.txt deleted file mode 100644 index 268727c..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-combine-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Create headers using same name for different values assert_equals: expected "doubleValue1, doubleValue2" but got "doubleValue1,doubleValue2" -PASS Check delete and has methods when using same name for different values -PASS Check set methods when called with already used name -FAIL Check append methods when called with already used name assert_equals: expected "singleValue, newSingleValue" but got "singleValue,newSingleValue" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt index 7d5a409..cb3a41bf 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
@@ -11,8 +11,8 @@ PASS Multiple calls of respondWith must throw InvalidStateErrors PASS Service Worker event.respondWith must set the used flag PASS Service Worker should expose FetchEvent URL fragments. -FAIL Service Worker responds to fetch event with the correct cache types assert_unreached: unexpected rejection: assert_equals: expected "no-cache" but got "default" Reached unreachable code +FAIL Service Worker responds to fetch event with the correct cache types assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with the correct type expected "no-store" but got "default" Reached unreachable code FAIL Service Worker should intercept EventSource assert_unreached: unexpected rejection: assert_equals: EventSource should bypass the http cache. expected "no-store" but got "default" Reached unreachable code -PASS Service Worker responds to fetch event with the correct integrity_metadata +FAIL Service Worker responds to fetch event with the correct integrity_metadata assert_unreached: unexpected rejection: assert_equals: integrity expected "gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=" but got "" Reached unreachable code Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https.html index 8d0531e..062a41e 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https.html
@@ -516,6 +516,7 @@ }) .catch(unreached_rejection(t)); }, 'Service Worker should expose FetchEvent URL fragments.'); + async_test(function(t) { var scope = 'resources/simple.html?cache'; var frame; @@ -549,6 +550,7 @@ .catch(reject); }); }); + return Promise.all(tests); }) .then(function() { return new Promise(function(resolve, reject) { @@ -639,25 +641,16 @@ assert_equals( frame.contentDocument.body.textContent, ''); - return new Promise(function(resolve, reject) { - return frame.contentWindow.fetch(scope, - {'integrity': integrity_metadata}) - .then(function(response) { - return response.text(); - }) - .then(function(response_text) { - // Should get the same integrity metadata. - assert_equals(response_text, integrity_metadata, - 'Service Worker should respond to fetch with the correct integrity'); - }) - .then(resolve()) - .catch(reject()); - }); + return frame.contentWindow.fetch(scope, {'integrity': integrity_metadata}); }) - .then(function() { + .then(response => { + return response.text(); + }) + .then(response_text => { + assert_equals(response_text, integrity_metadata, 'integrity'); frame.remove(); return service_worker_unregister_and_done(t, scope); - }) + }) .catch(unreached_rejection(t)); }, 'Service Worker responds to fetch event with the correct integrity_metadata');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting-expected.txt deleted file mode 100644 index fd7a2e2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting-expected.txt +++ /dev/null
@@ -1,52 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = error2 -PASS Aborting a WritableStream before it starts should cause the writer's unsettled ready promise to reject -PASS Aborting a WritableStream should cause the writer's fulfilled ready promise to reset to a rejected one -PASS abort() on a released writer rejects -PASS Aborting a WritableStream immediately prevents future writes -PASS Aborting a WritableStream prevents further writes after any that are in progress -PASS Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value -PASS WritableStream if sink's abort throws, the promise returned by writer.abort() rejects -PASS WritableStream if sink's abort throws, the promise returned by ws.abort() rejects -PASS WritableStream if sink's abort throws, for an abort performed during a write, the promise returned by ws.abort() rejects -PASS Aborting a WritableStream passes through the given reason -PASS Aborting a WritableStream puts it in an errored state, with a TypeError as the stored error -PASS Aborting a WritableStream causes any outstanding write() promises to be rejected with a TypeError -PASS Closing but then immediately aborting a WritableStream causes the stream to error -PASS Closing a WritableStream and aborting it while it closes causes the stream to ignore the abort attempt -PASS Aborting a WritableStream after it is closed is a no-op -PASS WritableStream should NOT call underlying sink's close if no abort is supplied (historical) -PASS returning a thenable from abort() should work -PASS .closed should not resolve before fulfilled write() -FAIL .closed should not resolve before rejected write(); write() error should not overwrite abort() error promise_test: Unhandled rejection with value: object "error1: error1" -PASS writes should be satisfied in order when aborting -FAIL writes should be satisfied in order after rejected write when aborting promise_test: Unhandled rejection with value: object "error1: error1" -FAIL close() should reject with TypeError when abort() is first error promise_test: Unhandled rejection with value: object "error1: error1" -PASS underlying abort() should not be called until underlying write() completes -PASS underlying abort() should not be called if underlying close() has started -PASS if underlying close() has started and then rejects, the abort() and close() promises should reject with the underlying close rejection reason -PASS an abort() that happens during a write() should trigger the underlying abort() even with a close() queued -PASS if a writer is created for a stream with a pending abort, its ready should be rejected with a TypeError -PASS writer close() promise should resolve before abort() promise -PASS writer.ready should reject on controller error without waiting for underlying write -FAIL writer.abort() while there is an in-flight write, and then finish the write with rejection promise_test: Unhandled rejection with value: object "error2: error2" -FAIL writer.abort(), controller.error() while there is an in-flight write, and then finish the write assert_throws: writePromise3 must reject with an error indicating abort function "function () { throw e }" threw object "error2: error2" ("error2") expected object "TypeError" ("TypeError") -FAIL writer.abort(), controller.error() while there is an in-flight close, and then finish the close promise_test: Unhandled rejection with value: object "error2: error2" -FAIL controller.error(), writer.abort() while there is an in-flight write, and then finish the write assert_array_equals: writePromise and writer.closed must not be fulfilled/rejected yet even after writer.abort() lengths differ, expected 0 got 1 -FAIL controller.error(), writer.abort() while there is an in-flight close, and then finish the close promise_test: Unhandled rejection with value: object "error2: error2" -PASS releaseLock() while aborting should reject the original closed promise -FAIL releaseLock() during delayed async abort() should reject the writer.closed promise assert_equals: closed promise should not have changed expected object "[object Promise]" but got object "[object Promise]" -PASS sink abort() should not be called until sink start() is done -FAIL if start attempts to error the controller after abort() has been called, then it should lose promise_test: Unhandled rejection with value: object "error1: error1" -FAIL stream abort() promise should still resolve if sink start() rejects promise_test: Unhandled rejection with value: object "error1: error1" -PASS writer abort() during sink start() should replace the writer.ready promise synchronously -FAIL promises returned from other writer methods should be rejected when writer abort() happens during sink start() assert_array_equals: promises should resolve in the standard order property 1, expected "write1" but got "close" -FAIL abort() should succeed despite rejection from write promise_test: Unhandled rejection with value: object "error1: error1" -FAIL abort() should be rejected with the rejection returned from close() assert_throws: abort() should reject with error2 function "function () { throw e }" threw object "error1: error1" ("error1") expected object "error2: error2" ("error2") -FAIL a rejecting sink.write() should not prevent sink.abort() from being called promise_test: Unhandled rejection with value: object "error1: error1" -FAIL when start errors after stream abort(), underlying sink abort() should be called anyway promise_test: Unhandled rejection with value: object "error1: error1" -PASS when calling abort() twice on the same stream, the second call should reject -PASS sink abort() should not be called if stream was erroring due to controller.error() before abort() was called -PASS sink abort() should not be called if stream was erroring due to bad strategy before abort() was called -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.dedicatedworker-expected.txt deleted file mode 100644 index fd7a2e2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.dedicatedworker-expected.txt +++ /dev/null
@@ -1,52 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = error2 -PASS Aborting a WritableStream before it starts should cause the writer's unsettled ready promise to reject -PASS Aborting a WritableStream should cause the writer's fulfilled ready promise to reset to a rejected one -PASS abort() on a released writer rejects -PASS Aborting a WritableStream immediately prevents future writes -PASS Aborting a WritableStream prevents further writes after any that are in progress -PASS Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value -PASS WritableStream if sink's abort throws, the promise returned by writer.abort() rejects -PASS WritableStream if sink's abort throws, the promise returned by ws.abort() rejects -PASS WritableStream if sink's abort throws, for an abort performed during a write, the promise returned by ws.abort() rejects -PASS Aborting a WritableStream passes through the given reason -PASS Aborting a WritableStream puts it in an errored state, with a TypeError as the stored error -PASS Aborting a WritableStream causes any outstanding write() promises to be rejected with a TypeError -PASS Closing but then immediately aborting a WritableStream causes the stream to error -PASS Closing a WritableStream and aborting it while it closes causes the stream to ignore the abort attempt -PASS Aborting a WritableStream after it is closed is a no-op -PASS WritableStream should NOT call underlying sink's close if no abort is supplied (historical) -PASS returning a thenable from abort() should work -PASS .closed should not resolve before fulfilled write() -FAIL .closed should not resolve before rejected write(); write() error should not overwrite abort() error promise_test: Unhandled rejection with value: object "error1: error1" -PASS writes should be satisfied in order when aborting -FAIL writes should be satisfied in order after rejected write when aborting promise_test: Unhandled rejection with value: object "error1: error1" -FAIL close() should reject with TypeError when abort() is first error promise_test: Unhandled rejection with value: object "error1: error1" -PASS underlying abort() should not be called until underlying write() completes -PASS underlying abort() should not be called if underlying close() has started -PASS if underlying close() has started and then rejects, the abort() and close() promises should reject with the underlying close rejection reason -PASS an abort() that happens during a write() should trigger the underlying abort() even with a close() queued -PASS if a writer is created for a stream with a pending abort, its ready should be rejected with a TypeError -PASS writer close() promise should resolve before abort() promise -PASS writer.ready should reject on controller error without waiting for underlying write -FAIL writer.abort() while there is an in-flight write, and then finish the write with rejection promise_test: Unhandled rejection with value: object "error2: error2" -FAIL writer.abort(), controller.error() while there is an in-flight write, and then finish the write assert_throws: writePromise3 must reject with an error indicating abort function "function () { throw e }" threw object "error2: error2" ("error2") expected object "TypeError" ("TypeError") -FAIL writer.abort(), controller.error() while there is an in-flight close, and then finish the close promise_test: Unhandled rejection with value: object "error2: error2" -FAIL controller.error(), writer.abort() while there is an in-flight write, and then finish the write assert_array_equals: writePromise and writer.closed must not be fulfilled/rejected yet even after writer.abort() lengths differ, expected 0 got 1 -FAIL controller.error(), writer.abort() while there is an in-flight close, and then finish the close promise_test: Unhandled rejection with value: object "error2: error2" -PASS releaseLock() while aborting should reject the original closed promise -FAIL releaseLock() during delayed async abort() should reject the writer.closed promise assert_equals: closed promise should not have changed expected object "[object Promise]" but got object "[object Promise]" -PASS sink abort() should not be called until sink start() is done -FAIL if start attempts to error the controller after abort() has been called, then it should lose promise_test: Unhandled rejection with value: object "error1: error1" -FAIL stream abort() promise should still resolve if sink start() rejects promise_test: Unhandled rejection with value: object "error1: error1" -PASS writer abort() during sink start() should replace the writer.ready promise synchronously -FAIL promises returned from other writer methods should be rejected when writer abort() happens during sink start() assert_array_equals: promises should resolve in the standard order property 1, expected "write1" but got "close" -FAIL abort() should succeed despite rejection from write promise_test: Unhandled rejection with value: object "error1: error1" -FAIL abort() should be rejected with the rejection returned from close() assert_throws: abort() should reject with error2 function "function () { throw e }" threw object "error1: error1" ("error1") expected object "error2: error2" ("error2") -FAIL a rejecting sink.write() should not prevent sink.abort() from being called promise_test: Unhandled rejection with value: object "error1: error1" -FAIL when start errors after stream abort(), underlying sink abort() should be called anyway promise_test: Unhandled rejection with value: object "error1: error1" -PASS when calling abort() twice on the same stream, the second call should reject -PASS sink abort() should not be called if stream was erroring due to controller.error() before abort() was called -PASS sink abort() should not be called if stream was erroring due to bad strategy before abort() was called -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.serviceworker.https-expected.txt deleted file mode 100644 index 4367f58c..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.serviceworker.https-expected.txt +++ /dev/null
@@ -1,53 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = error2 -PASS Service worker test setup -PASS Aborting a WritableStream before it starts should cause the writer's unsettled ready promise to reject -PASS Aborting a WritableStream should cause the writer's fulfilled ready promise to reset to a rejected one -PASS abort() on a released writer rejects -PASS Aborting a WritableStream immediately prevents future writes -PASS Aborting a WritableStream prevents further writes after any that are in progress -PASS Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value -PASS WritableStream if sink's abort throws, the promise returned by writer.abort() rejects -PASS WritableStream if sink's abort throws, the promise returned by ws.abort() rejects -PASS WritableStream if sink's abort throws, for an abort performed during a write, the promise returned by ws.abort() rejects -PASS Aborting a WritableStream passes through the given reason -PASS Aborting a WritableStream puts it in an errored state, with a TypeError as the stored error -PASS Aborting a WritableStream causes any outstanding write() promises to be rejected with a TypeError -PASS Closing but then immediately aborting a WritableStream causes the stream to error -PASS Closing a WritableStream and aborting it while it closes causes the stream to ignore the abort attempt -PASS Aborting a WritableStream after it is closed is a no-op -PASS WritableStream should NOT call underlying sink's close if no abort is supplied (historical) -PASS returning a thenable from abort() should work -PASS .closed should not resolve before fulfilled write() -FAIL .closed should not resolve before rejected write(); write() error should not overwrite abort() error promise_test: Unhandled rejection with value: object "error1: error1" -PASS writes should be satisfied in order when aborting -FAIL writes should be satisfied in order after rejected write when aborting promise_test: Unhandled rejection with value: object "error1: error1" -FAIL close() should reject with TypeError when abort() is first error promise_test: Unhandled rejection with value: object "error1: error1" -PASS underlying abort() should not be called until underlying write() completes -PASS underlying abort() should not be called if underlying close() has started -PASS if underlying close() has started and then rejects, the abort() and close() promises should reject with the underlying close rejection reason -PASS an abort() that happens during a write() should trigger the underlying abort() even with a close() queued -PASS if a writer is created for a stream with a pending abort, its ready should be rejected with a TypeError -PASS writer close() promise should resolve before abort() promise -PASS writer.ready should reject on controller error without waiting for underlying write -FAIL writer.abort() while there is an in-flight write, and then finish the write with rejection promise_test: Unhandled rejection with value: object "error2: error2" -FAIL writer.abort(), controller.error() while there is an in-flight write, and then finish the write assert_throws: writePromise3 must reject with an error indicating abort function "function () { throw e }" threw object "error2: error2" ("error2") expected object "TypeError" ("TypeError") -FAIL writer.abort(), controller.error() while there is an in-flight close, and then finish the close promise_test: Unhandled rejection with value: object "error2: error2" -FAIL controller.error(), writer.abort() while there is an in-flight write, and then finish the write assert_array_equals: writePromise and writer.closed must not be fulfilled/rejected yet even after writer.abort() lengths differ, expected 0 got 1 -FAIL controller.error(), writer.abort() while there is an in-flight close, and then finish the close promise_test: Unhandled rejection with value: object "error2: error2" -PASS releaseLock() while aborting should reject the original closed promise -FAIL releaseLock() during delayed async abort() should reject the writer.closed promise assert_equals: closed promise should not have changed expected object "[object Promise]" but got object "[object Promise]" -PASS sink abort() should not be called until sink start() is done -FAIL if start attempts to error the controller after abort() has been called, then it should lose promise_test: Unhandled rejection with value: object "error1: error1" -FAIL stream abort() promise should still resolve if sink start() rejects promise_test: Unhandled rejection with value: object "error1: error1" -PASS writer abort() during sink start() should replace the writer.ready promise synchronously -FAIL promises returned from other writer methods should be rejected when writer abort() happens during sink start() assert_array_equals: promises should resolve in the standard order property 1, expected "write1" but got "close" -FAIL abort() should succeed despite rejection from write promise_test: Unhandled rejection with value: object "error1: error1" -FAIL abort() should be rejected with the rejection returned from close() assert_throws: abort() should reject with error2 function "function () { throw e }" threw object "error1: error1" ("error1") expected object "error2: error2" ("error2") -FAIL a rejecting sink.write() should not prevent sink.abort() from being called promise_test: Unhandled rejection with value: object "error1: error1" -FAIL when start errors after stream abort(), underlying sink abort() should be called anyway promise_test: Unhandled rejection with value: object "error1: error1" -PASS when calling abort() twice on the same stream, the second call should reject -PASS sink abort() should not be called if stream was erroring due to controller.error() before abort() was called -PASS sink abort() should not be called if stream was erroring due to bad strategy before abort() was called -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.sharedworker-expected.txt deleted file mode 100644 index fd7a2e2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/aborting.sharedworker-expected.txt +++ /dev/null
@@ -1,52 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = error2 -PASS Aborting a WritableStream before it starts should cause the writer's unsettled ready promise to reject -PASS Aborting a WritableStream should cause the writer's fulfilled ready promise to reset to a rejected one -PASS abort() on a released writer rejects -PASS Aborting a WritableStream immediately prevents future writes -PASS Aborting a WritableStream prevents further writes after any that are in progress -PASS Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value -PASS WritableStream if sink's abort throws, the promise returned by writer.abort() rejects -PASS WritableStream if sink's abort throws, the promise returned by ws.abort() rejects -PASS WritableStream if sink's abort throws, for an abort performed during a write, the promise returned by ws.abort() rejects -PASS Aborting a WritableStream passes through the given reason -PASS Aborting a WritableStream puts it in an errored state, with a TypeError as the stored error -PASS Aborting a WritableStream causes any outstanding write() promises to be rejected with a TypeError -PASS Closing but then immediately aborting a WritableStream causes the stream to error -PASS Closing a WritableStream and aborting it while it closes causes the stream to ignore the abort attempt -PASS Aborting a WritableStream after it is closed is a no-op -PASS WritableStream should NOT call underlying sink's close if no abort is supplied (historical) -PASS returning a thenable from abort() should work -PASS .closed should not resolve before fulfilled write() -FAIL .closed should not resolve before rejected write(); write() error should not overwrite abort() error promise_test: Unhandled rejection with value: object "error1: error1" -PASS writes should be satisfied in order when aborting -FAIL writes should be satisfied in order after rejected write when aborting promise_test: Unhandled rejection with value: object "error1: error1" -FAIL close() should reject with TypeError when abort() is first error promise_test: Unhandled rejection with value: object "error1: error1" -PASS underlying abort() should not be called until underlying write() completes -PASS underlying abort() should not be called if underlying close() has started -PASS if underlying close() has started and then rejects, the abort() and close() promises should reject with the underlying close rejection reason -PASS an abort() that happens during a write() should trigger the underlying abort() even with a close() queued -PASS if a writer is created for a stream with a pending abort, its ready should be rejected with a TypeError -PASS writer close() promise should resolve before abort() promise -PASS writer.ready should reject on controller error without waiting for underlying write -FAIL writer.abort() while there is an in-flight write, and then finish the write with rejection promise_test: Unhandled rejection with value: object "error2: error2" -FAIL writer.abort(), controller.error() while there is an in-flight write, and then finish the write assert_throws: writePromise3 must reject with an error indicating abort function "function () { throw e }" threw object "error2: error2" ("error2") expected object "TypeError" ("TypeError") -FAIL writer.abort(), controller.error() while there is an in-flight close, and then finish the close promise_test: Unhandled rejection with value: object "error2: error2" -FAIL controller.error(), writer.abort() while there is an in-flight write, and then finish the write assert_array_equals: writePromise and writer.closed must not be fulfilled/rejected yet even after writer.abort() lengths differ, expected 0 got 1 -FAIL controller.error(), writer.abort() while there is an in-flight close, and then finish the close promise_test: Unhandled rejection with value: object "error2: error2" -PASS releaseLock() while aborting should reject the original closed promise -FAIL releaseLock() during delayed async abort() should reject the writer.closed promise assert_equals: closed promise should not have changed expected object "[object Promise]" but got object "[object Promise]" -PASS sink abort() should not be called until sink start() is done -FAIL if start attempts to error the controller after abort() has been called, then it should lose promise_test: Unhandled rejection with value: object "error1: error1" -FAIL stream abort() promise should still resolve if sink start() rejects promise_test: Unhandled rejection with value: object "error1: error1" -PASS writer abort() during sink start() should replace the writer.ready promise synchronously -FAIL promises returned from other writer methods should be rejected when writer abort() happens during sink start() assert_array_equals: promises should resolve in the standard order property 1, expected "write1" but got "close" -FAIL abort() should succeed despite rejection from write promise_test: Unhandled rejection with value: object "error1: error1" -FAIL abort() should be rejected with the rejection returned from close() assert_throws: abort() should reject with error2 function "function () { throw e }" threw object "error1: error1" ("error1") expected object "error2: error2" ("error2") -FAIL a rejecting sink.write() should not prevent sink.abort() from being called promise_test: Unhandled rejection with value: object "error1: error1" -FAIL when start errors after stream abort(), underlying sink abort() should be called anyway promise_test: Unhandled rejection with value: object "error1: error1" -PASS when calling abort() twice on the same stream, the second call should reject -PASS sink abort() should not be called if stream was erroring due to controller.error() before abort() was called -PASS sink abort() should not be called if stream was erroring due to bad strategy before abort() was called -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close-expected.txt deleted file mode 100644 index 400571f..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close-expected.txt +++ /dev/null
@@ -1,21 +0,0 @@ -This is a testharness.js-based test. -PASS fulfillment value of ws.close() call must be undefined even if the underlying sink returns a non-undefined value -FAIL when sink calls error asynchronously while sink close is in-flight, the stream should not become errored promise_test: Unhandled rejection with value: object "error1: error1" -FAIL when sink calls error synchronously while closing, the stream should not become errored promise_test: Unhandled rejection with value: object "Error: error me" -PASS when the sink throws during close, and the close is requested while a write is still in-flight, the stream should become errored during the close -PASS releaseLock on a stream with a pending write in which the stream has been errored -PASS releaseLock on a stream with a pending close in which controller.error() was called -PASS when close is called on a WritableStream in writable state, ready should return a fulfilled promise -PASS when close is called on a WritableStream in waiting state, ready promise should be fulfilled -PASS when close is called on a WritableStream in waiting state, ready should be fulfilled immediately even if close takes a long time -PASS returning a thenable from close() should work -PASS releaseLock() should not change the result of sync close() -PASS releaseLock() should not change the result of async close() -PASS close() should set state to CLOSED even if writer has detached -PASS the promise returned by async abort during close should resolve -PASS promises must fulfill/reject in the expected order on closure -FAIL promises must fulfill/reject in the expected order on aborted closure assert_array_equals: promises must fulfill/reject in the expected order property 1, expected "abortPromise" but got "closed" -FAIL promises must fulfill/reject in the expected order on aborted and errored closure assert_throws: writer.closed must reject with a TypeError indicating the stream was aborted function "function () { throw e }" threw object "error1: error1" ("error1") expected object "TypeError" ("TypeError") -FAIL close() should not reject until no sink methods are in flight assert_false: expected false got true -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.dedicatedworker-expected.txt deleted file mode 100644 index 400571f..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.dedicatedworker-expected.txt +++ /dev/null
@@ -1,21 +0,0 @@ -This is a testharness.js-based test. -PASS fulfillment value of ws.close() call must be undefined even if the underlying sink returns a non-undefined value -FAIL when sink calls error asynchronously while sink close is in-flight, the stream should not become errored promise_test: Unhandled rejection with value: object "error1: error1" -FAIL when sink calls error synchronously while closing, the stream should not become errored promise_test: Unhandled rejection with value: object "Error: error me" -PASS when the sink throws during close, and the close is requested while a write is still in-flight, the stream should become errored during the close -PASS releaseLock on a stream with a pending write in which the stream has been errored -PASS releaseLock on a stream with a pending close in which controller.error() was called -PASS when close is called on a WritableStream in writable state, ready should return a fulfilled promise -PASS when close is called on a WritableStream in waiting state, ready promise should be fulfilled -PASS when close is called on a WritableStream in waiting state, ready should be fulfilled immediately even if close takes a long time -PASS returning a thenable from close() should work -PASS releaseLock() should not change the result of sync close() -PASS releaseLock() should not change the result of async close() -PASS close() should set state to CLOSED even if writer has detached -PASS the promise returned by async abort during close should resolve -PASS promises must fulfill/reject in the expected order on closure -FAIL promises must fulfill/reject in the expected order on aborted closure assert_array_equals: promises must fulfill/reject in the expected order property 1, expected "abortPromise" but got "closed" -FAIL promises must fulfill/reject in the expected order on aborted and errored closure assert_throws: writer.closed must reject with a TypeError indicating the stream was aborted function "function () { throw e }" threw object "error1: error1" ("error1") expected object "TypeError" ("TypeError") -FAIL close() should not reject until no sink methods are in flight assert_false: expected false got true -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.serviceworker.https-expected.txt deleted file mode 100644 index f99ba6e..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.serviceworker.https-expected.txt +++ /dev/null
@@ -1,22 +0,0 @@ -This is a testharness.js-based test. -PASS Service worker test setup -PASS fulfillment value of ws.close() call must be undefined even if the underlying sink returns a non-undefined value -FAIL when sink calls error asynchronously while sink close is in-flight, the stream should not become errored promise_test: Unhandled rejection with value: object "error1: error1" -FAIL when sink calls error synchronously while closing, the stream should not become errored promise_test: Unhandled rejection with value: object "Error: error me" -PASS when the sink throws during close, and the close is requested while a write is still in-flight, the stream should become errored during the close -PASS releaseLock on a stream with a pending write in which the stream has been errored -PASS releaseLock on a stream with a pending close in which controller.error() was called -PASS when close is called on a WritableStream in writable state, ready should return a fulfilled promise -PASS when close is called on a WritableStream in waiting state, ready promise should be fulfilled -PASS when close is called on a WritableStream in waiting state, ready should be fulfilled immediately even if close takes a long time -PASS returning a thenable from close() should work -PASS releaseLock() should not change the result of sync close() -PASS releaseLock() should not change the result of async close() -PASS close() should set state to CLOSED even if writer has detached -PASS the promise returned by async abort during close should resolve -PASS promises must fulfill/reject in the expected order on closure -FAIL promises must fulfill/reject in the expected order on aborted closure assert_array_equals: promises must fulfill/reject in the expected order property 1, expected "abortPromise" but got "closed" -FAIL promises must fulfill/reject in the expected order on aborted and errored closure assert_throws: writer.closed must reject with a TypeError indicating the stream was aborted function "function () { throw e }" threw object "error1: error1" ("error1") expected object "TypeError" ("TypeError") -FAIL close() should not reject until no sink methods are in flight assert_false: expected false got true -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.sharedworker-expected.txt deleted file mode 100644 index 400571f..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/close.sharedworker-expected.txt +++ /dev/null
@@ -1,21 +0,0 @@ -This is a testharness.js-based test. -PASS fulfillment value of ws.close() call must be undefined even if the underlying sink returns a non-undefined value -FAIL when sink calls error asynchronously while sink close is in-flight, the stream should not become errored promise_test: Unhandled rejection with value: object "error1: error1" -FAIL when sink calls error synchronously while closing, the stream should not become errored promise_test: Unhandled rejection with value: object "Error: error me" -PASS when the sink throws during close, and the close is requested while a write is still in-flight, the stream should become errored during the close -PASS releaseLock on a stream with a pending write in which the stream has been errored -PASS releaseLock on a stream with a pending close in which controller.error() was called -PASS when close is called on a WritableStream in writable state, ready should return a fulfilled promise -PASS when close is called on a WritableStream in waiting state, ready promise should be fulfilled -PASS when close is called on a WritableStream in waiting state, ready should be fulfilled immediately even if close takes a long time -PASS returning a thenable from close() should work -PASS releaseLock() should not change the result of sync close() -PASS releaseLock() should not change the result of async close() -PASS close() should set state to CLOSED even if writer has detached -PASS the promise returned by async abort during close should resolve -PASS promises must fulfill/reject in the expected order on closure -FAIL promises must fulfill/reject in the expected order on aborted closure assert_array_equals: promises must fulfill/reject in the expected order property 1, expected "abortPromise" but got "closed" -FAIL promises must fulfill/reject in the expected order on aborted and errored closure assert_throws: writer.closed must reject with a TypeError indicating the stream was aborted function "function () { throw e }" threw object "error1: error1" ("error1") expected object "TypeError" ("TypeError") -FAIL close() should not reject until no sink methods are in flight assert_false: expected false got true -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor-expected.txt deleted file mode 100644 index 1998efd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -This is a testharness.js-based test. -PASS controller argument should be passed to start method -PASS controller argument should be passed to write method -FAIL controller argument should not be passed to close method assert_array_equals: no arguments should be passed to close lengths differ, expected 0 got 1 -PASS highWaterMark should be reflected to desiredSize -PASS WritableStream should be writable and ready should fulfill immediately if the strategy does not apply backpressure -PASS WritableStream should be constructible with no arguments -PASS WritableStream instances should have standard methods and properties -PASS private constructors should not be exported -PASS WritableStreamDefaultController constructor should throw unless passed a WritableStream -PASS WritableStreamDefaultController constructor should throw when passed an initialised WritableStream -PASS WritableStreamDefaultWriter should throw unless passed a WritableStream -PASS WritableStreamDefaultWriter constructor should throw when stream argument is locked -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.dedicatedworker-expected.txt deleted file mode 100644 index 1998efd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.dedicatedworker-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -This is a testharness.js-based test. -PASS controller argument should be passed to start method -PASS controller argument should be passed to write method -FAIL controller argument should not be passed to close method assert_array_equals: no arguments should be passed to close lengths differ, expected 0 got 1 -PASS highWaterMark should be reflected to desiredSize -PASS WritableStream should be writable and ready should fulfill immediately if the strategy does not apply backpressure -PASS WritableStream should be constructible with no arguments -PASS WritableStream instances should have standard methods and properties -PASS private constructors should not be exported -PASS WritableStreamDefaultController constructor should throw unless passed a WritableStream -PASS WritableStreamDefaultController constructor should throw when passed an initialised WritableStream -PASS WritableStreamDefaultWriter should throw unless passed a WritableStream -PASS WritableStreamDefaultWriter constructor should throw when stream argument is locked -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.serviceworker.https-expected.txt deleted file mode 100644 index d064d68..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.serviceworker.https-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -This is a testharness.js-based test. -PASS Service worker test setup -PASS controller argument should be passed to start method -PASS controller argument should be passed to write method -FAIL controller argument should not be passed to close method assert_array_equals: no arguments should be passed to close lengths differ, expected 0 got 1 -PASS highWaterMark should be reflected to desiredSize -PASS WritableStream should be writable and ready should fulfill immediately if the strategy does not apply backpressure -PASS WritableStream should be constructible with no arguments -PASS WritableStream instances should have standard methods and properties -PASS private constructors should not be exported -PASS WritableStreamDefaultController constructor should throw unless passed a WritableStream -PASS WritableStreamDefaultController constructor should throw when passed an initialised WritableStream -PASS WritableStreamDefaultWriter should throw unless passed a WritableStream -PASS WritableStreamDefaultWriter constructor should throw when stream argument is locked -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.sharedworker-expected.txt deleted file mode 100644 index 1998efd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/constructor.sharedworker-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -This is a testharness.js-based test. -PASS controller argument should be passed to start method -PASS controller argument should be passed to write method -FAIL controller argument should not be passed to close method assert_array_equals: no arguments should be passed to close lengths differ, expected 0 got 1 -PASS highWaterMark should be reflected to desiredSize -PASS WritableStream should be writable and ready should fulfill immediately if the strategy does not apply backpressure -PASS WritableStream should be constructible with no arguments -PASS WritableStream instances should have standard methods and properties -PASS private constructors should not be exported -PASS WritableStreamDefaultController constructor should throw unless passed a WritableStream -PASS WritableStreamDefaultController constructor should throw when passed an initialised WritableStream -PASS WritableStreamDefaultWriter should throw unless passed a WritableStream -PASS WritableStreamDefaultWriter constructor should throw when stream argument is locked -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error-expected.txt deleted file mode 100644 index e3bb1267..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS controller.error() should error the stream -PASS controller.error() on erroring stream should not throw -FAIL surplus calls to controller.error() should be a no-op Cannot error a errored writable stream -FAIL controller.error() on errored stream should not throw promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream" -FAIL controller.error() on closed stream should not throw promise_test: Unhandled rejection with value: object "TypeError: Cannot error a closed writable stream" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.dedicatedworker-expected.txt deleted file mode 100644 index e3bb1267..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.dedicatedworker-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS controller.error() should error the stream -PASS controller.error() on erroring stream should not throw -FAIL surplus calls to controller.error() should be a no-op Cannot error a errored writable stream -FAIL controller.error() on errored stream should not throw promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream" -FAIL controller.error() on closed stream should not throw promise_test: Unhandled rejection with value: object "TypeError: Cannot error a closed writable stream" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.serviceworker.https-expected.txt deleted file mode 100644 index 57815f8..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.serviceworker.https-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = error1 -PASS Service worker test setup -PASS controller.error() should error the stream -PASS controller.error() on erroring stream should not throw -FAIL surplus calls to controller.error() should be a no-op Cannot error a errored writable stream -FAIL controller.error() on errored stream should not throw promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream" -FAIL controller.error() on closed stream should not throw promise_test: Unhandled rejection with value: object "TypeError: Cannot error a closed writable stream" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.sharedworker-expected.txt deleted file mode 100644 index e3bb1267..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/error.sharedworker-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS controller.error() should error the stream -PASS controller.error() on erroring stream should not throw -FAIL surplus calls to controller.error() should be a no-op Cannot error a errored writable stream -FAIL controller.error() on errored stream should not throw promise_test: Unhandled rejection with value: object "TypeError: Cannot error a errored writable stream" -FAIL controller.error() on closed stream should not throw promise_test: Unhandled rejection with value: object "TypeError: Cannot error a closed writable stream" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties-expected.txt deleted file mode 100644 index 6fe9cca..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties-expected.txt +++ /dev/null
@@ -1,47 +0,0 @@ -This is a testharness.js-based test. -PASS WritableStreamDefaultController should not be exported on the global object -PASS WritableStreamDefaultWriter should not be exported on the global object -PASS WritableStream.prototype.constructor should have standard properties -PASS WritableStream.prototype.constructor should be a constructor -PASS WritableStream.prototype.locked should have standard properties -PASS WritableStream.prototype.locked should be a getter -PASS WritableStream.prototype.abort should have standard properties -PASS WritableStream.prototype.abort should be a method -PASS WritableStream.prototype.getWriter should have standard properties -PASS WritableStream.prototype.getWriter should be a method -PASS WritableStream.prototype should have exactly the expected properties -PASS WritableStreamDefaultController.prototype.constructor should have standard properties -PASS WritableStreamDefaultController.prototype.constructor should be a constructor -PASS WritableStreamDefaultController.prototype.error should have standard properties -PASS WritableStreamDefaultController.prototype.error should be a method -PASS WritableStreamDefaultController.prototype should have exactly the expected properties -PASS WritableStreamDefaultWriter.prototype.constructor should have standard properties -PASS WritableStreamDefaultWriter.prototype.constructor should be a constructor -PASS WritableStreamDefaultWriter.prototype.closed should have standard properties -PASS WritableStreamDefaultWriter.prototype.closed should be a getter -PASS WritableStreamDefaultWriter.prototype.desiredSize should have standard properties -PASS WritableStreamDefaultWriter.prototype.desiredSize should be a getter -PASS WritableStreamDefaultWriter.prototype.ready should have standard properties -PASS WritableStreamDefaultWriter.prototype.ready should be a getter -PASS WritableStreamDefaultWriter.prototype.abort should have standard properties -PASS WritableStreamDefaultWriter.prototype.abort should be a method -PASS WritableStreamDefaultWriter.prototype.close should have standard properties -PASS WritableStreamDefaultWriter.prototype.close should be a method -PASS WritableStreamDefaultWriter.prototype.releaseLock should have standard properties -PASS WritableStreamDefaultWriter.prototype.releaseLock should be a method -PASS WritableStreamDefaultWriter.prototype.write should have standard properties -PASS WritableStreamDefaultWriter.prototype.write should be a method -PASS WritableStreamDefaultWriter.prototype should have exactly the expected properties -PASS sink method start should be called with the right number of arguments -PASS sink method start should be called even when it's located on the prototype chain -PASS sink method write should be called with the right number of arguments -PASS sink method write should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method write -FAIL sink method close should be called with the right number of arguments assert_equals: close should be called with 0 arguments expected 0 but got 1 -PASS sink method close should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method close -PASS sink method abort should be called with the right number of arguments -PASS sink method abort should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method abort -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.dedicatedworker-expected.txt deleted file mode 100644 index 6fe9cca..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.dedicatedworker-expected.txt +++ /dev/null
@@ -1,47 +0,0 @@ -This is a testharness.js-based test. -PASS WritableStreamDefaultController should not be exported on the global object -PASS WritableStreamDefaultWriter should not be exported on the global object -PASS WritableStream.prototype.constructor should have standard properties -PASS WritableStream.prototype.constructor should be a constructor -PASS WritableStream.prototype.locked should have standard properties -PASS WritableStream.prototype.locked should be a getter -PASS WritableStream.prototype.abort should have standard properties -PASS WritableStream.prototype.abort should be a method -PASS WritableStream.prototype.getWriter should have standard properties -PASS WritableStream.prototype.getWriter should be a method -PASS WritableStream.prototype should have exactly the expected properties -PASS WritableStreamDefaultController.prototype.constructor should have standard properties -PASS WritableStreamDefaultController.prototype.constructor should be a constructor -PASS WritableStreamDefaultController.prototype.error should have standard properties -PASS WritableStreamDefaultController.prototype.error should be a method -PASS WritableStreamDefaultController.prototype should have exactly the expected properties -PASS WritableStreamDefaultWriter.prototype.constructor should have standard properties -PASS WritableStreamDefaultWriter.prototype.constructor should be a constructor -PASS WritableStreamDefaultWriter.prototype.closed should have standard properties -PASS WritableStreamDefaultWriter.prototype.closed should be a getter -PASS WritableStreamDefaultWriter.prototype.desiredSize should have standard properties -PASS WritableStreamDefaultWriter.prototype.desiredSize should be a getter -PASS WritableStreamDefaultWriter.prototype.ready should have standard properties -PASS WritableStreamDefaultWriter.prototype.ready should be a getter -PASS WritableStreamDefaultWriter.prototype.abort should have standard properties -PASS WritableStreamDefaultWriter.prototype.abort should be a method -PASS WritableStreamDefaultWriter.prototype.close should have standard properties -PASS WritableStreamDefaultWriter.prototype.close should be a method -PASS WritableStreamDefaultWriter.prototype.releaseLock should have standard properties -PASS WritableStreamDefaultWriter.prototype.releaseLock should be a method -PASS WritableStreamDefaultWriter.prototype.write should have standard properties -PASS WritableStreamDefaultWriter.prototype.write should be a method -PASS WritableStreamDefaultWriter.prototype should have exactly the expected properties -PASS sink method start should be called with the right number of arguments -PASS sink method start should be called even when it's located on the prototype chain -PASS sink method write should be called with the right number of arguments -PASS sink method write should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method write -FAIL sink method close should be called with the right number of arguments assert_equals: close should be called with 0 arguments expected 0 but got 1 -PASS sink method close should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method close -PASS sink method abort should be called with the right number of arguments -PASS sink method abort should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method abort -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.serviceworker.https-expected.txt deleted file mode 100644 index ad8c37c802..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.serviceworker.https-expected.txt +++ /dev/null
@@ -1,48 +0,0 @@ -This is a testharness.js-based test. -PASS Service worker test setup -PASS WritableStreamDefaultController should not be exported on the global object -PASS WritableStreamDefaultWriter should not be exported on the global object -PASS WritableStream.prototype.constructor should have standard properties -PASS WritableStream.prototype.constructor should be a constructor -PASS WritableStream.prototype.locked should have standard properties -PASS WritableStream.prototype.locked should be a getter -PASS WritableStream.prototype.abort should have standard properties -PASS WritableStream.prototype.abort should be a method -PASS WritableStream.prototype.getWriter should have standard properties -PASS WritableStream.prototype.getWriter should be a method -PASS WritableStream.prototype should have exactly the expected properties -PASS WritableStreamDefaultController.prototype.constructor should have standard properties -PASS WritableStreamDefaultController.prototype.constructor should be a constructor -PASS WritableStreamDefaultController.prototype.error should have standard properties -PASS WritableStreamDefaultController.prototype.error should be a method -PASS WritableStreamDefaultController.prototype should have exactly the expected properties -PASS WritableStreamDefaultWriter.prototype.constructor should have standard properties -PASS WritableStreamDefaultWriter.prototype.constructor should be a constructor -PASS WritableStreamDefaultWriter.prototype.closed should have standard properties -PASS WritableStreamDefaultWriter.prototype.closed should be a getter -PASS WritableStreamDefaultWriter.prototype.desiredSize should have standard properties -PASS WritableStreamDefaultWriter.prototype.desiredSize should be a getter -PASS WritableStreamDefaultWriter.prototype.ready should have standard properties -PASS WritableStreamDefaultWriter.prototype.ready should be a getter -PASS WritableStreamDefaultWriter.prototype.abort should have standard properties -PASS WritableStreamDefaultWriter.prototype.abort should be a method -PASS WritableStreamDefaultWriter.prototype.close should have standard properties -PASS WritableStreamDefaultWriter.prototype.close should be a method -PASS WritableStreamDefaultWriter.prototype.releaseLock should have standard properties -PASS WritableStreamDefaultWriter.prototype.releaseLock should be a method -PASS WritableStreamDefaultWriter.prototype.write should have standard properties -PASS WritableStreamDefaultWriter.prototype.write should be a method -PASS WritableStreamDefaultWriter.prototype should have exactly the expected properties -PASS sink method start should be called with the right number of arguments -PASS sink method start should be called even when it's located on the prototype chain -PASS sink method write should be called with the right number of arguments -PASS sink method write should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method write -FAIL sink method close should be called with the right number of arguments assert_equals: close should be called with 0 arguments expected 0 but got 1 -PASS sink method close should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method close -PASS sink method abort should be called with the right number of arguments -PASS sink method abort should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method abort -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.sharedworker-expected.txt deleted file mode 100644 index 6fe9cca..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/properties.sharedworker-expected.txt +++ /dev/null
@@ -1,47 +0,0 @@ -This is a testharness.js-based test. -PASS WritableStreamDefaultController should not be exported on the global object -PASS WritableStreamDefaultWriter should not be exported on the global object -PASS WritableStream.prototype.constructor should have standard properties -PASS WritableStream.prototype.constructor should be a constructor -PASS WritableStream.prototype.locked should have standard properties -PASS WritableStream.prototype.locked should be a getter -PASS WritableStream.prototype.abort should have standard properties -PASS WritableStream.prototype.abort should be a method -PASS WritableStream.prototype.getWriter should have standard properties -PASS WritableStream.prototype.getWriter should be a method -PASS WritableStream.prototype should have exactly the expected properties -PASS WritableStreamDefaultController.prototype.constructor should have standard properties -PASS WritableStreamDefaultController.prototype.constructor should be a constructor -PASS WritableStreamDefaultController.prototype.error should have standard properties -PASS WritableStreamDefaultController.prototype.error should be a method -PASS WritableStreamDefaultController.prototype should have exactly the expected properties -PASS WritableStreamDefaultWriter.prototype.constructor should have standard properties -PASS WritableStreamDefaultWriter.prototype.constructor should be a constructor -PASS WritableStreamDefaultWriter.prototype.closed should have standard properties -PASS WritableStreamDefaultWriter.prototype.closed should be a getter -PASS WritableStreamDefaultWriter.prototype.desiredSize should have standard properties -PASS WritableStreamDefaultWriter.prototype.desiredSize should be a getter -PASS WritableStreamDefaultWriter.prototype.ready should have standard properties -PASS WritableStreamDefaultWriter.prototype.ready should be a getter -PASS WritableStreamDefaultWriter.prototype.abort should have standard properties -PASS WritableStreamDefaultWriter.prototype.abort should be a method -PASS WritableStreamDefaultWriter.prototype.close should have standard properties -PASS WritableStreamDefaultWriter.prototype.close should be a method -PASS WritableStreamDefaultWriter.prototype.releaseLock should have standard properties -PASS WritableStreamDefaultWriter.prototype.releaseLock should be a method -PASS WritableStreamDefaultWriter.prototype.write should have standard properties -PASS WritableStreamDefaultWriter.prototype.write should be a method -PASS WritableStreamDefaultWriter.prototype should have exactly the expected properties -PASS sink method start should be called with the right number of arguments -PASS sink method start should be called even when it's located on the prototype chain -PASS sink method write should be called with the right number of arguments -PASS sink method write should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method write -FAIL sink method close should be called with the right number of arguments assert_equals: close should be called with 0 arguments expected 0 but got 1 -PASS sink method close should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method close -PASS sink method abort should be called with the right number of arguments -PASS sink method abort should be called even when it's located on the prototype chain -PASS unexpected properties should not be accessed when calling sink method abort -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-dynamic-expected.html b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-dynamic-expected.html new file mode 100644 index 0000000..6f12503 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-dynamic-expected.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<style> +#target { + text-decoration: underline; + text-underline-position: under; +} +</style> +<p id=target>This text should have under-positioned underline.</p>
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-dynamic.html b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-dynamic.html new file mode 100644 index 0000000..246db46 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-dynamic.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<style> +#target { + text-decoration: underline; +} +</style> +<p id=target>This text should have under-positioned underline.</p> +<script> +if (window.testRunner) + testRunner.waitUntilDone(); +window.onload = function () { + document.body.offsetTop; /* force layout */ + /* Theoretically setting style can reproduce the issue, but neither setting + immediately nor requestAnimationFrame() work, so use setTimeout(). */ + setTimeout(function () { + target.style.textUnderlinePosition = 'under'; + if (window.testRunner) + testRunner.notifyDone(); + }, 10); +}; +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-cell-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-cell-collapsed-border.html index fbe7a8cc..64900e5 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-cell-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-cell-collapsed-border.html
@@ -5,6 +5,7 @@ <link rel="prev" href="backgr_border-table-column.html" title="Background with Borders: Background on 'table-column'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {border: 5px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-cell.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-cell.html index 0ee2e37..63d6419 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-cell.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-cell.html
@@ -5,6 +5,7 @@ <link rel="prev" href="backgr_border-table-column.html" title="Background with Borders: Background on 'table-column'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {border: 5px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-collapsed-border.html index c97ed35..52cc1b5 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-collapsed-border.html
@@ -5,6 +5,7 @@ <link rel="prev" href="backgr_layers-opacity.html" title="Background with Borders: Background on 'table-cell'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: black url(resources/edge.gif) top left no-repeat; border: 5px dotted;}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-collapsed-border.html index 64d24b9..1e66a2ae 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_border-table-row.html" title="Background with Borders: Background on 'table-row'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table { border: 3px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group-collapsed-border.html index c475b0f5..0c236e95 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_border-table-row-group.html" title="Background with Borders: Background on 'table-row-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table { border: 3px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group.html index 197218f99..008221f 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_border-table-row-group.html" title="Background with Borders: Background on 'table-row-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table { border: 3px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column.html index 6f5456d..65756145 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_border-table-row.html" title="Background with Borders: Background on 'table-row'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table { border: 3px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-quirks-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-quirks-collapsed-border.html index 2ea144c0..942e083 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-quirks-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-quirks-collapsed-border.html
@@ -5,6 +5,7 @@ <link rel="prev" href="layers-opacity.html" title="Background with Borders: Background on 'table-cell'"> <link rel="contents" href="./" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: black url(edge.gif) top left no-repeat; border: 5px dotted;}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-quirks.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-quirks.html index 5f9b360..595c55d 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-quirks.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-quirks.html
@@ -5,6 +5,7 @@ <link rel="prev" href="layers-opacity.html" title="Background with Borders: Background on 'table-cell'"> <link rel="contents" href="./" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: black url(edge.gif) top left no-repeat; border: 5px dotted;}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-collapsed-border.html index a6c39978..c307b316 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_border-table-column-group.html" title="Background with Borders: Background on 'table-column-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table { border: 3px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group-collapsed-border.html index 5ec3c8b..5a59da7 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_border-table.html" title="Background with Borders: Background on 'table'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table { border: 3px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group.html index f779070d..adf875d1 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_border-table.html" title="Background with Borders: Background on 'table'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table { border: 3px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row.html index c75e9c6..c37a0f9d 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_border-table-column-group.html" title="Background with Borders: Background on 'table-column-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table { border: 3px dotted}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table.html b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table.html index e2610baf..8d0bc94 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_border-table.html
@@ -5,6 +5,7 @@ <link rel="prev" href="backgr_layers-opacity.html" title="Background with Borders: Background on 'table-cell'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: black url(resources/edge.gif) top left no-repeat; border: 5px dotted;}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_image-crash.html b/third_party/WebKit/LayoutTests/fast/table/backgr_image-crash.html index 3ac79a57..b346905 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_image-crash.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_image-crash.html
@@ -3,6 +3,7 @@ <table id="table"> <colgroup style="background: url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7)"> </table> +<script src="resources/wait-for-onload.js"></script> <script> if (window.testRunner) testRunner.dumpAsText();
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-collapsed-border.html index 45f7acb4..e59c17f6 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_layers-show.html" title="Background Layers: empty-cell: show"> <link rel="contents" href="./backgr_indxe.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: blue; empty-cells: hide} tbody, thead {background: url(resources/edge.gif) right top no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide.html b/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide.html index 26392dcd..8ab8df7 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_layers-show.html" title="Background Layers: empty-cell: show"> <link rel="contents" href="./backgr_indxe.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: blue; empty-cells: hide} tbody, thead {background: url(resources/edge.gif) right top no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-show-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_layers-show-collapsed-border.html index 388a598..f70e857 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-show-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_layers-show-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-cell.html" title="Background Position: Background on 'table-cell'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: blue; empty-cells: show} tbody, thead {background: url(../images/edge.gif) right top no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-show.html b/third_party/WebKit/LayoutTests/fast/table/backgr_layers-show.html index 2d1abd88..db9a015 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-show.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_layers-show.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-cell.html" title="Background Position: Background on 'table-cell'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: blue; empty-cells: show} tbody, thead {background: url(../images/edge.gif) right top no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-cell-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-cell-collapsed-border.html index f08cd8a..a68c6a8 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-cell-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-cell-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-column.html" title="Background Position: Background on 'table-column'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> .e {background: black url(resources/edge.gif) top left no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-cell.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-cell.html index 17c9292..6321524 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-cell.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-cell.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-column.html" title="Background Position: Background on 'table-column'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> .e {background: black url(resources/edge.gif) top left no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-collapsed-border.html index 0b0f9273..1620090 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-cell.html" title="Background Position: Background on 'table-cell'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: black url(resources/edge.gif) top right no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-collapsed-border.html index 3d79787..8cd8870 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-row.html" title="Background Position: Background on 'table-row'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> .col-1 {background: black url(resources/edge.gif) bottom right no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group-collapsed-border.html index 453e34b1..ec4d490d 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-row-group.html" title="Background Position: Background on 'table-row-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> .colgroup-A {background: black url(resources/edge.gif) bottom right no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group.html index f4b614fd1..4a52735 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-row-group.html" title="Background Position: Background on 'table-row-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> .colgroup-A {background: black url(resources/edge.gif) bottom right no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column.html index ca61357..ee474f7 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-row.html" title="Background Position: Background on 'table-row'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> .col-1 {background: black url(resources/edge.gif) bottom right no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-collapsed-border.html index a4a3dea..251c89ac 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-column-group.html" title="Background Position: Background on 'table-column-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> .th-row-1 {background: black url(resources/edge.gif) bottom right no-repeat;}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group-collapsed-border.html index 08c0b318..218c71c0 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table.html" title="Background Position: Background on 'table'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> thead {background: black url(resources/edge.gif) top right no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group.html index 990b15e9..0ffcd4d 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table.html" title="Background Position: Background on 'table'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> thead {background: black url(resources/edge.gif) top right no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row.html index 62d9cc6..3b2625f 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-column-group.html" title="Background Position: Background on 'table-column-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> .th-row-1 {background: black url(resources/edge.gif) bottom right no-repeat;}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table.html b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table.html index 7156564..c20dfbfb 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_position-table.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_position-table-cell.html" title="Background Position: Background on 'table-cell'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: black url(resources/edge.gif) top right no-repeat}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-cell-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-cell-collapsed-border.html index 71151bf4..478dde7 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-cell-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-cell-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="next" href="backgr_position-table.html" title="Background Position: Background on 'table'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> td,th {background: black url(resources/rainbowv.gif) top right}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-cell.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-cell.html index 6740910..d712ee9 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-cell.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-cell.html
@@ -6,6 +6,7 @@ <link rel="next" href="backgr_position-table.html" title="Background Position: Background on 'table'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> td,th {background: black url(resources/rainbowv.gif) top right}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-collapsed-border.html index b743e50..5103e1a0 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-collapsed-border.html
@@ -5,6 +5,7 @@ <link rel="next" href="backgr_simple-table-row-group.html" title="Background Area: Background on 'table-row-group'"> <link rel="prev contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: black url(resources/rainbowh.gif) top right}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-collapsed-border.html index d9fd912..4585c55 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_simple-table-row.html" title="Background Area: Background on 'table-row'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> col {background: black url(resources/rainbowv.gif) top right}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group-collapsed-border.html index 5ac4187..cb5700f5 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_simple-table-row-group.html" title="Background Area: Background on 'table-row-group'"> <link rel="contents" href="./backgr_index,.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> colgroup {background: black url(resources/rainbowv.gif) top left}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group.html index 73634d9..646d956 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_simple-table-row-group.html" title="Background Area: Background on 'table-row-group'"> <link rel="contents" href="./backgr_index,.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> colgroup {background: black url(resources/rainbowv.gif) top left}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column.html index d1979d3..7ced06d 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_simple-table-row.html" title="Background Area: Background on 'table-row'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> col {background: black url(resources/rainbowv.gif) top right}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-collapsed-border.html index 2d90cf8..c5fe415 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_simple-table-column-group.html" title="Background Area: Background on 'table-column-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> tr {background: black url(resources/rainbowh.gif) bottom left;}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group-collapsed-border.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group-collapsed-border.html index 873e4a1..2ff4ee9 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group-collapsed-border.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group-collapsed-border.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_simple-table.html" title="Background Area: Background on 'table'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> tbody {background: black url(resources/rainbowh.gif) bottom left}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group.html index 6f9fd4c..88e901a 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_simple-table.html" title="Background Area: Background on 'table'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> tbody {background: black url(resources/rainbowh.gif) bottom left}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row.html index 4750803..571b5030 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row.html
@@ -6,6 +6,7 @@ <link rel="prev" href="backgr_simple-table-column-group.html" title="Background Area: Background on 'table-column-group'"> <link rel="contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> tr {background: black url(resources/rainbowh.gif) bottom left;}
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table.html b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table.html index 0ecfbfe..0bf8609 100644 --- a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table.html +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table.html
@@ -5,6 +5,7 @@ <link rel="next" href="backgr_simple-table-row-group.html" title="Background Area: Background on 'table-row-group'"> <link rel="prev contents" href="./backgr_index.html" title="Table of Contents"> <link rel="stylesheet" type="text/css" href="resources/common.css"> +<script src="resources/wait-for-onload.js"></script> <style type="text/css"> table {background: black url(resources/rainbowh.gif) top right}
diff --git a/third_party/WebKit/LayoutTests/fast/table/resources/wait-for-onload.js b/third_party/WebKit/LayoutTests/fast/table/resources/wait-for-onload.js new file mode 100644 index 0000000..4afdabc1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/table/resources/wait-for-onload.js
@@ -0,0 +1,15 @@ +if (window.testRunner) { + // This is a workaroud for an issue that the test runner sends notifyDone + // before resources specified in CSS url finish loading. Currently all + // such resources are specified in inline CSSs so we can rely on the + // Document load event (Note that we cannot rely on that with linked + // CSSs). + testRunner.waitUntilDone(); + window.addEventListener('load', () => { + // Force layout. + document.body.offsetTop; + + testRunner.notifyDone(); + }); +} +
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/resources/thorough-util.js b/third_party/WebKit/LayoutTests/http/tests/fetch/resources/thorough-util.js index 6fb0899..053c7c2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/fetch/resources/thorough-util.js +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/resources/thorough-util.js
@@ -166,7 +166,7 @@ checkJsonpHeader.bind(this, 'X-ServiceWorker-Test', 'test'); var hasCustomHeader2 = function(url, data) { checkJsonpHeader('X-ServiceWorker-s', 'test1', url, data); - checkJsonpHeader('X-ServiceWorker-Test', 'test2,test3', url, data); + checkJsonpHeader('X-ServiceWorker-Test', 'test2, test3', url, data); checkJsonpHeader('X-ServiceWorker-ua', 'test4', url, data); checkJsonpHeader('X-ServiceWorker-U', 'test5', url, data); checkJsonpHeader('X-ServiceWorker-V', 'test6', url, data);
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/headers.js b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/headers.js index 7c36bb3..babfaf7c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/headers.js +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/headers.js
@@ -136,7 +136,7 @@ headers.append('X-FETCH-TEST-2', 'response test field - append'); assert_equals(size(headers), 5, 'headers size should increase by 1.'); assert_equals(headers.get('X-FETCH-Test'), - 'response test field - updated,response test field - append', + 'response test field - updated, response test field - append', 'the value of the first header added should be returned.'); allValues = headers.getAll('X-FETch-TEST'); assert_equals(allValues.length, 2); @@ -156,7 +156,7 @@ headers = new Headers([['a', 'b'], ['c', 'd'], ['c', 'e']]); assert_equals(size(headers), 2, 'headers size should match'); assert_equals(headers.get('a'), 'b'); - assert_equals(headers.get('c'), 'd,e'); + assert_equals(headers.get('c'), 'd, e'); assert_equals(headers.getAll('c')[0], 'd'); assert_equals(headers.getAll('c')[1], 'e'); @@ -164,7 +164,7 @@ var headers2 = new Headers(headers); assert_equals(size(headers2), 2, 'headers size should match'); assert_equals(headers2.get('a'), 'b'); - assert_equals(headers2.get('c'), 'd,e'); + assert_equals(headers2.get('c'), 'd, e'); assert_equals(headers2.getAll('c')[0], 'd'); assert_equals(headers2.getAll('c')[1], 'e'); headers.set('a', 'x'); @@ -175,14 +175,14 @@ headers3.append('test', 'a'); headers3.append('test', ''); headers3.append('test', 'b'); - assert_equals(headers3.get('test'), 'a,,b'); + assert_equals(headers3.get('test'), 'a, , b'); headers3.set('test', ''); assert_equals(headers3.get('test'), ''); var headers4 = new Headers(); headers4.append('foo', ''); headers4.append('foo', 'a'); - assert_equals(headers4.get('foo'), ',a'); + assert_equals(headers4.get('foo'), ', a'); // new Headers with Dictionary headers = new Headers({'a': 'b', 'c': 'd'}); assert_equals(size(headers), 2, 'headers size should match'); @@ -269,7 +269,7 @@ assert_array_equals(keys, ['a', 'b', 'c'], 'The pairs to iterate over should be the return ' + 'value of an algorithm that implicitly makes a copy.'); - assert_array_equals(values, ['1,2,3', '2', '3'], + assert_array_equals(values, ['1, 2, 3', '2', '3'], "The values should be combined and separated by ','."); }, 'Iteration mutation');
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https-expected.txt b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https-expected.txt deleted file mode 100644 index abdd077..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https-expected.txt +++ /dev/null
@@ -1,25 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = 5 duplicate test names: "Piping from an errored readable stream to an errored writable stream", "Piping from an errored readable stream to an errored writable stream; preventAbort = true", "Piping from an errored readable stream to a closed writable stream", "Piping from a closed readable stream to an errored writable stream", "Piping from a closed readable stream to a closed writable stream" -PASS Piping from an errored readable stream to an errored writable stream -PASS Piping from an errored readable stream to an errored writable stream; preventAbort = true -PASS Piping from an errored readable stream to a closed writable stream -PASS Piping from a closed readable stream to an errored writable stream -PASS Piping from a closed readable stream to a closed writable stream -PASS Untitled -PASS Piping from an errored readable stream to an errored writable stream -PASS Piping from an errored readable stream to an errored writable stream; preventAbort = true -PASS Piping from an errored readable stream to a closed writable stream -PASS Piping from a closed readable stream to an errored writable stream -PASS Piping from a closed readable stream to a closed writable stream -PASS Piping from an errored readable stream to an errored writable stream -PASS Piping from an errored readable stream to an errored writable stream; preventAbort = true -PASS Piping from an errored readable stream to a closed writable stream -PASS Piping from a closed readable stream to an errored writable stream -PASS Piping from a closed readable stream to a closed writable stream -PASS Piping from an errored readable stream to an errored writable stream -PASS Piping from an errored readable stream to an errored writable stream; preventAbort = true -PASS Piping from an errored readable stream to a closed writable stream -PASS Piping from a closed readable stream to an errored writable stream -PASS Piping from a closed readable stream to a closed writable stream -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https.html b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https.html deleted file mode 100644 index c7951db8..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/serviceworker/resources/test-helpers.js"></script> -<script src="../resources/test-initializer.js"></script> -<script src="../resources/test-utils.js"></script> -<script src="../resources/recording-streams.js"></script> - -<script src="multiple-propagation.js"></script> -<script> -'use strict'; -worker_test('multiple-propagation.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.js b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.js deleted file mode 100644 index 2c7fd141..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.js +++ /dev/null
@@ -1,139 +0,0 @@ -'use strict'; - -if (self.importScripts) { - self.importScripts('/resources/testharness.js'); - self.importScripts('../resources/test-utils.js'); - self.importScripts('../resources/recording-streams.js'); -} - -const error1 = new Error('error1!'); -error1.name = 'error1'; - -const error2 = new Error('error2!'); -error2.name = 'error2'; - -promise_test(t => { - const rs = recordingReadableStream({ - start(c) { - c.error(error1); - } - }); - const ws = recordingWritableStream({ - start(c) { - c.error(error2); - } - }); - - // Trying to abort a stream that was errored will give that error back - return promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the writable stream\'s error').then(() => { - assert_array_equals(rs.events, []); - assert_array_equals(ws.events, []); - - return Promise.all([ - promise_rejects(t, error1, rs.getReader().closed, 'the readable stream must be errored with error1'), - promise_rejects(t, error2, ws.getWriter().closed, 'the writable stream must be errored with error2') - ]); - }); - -}, 'Piping from an errored readable stream to an errored writable stream'); - -promise_test(t => { - const rs = recordingReadableStream({ - start(c) { - c.error(error1); - } - }); - const ws = recordingWritableStream({ - start(c) { - c.error(error2); - } - }); - - return promise_rejects(t, error1, rs.pipeTo(ws, { preventAbort: true }), - 'pipeTo must reject with the readable stream\'s error') - .then(() => { - assert_array_equals(rs.events, []); - assert_array_equals(ws.events, []); - - return Promise.all([ - promise_rejects(t, error1, rs.getReader().closed, 'the readable stream must be errored with error1'), - promise_rejects(t, error2, ws.getWriter().closed, 'the writable stream must be errored with error2') - ]); - }); - -}, 'Piping from an errored readable stream to an errored writable stream; preventAbort = true'); - -// TODO(ricea): Revert to the upstream version of this test once https://github.com/whatwg/streams/pull/634 is -// resolved and WritableStream.js has been updated to match. -promise_test(t => { - const rs = recordingReadableStream({ - start(c) { - c.error(error1); - } - }); - const ws = recordingWritableStream(); - const writer = ws.getWriter(); - const closePromise = writer.close(); - writer.releaseLock(); - - return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the readable stream\'s error').then(() => { - assert_array_equals(rs.events, []); - assert_array_equals(ws.events, ['abort', error1], 'ws.events should contain abort for the time being'); - - return Promise.all([ - promise_rejects(t, error1, rs.getReader().closed, 'the readable stream must be errored with error1'), - promise_rejects(t, new TypeError(), ws.getWriter().closed, 'the writable stream should be errored for the time being'), - promise_rejects(t, new TypeError(), closePromise, 'close() should reject for the time being') - ]); - }); - -}, 'Piping from an errored readable stream to a closed writable stream'); - -promise_test(t => { - const rs = recordingReadableStream({ - start(c) { - c.close(); - } - }); - const ws = recordingWritableStream({ - start(c) { - c.error(error1); - } - }); - - return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the writable stream\'s error').then(() => { - assert_array_equals(rs.events, []); - assert_array_equals(ws.events, []); - - return Promise.all([ - rs.getReader().closed, - promise_rejects(t, error1, ws.getWriter().closed, 'the writable stream must be errored with error1') - ]); - }); - -}, 'Piping from a closed readable stream to an errored writable stream'); - -promise_test(() => { - const rs = recordingReadableStream({ - start(c) { - c.close(); - } - }); - const ws = recordingWritableStream(); - const writer = ws.getWriter(); - writer.close(); - writer.releaseLock(); - - return rs.pipeTo(ws).then(() => { - assert_array_equals(rs.events, []); - assert_array_equals(ws.events, ['close']); - - return Promise.all([ - rs.getReader().closed, - ws.getWriter().closed - ]); - }); - -}, 'Piping from a closed readable stream to a closed writable stream'); - -done();
diff --git a/third_party/WebKit/LayoutTests/transforms/combine-transforms-properties-motion-path.html b/third_party/WebKit/LayoutTests/transforms/combine-transforms-properties-motion-path.html index 2b1615b..9b007b6 100644 --- a/third_party/WebKit/LayoutTests/transforms/combine-transforms-properties-motion-path.html +++ b/third_party/WebKit/LayoutTests/transforms/combine-transforms-properties-motion-path.html
@@ -14,7 +14,7 @@ translate: 200px 10px; rotate: 90deg; scale: 1 2; - motion: path("m 0 0 v -20 h 20") 0rad 100%; + offset: path("m 0 0 v -20 h 20") 100% 0rad; } #expected { background-color: green;
diff --git a/third_party/WebKit/LayoutTests/usb/resources/webusb-test.js b/third_party/WebKit/LayoutTests/usb/resources/webusb-test.js index 112a780..f20c71a 100644 --- a/third_party/WebKit/LayoutTests/usb/resources/webusb-test.js +++ b/third_party/WebKit/LayoutTests/usb/resources/webusb-test.js
@@ -136,13 +136,13 @@ } switch (endpoint.type) { case "bulk": - endpointInfo.type = mojo.device.UsbEndpointType.BULK; + endpointInfo.type = mojo.device.UsbTransferType.BULK; break; case "interrupt": - endpointInfo.type = mojo.device.UsbEndpointType.INTERRUPT; + endpointInfo.type = mojo.device.UsbTransferType.INTERRUPT; break; case "isochronous": - endpointInfo.type = mojo.device.UsbEndpointType.ISOCHRONOUS; + endpointInfo.type = mojo.device.UsbTransferType.ISOCHRONOUS; break; } alternateInfo.endpoints.push(endpointInfo);
diff --git a/third_party/WebKit/LayoutTests/virtual/mojo-loading/fast/table/README.txt b/third_party/WebKit/LayoutTests/virtual/mojo-loading/fast/table/README.txt new file mode 100644 index 0000000..9444a6b --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/mojo-loading/fast/table/README.txt
@@ -0,0 +1,4 @@ +This directory is for testing loading with mojo. + +This directory was added because fast/table tests once relied on a unspecified +timing and were broken with mojo-loading.
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt index b607b33..3813f6b 100644 --- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
@@ -14,6 +14,37 @@ getter y getter z method constructor +interface AccessibleNode + attribute @@toStringTag + getter autocomplete + getter checked + getter current + getter invalid + getter keyShortcuts + getter label + getter live + getter orientation + getter placeholder + getter relevant + getter role + getter roleDescription + getter sort + getter valueText + method constructor + setter autocomplete + setter checked + setter current + setter invalid + setter keyShortcuts + setter label + setter live + setter orientation + setter placeholder + setter relevant + setter role + setter roleDescription + setter sort + setter valueText interface AmbientLightSensor : Sensor attribute @@toStringTag getter illuminance @@ -1682,6 +1713,7 @@ interface Element : Node attribute @@toStringTag attribute @@unscopables + getter accessibleNode getter assignedSlot getter attributes getter childElementCount
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt index 5512948f..70a32387 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
@@ -192,7 +192,6 @@ minWidth minZoom mixBlendMode -motion objectFit objectPosition offset
diff --git a/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt index c8f4570..a9d3112 100644 --- a/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt
@@ -198,7 +198,6 @@ minWidth minZoom mixBlendMode -motion objectFit objectPosition offset
diff --git a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt index 9f75dde..bb77da6 100644 --- a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
@@ -25,6 +25,7 @@ property PROCESSING_INSTRUCTION_NODE property TEXT_NODE property accessKey + property accessibleNode property addEventListener property after property animate @@ -1125,6 +1126,7 @@ property PROCESSING_INSTRUCTION_NODE property TEXT_NODE property accessKey + property accessibleNode property addEventListener property after property animate
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index dc45ff62d..32079e5 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -14,6 +14,37 @@ getter y getter z method constructor +interface AccessibleNode + attribute @@toStringTag + getter autocomplete + getter checked + getter current + getter invalid + getter keyShortcuts + getter label + getter live + getter orientation + getter placeholder + getter relevant + getter role + getter roleDescription + getter sort + getter valueText + method constructor + setter autocomplete + setter checked + setter current + setter invalid + setter keyShortcuts + setter label + setter live + setter orientation + setter placeholder + setter relevant + setter role + setter roleDescription + setter sort + setter valueText interface AmbientLightSensor : Sensor attribute @@toStringTag getter illuminance @@ -1682,6 +1713,7 @@ interface Element : Node attribute @@toStringTag attribute @@unscopables + getter accessibleNode getter assignedSlot getter attributes getter childElementCount
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.h b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.h index 2390472594..81c2f92 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.h
@@ -72,10 +72,6 @@ void SuppressStreaming(); bool StreamingSuppressed() const { return streaming_suppressed_; } - v8::ScriptCompiler::CompileOptions GetCompileOptions() const { - return compile_options_; - } - // Called by PendingScript when data arrives from the network. void NotifyAppendData(ScriptResource*); void NotifyFinished(Resource*); @@ -84,10 +80,6 @@ // has processed it. void StreamingCompleteOnBackgroundThread(); - v8::ScriptCompiler::StreamedSource::Encoding GetEncoding() const { - return encoding_; - } - const String& ScriptURLString() const { return script_url_string_; } unsigned long ScriptResourceIdentifier() const { return script_resource_identifier_; @@ -97,8 +89,6 @@ small_script_threshold_ = threshold; } - static size_t SmallScriptThreshold() { return small_script_threshold_; } - private: // Scripts whose first data chunk is smaller than this constant won't be // streamed. Non-const for testing.
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index f96ccc36..85f50b95 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1350,6 +1350,7 @@ "loader/TextResourceDecoderBuilderTest.cpp", "loader/ThreadableLoaderTest.cpp", "loader/modulescript/ModuleScriptLoaderTest.cpp", + "loader/modulescript/ModuleTreeLinkerTest.cpp", "loader/resource/CSSStyleSheetResourceTest.cpp", "loader/resource/FontResourceTest.cpp", "loader/resource/ImageResourceTest.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index a3217e9b..5c3cfba 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -1264,7 +1264,6 @@ api_class: "CSSPropertyAPIMargin", api_methods: ["parseSingleValue"], converter: "ConvertQuirkyLength", - initial: "InitialMargin", interpolable: true, }, { @@ -1272,7 +1271,6 @@ api_class: "CSSPropertyAPIMargin", api_methods: ["parseSingleValue"], converter: "ConvertQuirkyLength", - initial: "InitialMargin", interpolable: true, }, { @@ -1280,7 +1278,6 @@ api_class: "CSSPropertyAPIMargin", api_methods: ["parseSingleValue"], converter: "ConvertQuirkyLength", - initial: "InitialMargin", interpolable: true, }, { @@ -1288,7 +1285,6 @@ api_class: "CSSPropertyAPIMargin", api_methods: ["parseSingleValue"], converter: "ConvertQuirkyLength", - initial: "InitialMargin", interpolable: true, }, { @@ -2818,10 +2814,6 @@ longhands: "marker-start;marker-mid;marker-end", }, { - name: "motion", - longhands: "offset-path;offset-distance;offset-rotation", - }, - { name: "offset", longhands: "offset-path;offset-distance;offset-rotation", },
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp index 83acd1a5..c8b49c4d 100644 --- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp +++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -3412,10 +3412,6 @@ case CSSPropertyBackgroundRepeatY: return nullptr; - case CSSPropertyMotion: - return ValuesForShorthandProperty(motionShorthand(), style, layout_object, - styled_node, allow_visited_style); - case CSSPropertyOffset: return ValuesForShorthandProperty(offsetShorthand(), style, layout_object, styled_node, allow_visited_style);
diff --git a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp index 3918ae8..44d2b01 100644 --- a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp +++ b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
@@ -335,7 +335,6 @@ case CSSPropertyGridArea: case CSSPropertyGridGap: case CSSPropertyListStyle: - case CSSPropertyMotion: case CSSPropertyOffset: case CSSPropertyTextDecoration: case CSSPropertyWebkitMarginCollapse: @@ -475,8 +474,6 @@ return FontVariantValue(); case CSSPropertyMargin: return Get4Values(marginShorthand()); - case CSSPropertyMotion: - return GetShorthandValue(motionShorthand()); case CSSPropertyOffset: return GetShorthandValue(offsetShorthand()); case CSSPropertyWebkitMarginCollapse:
diff --git a/third_party/WebKit/Source/core/css/mediaControls.css b/third_party/WebKit/Source/core/css/mediaControls.css index dd4a094..152f634 100644 --- a/third_party/WebKit/Source/core/css/mediaControls.css +++ b/third_party/WebKit/Source/core/css/mediaControls.css
@@ -153,12 +153,11 @@ direction: ltr; display: flex; flex-direction: column; - font-family: Segoe, "Helvetica Neue", Roboto, Arial, Helvetica, sans-serif; justify-content: flex-end; align-items: center; - font-size: 28px; + font-size: 16px; background-color: black; - transition: opacity .2s cubic-bezier (0.4, 0.0, 0.2, 1); + transition: opacity .2s ease-in-out; } video::-internal-media-remoting-background-image { @@ -183,11 +182,11 @@ margin: 0px; border-width: 0px; background-color: transparent; - height: 36px; - width: 44px; + height: 18px; + width: 22px; padding: 0px; - left: calc(50% - 22px); - top: calc(50% - 60px); + left: calc(50% - 11px); + top: calc(50% - 40px); } video::-internal-media-remoting-cast-text-message { @@ -195,14 +194,13 @@ position: absolute; top: calc(50% - 10px); border: none; - color: #FFFFFF; - opacity: 54% + color: rgba(255,255,255,.54); width: 100%; text-wrap: none; text-align: center; background-color: transparent; - font-size: 13pt; - font-face: Roboto-Regular, Sans-serif, Segoe, Serif, Helvetica; + font-size: 81.25%; + font-family: Roboto-Regular, Sans-serif, Segoe, Serif, Helvetica; padding: 0px; margin: 0px; } @@ -210,20 +208,28 @@ video::-internal-media-remoting-disable-button { display: flex; position: absolute; - top: calc(50% + 55pt); - left: calc(50% - 102px); - height: 28pt; - border: 2pt solid rgba(255,255,255,.54); + top: calc(50% + 60px); + left: calc(50% - 74px); + height: 28px; + border: 1pt solid rgba(255,255,255,.54); border-radius: 2pt; background-color: transparent; - color: #FFFFFF; + color: rgba(255,255,255,.54); margin: 0px; - padding: 8pt 16pt 0pt 16pt; + padding: 5.5px 16px 0px 16px; text-wrap: none; - font-size: 13pt; - font-face: Roboto-Medium, Sans-serif, Segoe, Serif, Helvetica; - opacity: 54% - transition: border .5s ease-out; + font-size: 75%; + font-weight: 500; + font-family: Roboto-Medium, Sans-serif, Segoe, Serif, Helvetica; + box-sizing: border-box; + transition: border,color .5s ease-out; + z-index: 1; /* Set this z-index to make the hover effect work. */ +} + +video::-internal-media-remoting-disable-button:hover { + border: 1pt solid rgba(255,255,255,.70); + color: rgba(255,255,255,.70); + cursor: pointer; } video::-internal-media-controls-overlay-cast-button {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index eaab6a2..7abefdc 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1951,9 +1951,7 @@ return ConsumePathOrNone(range_); case CSSPropertyOffsetPath: return ConsumeOffsetPath( - range_, context_, - current_shorthand == CSSPropertyMotion || - unresolved_property == CSSPropertyAliasMotionPath); + range_, context_, unresolved_property == CSSPropertyAliasMotionPath); case CSSPropertyOffsetDistance: return ConsumeLengthOrPercent(range_, context_->Mode(), kValueRangeAll); case CSSPropertyOffsetRotate: @@ -3478,8 +3476,6 @@ return Consume4Values(marginShorthand(), important); case CSSPropertyPadding: return Consume4Values(paddingShorthand(), important); - case CSSPropertyMotion: - return ConsumeShorthandGreedily(motionShorthand(), important); case CSSPropertyOffset: return ConsumeOffsetShorthand(important); case CSSPropertyWebkitTextEmphasis:
diff --git a/third_party/WebKit/Source/core/dom/BUILD.gn b/third_party/WebKit/Source/core/dom/BUILD.gn index 01139383..80821d3 100644 --- a/third_party/WebKit/Source/core/dom/BUILD.gn +++ b/third_party/WebKit/Source/core/dom/BUILD.gn
@@ -194,6 +194,8 @@ "MessagePort.h", "Modulator.cpp", "Modulator.h", + "ModulatorImpl.cpp", + "ModulatorImpl.h", "ModuleMap.cpp", "ModuleMap.h", "ModuleScript.cpp",
diff --git a/third_party/WebKit/Source/core/dom/Modulator.cpp b/third_party/WebKit/Source/core/dom/Modulator.cpp index c48775ff..56abb82 100644 --- a/third_party/WebKit/Source/core/dom/Modulator.cpp +++ b/third_party/WebKit/Source/core/dom/Modulator.cpp
@@ -6,6 +6,10 @@ #include "bindings/core/v8/ScriptState.h" #include "bindings/core/v8/V8Binding.h" +#include "bindings/core/v8/V8PerContextData.h" +#include "core/dom/Document.h" +#include "core/dom/ModulatorImpl.h" +#include "core/frame/LocalFrame.h" namespace blink { @@ -16,10 +20,20 @@ Modulator* Modulator::From(ScriptState* script_state) { if (!script_state) return nullptr; + V8PerContextData* per_context_data = script_state->PerContextData(); if (!per_context_data) return nullptr; - return static_cast<Modulator*>(per_context_data->GetData(kPerContextDataKey)); + + Modulator* modulator = + static_cast<Modulator*>(per_context_data->GetData(kPerContextDataKey)); + if (!modulator) { + if (Document* document = ToDocument(ExecutionContext::From(script_state))) { + modulator = ModulatorImpl::Create(script_state, *document); + Modulator::SetModulator(script_state, modulator); + } + } + return modulator; } Modulator::~Modulator() {}
diff --git a/third_party/WebKit/Source/core/dom/Modulator.h b/third_party/WebKit/Source/core/dom/Modulator.h index e3a00c5..4c63e3c3 100644 --- a/third_party/WebKit/Source/core/dom/Modulator.h +++ b/third_party/WebKit/Source/core/dom/Modulator.h
@@ -89,6 +89,7 @@ // Synchronously retrieves a single module script from existing module map // entry. + // Note: returns nullptr if the module map entry is still "fetching". virtual ModuleScript* GetFetchedModuleScript(const KURL&) = 0; // https://html.spec.whatwg.org/#resolve-a-module-specifier
diff --git a/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp b/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp new file mode 100644 index 0000000..dbf2f24 --- /dev/null +++ b/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp
@@ -0,0 +1,151 @@ +// Copyright 2017 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 "core/dom/ModulatorImpl.h" + +#include "core/dom/Document.h" +#include "core/dom/ExecutionContext.h" +#include "core/dom/ModuleMap.h" +#include "core/dom/ModuleScript.h" +#include "core/dom/ScriptModuleResolverImpl.h" +#include "core/dom/TaskRunnerHelper.h" +#include "core/frame/LocalFrame.h" +#include "core/loader/modulescript/ModuleScriptFetchRequest.h" +#include "core/loader/modulescript/ModuleScriptLoaderRegistry.h" +#include "platform/loader/fetch/ResourceFetcher.h" + +namespace blink { + +ModulatorImpl* ModulatorImpl::Create(RefPtr<ScriptState> script_state, + Document& document) { + return new ModulatorImpl( + std::move(script_state), + TaskRunnerHelper::Get(TaskType::kNetworking, &document), + document.Fetcher()); +} + +ModulatorImpl::ModulatorImpl(RefPtr<ScriptState> script_state, + RefPtr<WebTaskRunner> task_runner, + ResourceFetcher* fetcher) + : script_state_(std::move(script_state)), + task_runner_(std::move(task_runner)), + fetcher_(fetcher), + map_(this, ModuleMap::Create(this)), + loader_registry_(ModuleScriptLoaderRegistry::Create()), + script_module_resolver_(ScriptModuleResolverImpl::Create(this)) { + DCHECK(script_state_); + DCHECK(task_runner_); + DCHECK(fetcher_); +} + +ModulatorImpl::~ModulatorImpl() {} + +ReferrerPolicy ModulatorImpl::GetReferrerPolicy() { + return GetExecutionContext()->GetReferrerPolicy(); +} + +SecurityOrigin* ModulatorImpl::GetSecurityOrigin() { + return GetExecutionContext()->GetSecurityOrigin(); +} + +void ModulatorImpl::FetchTree(const ModuleScriptFetchRequest& request, + ModuleTreeClient* client) { + // Step 1. Perform the internal module script graph fetching procedure given + // url, settings object, destination, cryptographic nonce, parser state, + // credentials mode, settings object, a new empty list, "client", and with the + // top-level module fetch flag set. If the caller of this algorithm specified + // custom perform the fetch steps, pass those along as well. + + // Note: "Fetch a module script graph" algorithm doesn't have "referrer" as + // its argument. + DCHECK(request.GetReferrer().IsNull()); + + AncestorList empty_ancestor_list; + FetchTreeInternal(request, empty_ancestor_list, + ModuleGraphLevel::kTopLevelModuleFetch, client); + + // Step 2. When the internal module script graph fetching procedure + // asynchronously completes with result, asynchronously complete this + // algorithm with result. + // Note: We delegate to ModuleTreeLinker to notify ModuleTreeClient. +} + +void ModulatorImpl::FetchTreeInternal(const ModuleScriptFetchRequest& request, + const AncestorList& ancestor_list, + ModuleGraphLevel level, + ModuleTreeClient* client) { + NOTIMPLEMENTED(); +} + +void ModulatorImpl::FetchSingle(const ModuleScriptFetchRequest& request, + ModuleGraphLevel level, + SingleModuleClient* client) { + map_->FetchSingleModuleScript(request, level, client); +} + +void ModulatorImpl::FetchNewSingleModule( + const ModuleScriptFetchRequest& request, + ModuleGraphLevel level, + ModuleScriptLoaderClient* client) { + loader_registry_->Fetch(request, level, this, fetcher_.Get(), client); +} + +ModuleScript* ModulatorImpl::GetFetchedModuleScript(const KURL& url) { + return map_->GetFetchedModuleScript(url); +} + +ScriptModule ModulatorImpl::CompileModule( + const String& provided_source, + const String& url_str, + AccessControlStatus access_control_status) { + // Implements Steps 3-6 of + // https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-module-script + + // Step 3. Let realm be the provided environment settings object's Realm. + // Note: Realm is v8::Context. + + // Step 4. If scripting is disabled for the given environment settings + // object's responsible browsing context, then let script source be the empty + // string. Otherwise, let script source be the provided script source. + String script_source; + if (GetExecutionContext()->CanExecuteScripts(kAboutToExecuteScript)) + script_source = provided_source; + + // Step 5. Let result be ParseModule(script source, realm, script). + // Step 6. If result is a List of errors, report the exception given by the + // first element of result for script, return null, and abort these steps. + // Note: reporting is routed via V8Initializer::messageHandlerInMainThread. + ScriptState::Scope scope(script_state_.Get()); + return ScriptModule::Compile(script_state_->GetIsolate(), script_source, + url_str, access_control_status); +} + +ScriptValue ModulatorImpl::InstantiateModule(ScriptModule script_module) { + ScriptState::Scope scope(script_state_.Get()); + return script_module.Instantiate(script_state_.Get()); +} + +Vector<String> ModulatorImpl::ModuleRequestsFromScriptModule( + ScriptModule script_module) { + ScriptState::Scope scope(script_state_.Get()); + return script_module.ModuleRequests(script_state_.Get()); +} + +inline ExecutionContext* ModulatorImpl::GetExecutionContext() const { + return ExecutionContext::From(script_state_.Get()); +} + +DEFINE_TRACE(ModulatorImpl) { + Modulator::Trace(visitor); + visitor->Trace(fetcher_); + visitor->Trace(map_); + visitor->Trace(loader_registry_); + visitor->Trace(script_module_resolver_); +} + +DEFINE_TRACE_WRAPPERS(ModulatorImpl) { + visitor->TraceWrappers(map_); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/ModulatorImpl.h b/third_party/WebKit/Source/core/dom/ModulatorImpl.h new file mode 100644 index 0000000..711d4d7d --- /dev/null +++ b/third_party/WebKit/Source/core/dom/ModulatorImpl.h
@@ -0,0 +1,79 @@ +// Copyright 2017 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 ModulatorImpl_h +#define ModulatorImpl_h + +#include "bindings/core/v8/ScriptModule.h" +#include "bindings/core/v8/ScriptWrappable.h" +#include "bindings/core/v8/TraceWrapperMember.h" +#include "bindings/core/v8/V8PerIsolateData.h" +#include "core/dom/Modulator.h" +#include "platform/heap/Handle.h" + +namespace blink { + +class Document; +class ExecutionContext; +class ModuleMap; +class ModuleScriptLoaderRegistry; +class ResourceFetcher; +class ScriptState; +class WebTaskRunner; + +// ModulatorImpl is the implementation of Modulator interface, which represents +// "environment settings object" concept for module scripts. +// ModulatorImpl serves as the backplane for tieing all ES6 module algorithm +// components together. +class ModulatorImpl final : public Modulator { + public: + static ModulatorImpl* Create(RefPtr<ScriptState>, Document&); + + virtual ~ModulatorImpl(); + DECLARE_TRACE(); + DECLARE_VIRTUAL_TRACE_WRAPPERS(); + + private: + // Implements Modulator + + ScriptModuleResolver* GetScriptModuleResolver() override { + return script_module_resolver_.Get(); + } + WebTaskRunner* TaskRunner() override { return task_runner_.Get(); } + ReferrerPolicy GetReferrerPolicy() override; + SecurityOrigin* GetSecurityOrigin() override; + + void FetchTree(const ModuleScriptFetchRequest&, ModuleTreeClient*) override; + void FetchTreeInternal(const ModuleScriptFetchRequest&, + const AncestorList&, + ModuleGraphLevel, + ModuleTreeClient*) override; + void FetchSingle(const ModuleScriptFetchRequest&, + ModuleGraphLevel, + SingleModuleClient*) override; + ModuleScript* GetFetchedModuleScript(const KURL&) override; + void FetchNewSingleModule(const ModuleScriptFetchRequest&, + ModuleGraphLevel, + ModuleScriptLoaderClient*) override; + ScriptModule CompileModule(const String& script, + const String& url_str, + AccessControlStatus) override; + ScriptValue InstantiateModule(ScriptModule) override; + Vector<String> ModuleRequestsFromScriptModule(ScriptModule) override; + + ModulatorImpl(RefPtr<ScriptState>, RefPtr<WebTaskRunner>, ResourceFetcher*); + + ExecutionContext* GetExecutionContext() const; + + RefPtr<ScriptState> script_state_; + RefPtr<WebTaskRunner> task_runner_; + Member<ResourceFetcher> fetcher_; + TraceWrapperMember<ModuleMap> map_; + Member<ModuleScriptLoaderRegistry> loader_registry_; + Member<ScriptModuleResolver> script_module_resolver_; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/dom/ModuleScript.cpp b/third_party/WebKit/Source/core/dom/ModuleScript.cpp index f175cd9..9e2845e1 100644 --- a/third_party/WebKit/Source/core/dom/ModuleScript.cpp +++ b/third_party/WebKit/Source/core/dom/ModuleScript.cpp
@@ -4,18 +4,36 @@ #include "core/dom/ModuleScript.h" +#include "bindings/core/v8/ScriptState.h" +#include "bindings/core/v8/ScriptValue.h" +#include "v8/include/v8.h" + namespace blink { -void ModuleScript::SetInstantiationError(v8::Isolate* isolate, - v8::Local<v8::Value> error) { +void ModuleScript::SetInstantiationErrorAndClearRecord(ScriptValue error) { + // Implements Step 7.1 of: + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + + // "set script's instantiation state to "errored", ..." DCHECK_EQ(instantiation_state_, ModuleInstantiationState::kUninstantiated); instantiation_state_ = ModuleInstantiationState::kErrored; + // "its instantiation error to instantiationStatus.[[Value]], and ..." DCHECK(!error.IsEmpty()); - instantiation_error_.Set(isolate, error); + { + ScriptState::Scope scope(error.GetScriptState()); + instantiation_error_.Set(error.GetIsolate(), error.V8Value()); + } + + // "its module record to null." + record_ = ScriptModule(); } void ModuleScript::SetInstantiationSuccess() { + // Implements Step 7.2 of: + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + + // "set script's instantiation state to "instantiated"." DCHECK_EQ(instantiation_state_, ModuleInstantiationState::kUninstantiated); instantiation_state_ = ModuleInstantiationState::kInstantiated; }
diff --git a/third_party/WebKit/Source/core/dom/ModuleScript.h b/third_party/WebKit/Source/core/dom/ModuleScript.h index 17cec9d..f334179 100644 --- a/third_party/WebKit/Source/core/dom/ModuleScript.h +++ b/third_party/WebKit/Source/core/dom/ModuleScript.h
@@ -43,15 +43,18 @@ ~ModuleScript() override = default; ScriptModule& Record() { return record_; } - void ClearRecord() { record_ = ScriptModule(); } const KURL& BaseURL() const { return base_url_; } ModuleInstantiationState InstantiationState() const { return instantiation_state_; } + // Implements Step 7.1 of: + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + void SetInstantiationErrorAndClearRecord(ScriptValue error); + // Implements Step 7.2 of: + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure void SetInstantiationSuccess(); - void SetInstantiationError(v8::Isolate*, v8::Local<v8::Value> error); ParserDisposition ParserState() const { return parser_state_; } WebURLRequest::FetchCredentialsMode CredentialsMode() const {
diff --git a/third_party/WebKit/Source/core/editing/BUILD.gn b/third_party/WebKit/Source/core/editing/BUILD.gn index 12efe0b37..15bdd615 100644 --- a/third_party/WebKit/Source/core/editing/BUILD.gn +++ b/third_party/WebKit/Source/core/editing/BUILD.gn
@@ -32,6 +32,8 @@ "EditorKeyBindings.cpp", "EphemeralRange.cpp", "EphemeralRange.h", + "FindInPageCoordinates.cpp", + "FindInPageCoordinates.h", "FrameCaret.cpp", "FrameCaret.h", "FrameSelection.cpp",
diff --git a/third_party/WebKit/Source/web/FindInPageCoordinates.cpp b/third_party/WebKit/Source/core/editing/FindInPageCoordinates.cpp similarity index 98% rename from third_party/WebKit/Source/web/FindInPageCoordinates.cpp rename to third_party/WebKit/Source/core/editing/FindInPageCoordinates.cpp index e84c7c7..f09f593b 100644 --- a/third_party/WebKit/Source/web/FindInPageCoordinates.cpp +++ b/third_party/WebKit/Source/core/editing/FindInPageCoordinates.cpp
@@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "web/FindInPageCoordinates.h" +#include "core/editing/FindInPageCoordinates.h" #include "core/dom/Node.h" #include "core/dom/Range.h"
diff --git a/third_party/WebKit/Source/web/FindInPageCoordinates.h b/third_party/WebKit/Source/core/editing/FindInPageCoordinates.h similarity index 91% rename from third_party/WebKit/Source/web/FindInPageCoordinates.h rename to third_party/WebKit/Source/core/editing/FindInPageCoordinates.h index 5aa8fff..bf1c37a8 100644 --- a/third_party/WebKit/Source/web/FindInPageCoordinates.h +++ b/third_party/WebKit/Source/core/editing/FindInPageCoordinates.h
@@ -31,8 +31,8 @@ #ifndef FindInPageCoordinates_h #define FindInPageCoordinates_h +#include "core/CoreExport.h" #include "platform/geometry/FloatRect.h" -#include "web/WebExport.h" namespace blink { class Range; @@ -54,9 +54,9 @@ // of their container. The provided methods support scroll:overflow and are // CSS position and transform-friendly. -WEB_EXPORT FloatRect FindInPageRectFromAbsoluteRect(const FloatRect&, - const LayoutObject*); -WEB_EXPORT FloatRect FindInPageRectFromRange(Range*); +CORE_EXPORT FloatRect FindInPageRectFromAbsoluteRect(const FloatRect&, + const LayoutObject*); +CORE_EXPORT FloatRect FindInPageRectFromRange(Range*); } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp index c754219..44d4438 100644 --- a/third_party/WebKit/Source/core/frame/Deprecation.cpp +++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -127,8 +127,6 @@ case CSSPropertyAliasMotionPath: return replacedWillBeRemoved("motion-path", "offset-path", M58, "6390764217040896"); - case CSSPropertyMotion: - return replacedWillBeRemoved("motion", "offset", M58, "6390764217040896"); case CSSPropertyOffsetRotation: return replacedWillBeRemoved("offset-rotation", "offset-rotate", M58, "6390764217040896");
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp index 74e0cefd..070d70a 100644 --- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp +++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -896,9 +896,24 @@ return; } + CanvasColorParams canvas_color_params; + if (RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() && + RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) { + ImageDataColorSettings color_settings; + data->getColorSettings(color_settings); + CanvasColorSpace canvas_color_space = + ImageData::GetCanvasColorSpace(color_settings.colorSpace()); + CanvasPixelFormat canvas_pixel_format = kRGBA8CanvasPixelFormat; + if (ImageData::GetImageDataStorageFormat(color_settings.storageFormat()) != + kUint8ClampedArrayStorageFormat) { + canvas_pixel_format = kF16CanvasPixelFormat; + } + canvas_color_params = + CanvasColorParams(canvas_color_space, canvas_pixel_format); + } std::unique_ptr<ImageBuffer> buffer = ImageBuffer::Create(parsed_options.crop_rect.Size(), kNonOpaque, - kDoNotInitializeImagePixels, data->GetSkColorSpace()); + kDoNotInitializeImagePixels, canvas_color_params); if (!buffer) return;
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index 8a46a3b..5a68e69 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -887,8 +887,7 @@ return 458; case CSSPropertyAliasMotionRotation: return 459; - case CSSPropertyMotion: - return 460; + // CSSPropertyMotion was 460. case CSSPropertyX: return 461; case CSSPropertyY:
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 32b5099..ca26c8a 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -896,10 +896,9 @@ virtual std::unique_ptr<ImageBufferSurface> CreateSurface( const IntSize& size, OpacityMode opacity_mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type) { + const CanvasColorParams& color_params) { return WTF::WrapUnique(new UnacceleratedImageBufferSurface( - size, opacity_mode, kInitializeImagePixels, color_space, color_type)); + size, opacity_mode, kInitializeImagePixels, color_params)); } virtual ~UnacceleratedSurfaceFactory() {} @@ -908,7 +907,10 @@ } // namespace bool HTMLCanvasElement::ShouldUseDisplayList() { - if (context_->ColorSpace() != kLegacyCanvasColorSpace) + // Rasterization of web contents will blend in the output space. Only embed + // the canvas as a display list if it intended to do output space blending as + // well. + if (!context_->color_params().UsesOutputSpaceBlending()) return false; if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) @@ -927,8 +929,7 @@ // then make a non-accelerated ImageBuffer. This means copying the internal // Image will require a pixel readback, but that is unavoidable in this case. auto surface = WTF::WrapUnique(new AcceleratedImageBufferSurface( - size(), opacity_mode, context_->SkSurfaceColorSpace(), - context_->ColorType())); + size(), opacity_mode, context_->color_params())); if (surface->IsValid()) return std::move(surface); return nullptr; @@ -958,8 +959,7 @@ std::unique_ptr<ImageBufferSurface> surface = WTF::WrapUnique(new Canvas2DImageBufferSurface( std::move(context_provider), size(), *msaa_sample_count, opacity_mode, - Canvas2DLayerBridge::kEnableAcceleration, context_->GfxColorSpace(), - context_->SkSurfacesUseColorSpace(), context_->ColorType())); + Canvas2DLayerBridge::kEnableAcceleration, context_->color_params())); if (!surface->IsValid()) { CanvasMetrics::CountCanvasContextUsage( CanvasMetrics::kGPUAccelerated2DCanvasImageBufferCreationFailed); @@ -977,7 +977,7 @@ if (ShouldUseDisplayList()) { auto surface = WTF::WrapUnique(new RecordingImageBufferSurface( size(), WTF::WrapUnique(new UnacceleratedSurfaceFactory), opacity_mode, - context_->SkSurfaceColorSpace(), context_->ColorType())); + context_->color_params())); if (surface->IsValid()) { CanvasMetrics::CountCanvasContextUsage( CanvasMetrics::kDisplayList2DCanvasImageBufferCreated); @@ -989,8 +989,7 @@ auto surface_factory = WTF::MakeUnique<UnacceleratedSurfaceFactory>(); auto surface = surface_factory->CreateSurface(size(), opacity_mode, - context_->SkSurfaceColorSpace(), - context_->ColorType()); + context_->color_params()); if (surface->IsValid()) { CanvasMetrics::CountCanvasContextUsage( CanvasMetrics::kUnaccelerated2DCanvasImageBufferCreated);
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp index 23590934..bb9f51c 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -67,7 +67,7 @@ // linearPixelMath rather than the requested one. creation_attributes_.setColorSpace(ColorSpaceAsString()); creation_attributes_.setPixelFormat(PixelFormatAsString()); - creation_attributes_.setLinearPixelMath(LinearPixelMath()); + creation_attributes_.setLinearPixelMath(color_params_.LinearPixelMath()); } WTF::String CanvasRenderingContext::ColorSpaceAsString() const { @@ -100,37 +100,13 @@ return ""; } -gfx::ColorSpace CanvasRenderingContext::GfxColorSpace() const { - return color_params_.GetGfxColorSpace(); -} - -sk_sp<SkColorSpace> CanvasRenderingContext::SkSurfaceColorSpace() const { - return color_params_.GetSkColorSpaceForSkSurfaces(); -} - -bool CanvasRenderingContext::SkSurfacesUseColorSpace() const { - return color_params_.GetSkColorSpaceForSkSurfaces(); -} - -bool CanvasRenderingContext::LinearPixelMath() const { - return color_params_.LinearPixelMath(); -} - ColorBehavior CanvasRenderingContext::ColorBehaviorForMediaDrawnToCanvas() const { if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) - return ColorBehavior::TransformTo(GfxColorSpace()); + return ColorBehavior::TransformTo(color_params_.GetGfxColorSpace()); return ColorBehavior::TransformToGlobalTarget(); } -CanvasColorSpace CanvasRenderingContext::ColorSpace() const { - return color_params_.color_space(); -} - -SkColorType CanvasRenderingContext::ColorType() const { - return color_params_.GetSkColorType(); -} - void CanvasRenderingContext::Dispose() { if (finalize_frame_scheduled_) { Platform::Current()->CurrentThread()->RemoveTaskObserver(this);
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h index 0a6a2369..84040416 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -89,21 +89,11 @@ HTMLCanvasElement* canvas() const { return canvas_; } - CanvasColorSpace ColorSpace() const; WTF::String ColorSpaceAsString() const; - CanvasPixelFormat PixelFormat() const; WTF::String PixelFormatAsString() const; - bool LinearPixelMath() const; - // The color space in which the the content should be interpreted by the - // compositor. This is always defined. - gfx::ColorSpace GfxColorSpace() const; - // The color space that should be used for SkSurface creation. This may - // be nullptr. - sk_sp<SkColorSpace> SkSurfaceColorSpace() const; - SkColorType ColorType() const; + const CanvasColorParams& color_params() const { return color_params_; } ColorBehavior ColorBehaviorForMediaDrawnToCanvas() const; - bool SkSurfacesUseColorSpace() const; virtual PassRefPtr<Image> GetImage(AccelerationHint, SnapshotReason) const = 0;
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp index be63dba..1add0ab 100644 --- a/third_party/WebKit/Source/core/input/EventHandler.cpp +++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -651,8 +651,7 @@ } mouse_event_manager_->SetClickCount(mouse_event.click_count); - mouse_event_manager_->SetClickElement( - EventHandlingUtil::ParentElementIfNeeded(mev.InnerNode())); + mouse_event_manager_->SetClickElement(mev.InnerElement()); if (!mouse_event.FromTouch()) frame_->Selection().SetCaretBlinkingSuspended(true); @@ -957,8 +956,7 @@ HitTestRequest request(hit_type); MouseEventWithHitTestResults mev = EventHandlingUtil::PerformMouseEventHitTest(frame_, request, mouse_event); - Element* mouse_release_target = - EventHandlingUtil::ParentElementIfNeeded(mev.InnerNode()); + Element* mouse_release_target = mev.InnerElement(); LocalFrame* subframe = capturing_mouse_events_node_.Get() ? SubframeForTargetNode(capturing_mouse_events_node_.Get())
diff --git a/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp b/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp index 0872c3a..8ce9d0ca 100644 --- a/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp +++ b/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp
@@ -92,14 +92,6 @@ return nullptr; } -Element* ParentElementIfNeeded(Node* node) { - if (!node) - return nullptr; - if (node->IsElementNode()) - return ToElement(node); - return FlatTreeTraversal::ParentElement(*node); -} - ContainerNode* ParentForClickEvent(const Node& node) { // IE doesn't dispatch click events for mousedown/mouseup events across form // controls.
diff --git a/third_party/WebKit/Source/core/input/EventHandlingUtil.h b/third_party/WebKit/Source/core/input/EventHandlingUtil.h index edef3b9..fb9ed3da 100644 --- a/third_party/WebKit/Source/core/input/EventHandlingUtil.h +++ b/third_party/WebKit/Source/core/input/EventHandlingUtil.h
@@ -31,7 +31,6 @@ PaintLayer* LayerForNode(Node*); ScrollableArea* AssociatedScrollableArea(const PaintLayer*); -Element* ParentElementIfNeeded(Node*); ContainerNode* ParentForClickEvent(const Node&); LayoutPoint ContentPointFromRootFrame(LocalFrame*,
diff --git a/third_party/WebKit/Source/core/input/GestureManager.cpp b/third_party/WebKit/Source/core/input/GestureManager.cpp index a291e0e..ce5f660 100644 --- a/third_party/WebKit/Source/core/input/GestureManager.cpp +++ b/third_party/WebKit/Source/core/input/GestureManager.cpp
@@ -188,8 +188,7 @@ IntPoint tapped_position = FlooredIntPoint(gesture_event.PositionInRootFrame()); Node* tapped_node = current_hit_test.InnerNode(); - Element* tapped_element = - EventHandlingUtil::ParentElementIfNeeded(tapped_node); + Element* tapped_element = current_hit_test.InnerElement(); UserGestureIndicator gesture_indicator(DocumentUserGestureToken::Create( tapped_node ? &tapped_node->GetDocument() : nullptr));
diff --git a/third_party/WebKit/Source/core/layout/HitTestResult.cpp b/third_party/WebKit/Source/core/layout/HitTestResult.cpp index 3799c7b..3018bc3 100644 --- a/third_party/WebKit/Source/core/layout/HitTestResult.cpp +++ b/third_party/WebKit/Source/core/layout/HitTestResult.cpp
@@ -508,13 +508,11 @@ } Element* HitTestResult::InnerElement() const { - for (Node* node = inner_node_.Get(); node; - node = FlatTreeTraversal::Parent(*node)) { - if (node->IsElementNode()) - return ToElement(node); - } - - return nullptr; + if (!inner_node_) + return nullptr; + if (inner_node_->IsElementNode()) + return ToElement(inner_node_); + return FlatTreeTraversal::ParentElement(*inner_node_); } Node* HitTestResult::InnerNodeOrImageMapImage() const {
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc index 4976df78..bee54c30 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -133,25 +133,25 @@ ToLayoutText(GetLayoutObjectByElementId("text")->SlowFirstChild()); DCHECK(layout_text->HasTextBoxes()); - ASSERT_EQ(4UL, text_fragments.size()); + // Line break points may vary by minor differences in fonts. + // The test is valid as long as we have 3 or more lines and their positions + // are correct. + EXPECT_GE(text_fragments.size(), 3UL); auto* text_fragment1 = text_fragments[0]; // 40 = #left-float1' width 30 + #left-float2 10 EXPECT_EQ(LayoutUnit(40), text_fragment1->LeftOffset()); - EXPECT_EQ("The quick ", text_fragment1->Text()); InlineTextBox* inline_text_box1 = layout_text->FirstTextBox(); EXPECT_EQ(LayoutUnit(40), inline_text_box1->X()); auto* text_fragment2 = text_fragments[1]; // 40 = #left-float1' width 30 EXPECT_EQ(LayoutUnit(30), text_fragment2->LeftOffset()); - EXPECT_EQ("brown fox ", text_fragment2->Text()); InlineTextBox* inline_text_box2 = inline_text_box1->NextTextBox(); EXPECT_EQ(LayoutUnit(30), inline_text_box2->X()); auto* text_fragment3 = text_fragments[2]; EXPECT_EQ(LayoutUnit(), text_fragment3->LeftOffset()); - EXPECT_EQ("jumps over the lazy ", text_fragment3->Text()); InlineTextBox* inline_text_box3 = inline_text_box2->NextTextBox(); EXPECT_EQ(LayoutUnit(), inline_text_box3->X()); }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc index a9d8dd6..96402b5 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -203,6 +203,11 @@ LayoutObject* next_sibling = layout_box_->NextSibling(); if (next_sibling) { if (next_sibling->IsInline()) { + // As long as we traverse LayoutObject tree, this should not happen. + // See ShouldHandleByInlineContext() for more context. + // Also this leads to incorrect layout because we create two + // NGLayoutInputNode for one LayoutBlockFlow. + NOTREACHED(); next_sibling_ = new NGInlineNode( next_sibling, ToLayoutBlockFlow(layout_box_->Parent())); } else { @@ -217,11 +222,32 @@ return layout_box_; } +static bool ShouldHandleByInlineContext(LayoutObject* child) { + DCHECK(child); + // The spec isn't clear about whether floats/OOF should be in inline + // formatting context or in block formatting context. + // Prefer inline formatting context because 1) floats/OOF at the beginning + // and in the middle of inline should be handled in the same code, and 2) + // it matches to the LayoutObject tree. + for (; child; child = child->NextSibling()) { + if (child->IsInline()) + return true; + if (child->IsFloating() || child->IsOutOfFlowPositioned()) + continue; + return false; + } + // All children are either float or OOF. + // TODO(kojii): Should this be handled in block context or inline context? + // If we handle in inline, we can remove all code for floats/OOF from block + // layout, but it may change semantics and causes incorrectness? + return false; +} + NGLayoutInputNode* NGBlockNode::FirstChild() { if (!first_child_) { LayoutObject* child = layout_box_->SlowFirstChild(); if (child) { - if (child->IsInline()) { + if (ShouldHandleByInlineContext(child)) { first_child_ = new NGInlineNode(child, ToLayoutBlockFlow(layout_box_)); } else { first_child_ = new NGBlockNode(child);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc index 7c70718..d3becbc 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc
@@ -18,6 +18,152 @@ ~NGBlockNodeForTest() { RuntimeEnabledFeatures::setLayoutNGEnabled(false); }; }; +TEST_F(NGBlockNodeForTest, ChildInlineAndBlock) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <div id=container>Hello!<div></div></div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsBlock()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_TRUE(child2 && child2->IsBlock()); + NGLayoutInputNode* child3 = child2->NextSibling(); + EXPECT_EQ(child3, nullptr); +} + +TEST_F(NGBlockNodeForTest, ChildBlockAndInline) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <div id=container><div></div>Hello!</div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsBlock()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_TRUE(child2 && child2->IsBlock()); + NGLayoutInputNode* child3 = child2->NextSibling(); + EXPECT_EQ(child3, nullptr); +} + +TEST_F(NGBlockNodeForTest, ChildFloatBeforeBlock) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + float { float: left; } + </style> + <div id=container><float></float><div></div></div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsBlock()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_TRUE(child2 && child2->IsBlock()); + NGLayoutInputNode* child3 = child2->NextSibling(); + EXPECT_EQ(child3, nullptr); +} + +TEST_F(NGBlockNodeForTest, ChildFloatBeforeInline) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + float { float: left; } + </style> + <div id=container><float></float>Hello!</div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsInline()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_EQ(child2, nullptr); +} + +TEST_F(NGBlockNodeForTest, ChildFloatAfterInline) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + float { float: left; } + </style> + <div id=container>Hello<float></float></div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsInline()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_EQ(child2, nullptr); +} + +TEST_F(NGBlockNodeForTest, ChildFloatOnly) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + float { float: left; } + </style> + <div id=container><float></float></div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsBlock()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_EQ(child2, nullptr); +} + +TEST_F(NGBlockNodeForTest, ChildFloatWithSpaces) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + float { float: left; } + </style> + <div id=container> + <float></float> + </div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsBlock()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_EQ(child2, nullptr); +} + +TEST_F(NGBlockNodeForTest, ChildOofBeforeInline) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + oof { position: absolute; } + </style> + <div id=container><oof></oof>Hello!</div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsInline()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_EQ(child2, nullptr); +} + +TEST_F(NGBlockNodeForTest, ChildOofAfterInline) { + SetBodyInnerHTML(R"HTML( + <!DOCTYPE html> + <style> + oof { position: absolute; } + </style> + <div id=container>Hello!<oof></oof></div> + )HTML"); + NGBlockNode* container = + new NGBlockNode(GetLayoutObjectByElementId("container")); + NGLayoutInputNode* child1 = container->FirstChild(); + EXPECT_TRUE(child1 && child1->IsInline()); + NGLayoutInputNode* child2 = child1->NextSibling(); + EXPECT_EQ(child2, nullptr); +} + TEST_F(NGBlockNodeForTest, MinAndMaxContent) { SetBodyInnerHTML(R"HTML( <div id="box" >
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp b/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp index c26d53819..4156e04 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp
@@ -418,6 +418,58 @@ } } +void SVGResources::ClearReferencesTo(LayoutSVGResourceContainer* resource) { + DCHECK(resource); + if (linked_resource_ == resource) { + DCHECK(!clipper_filter_masker_data_); + DCHECK(!marker_data_); + DCHECK(!fill_stroke_data_); + linked_resource_ = nullptr; + return; + } + + switch (resource->ResourceType()) { + case kMaskerResourceType: + DCHECK(clipper_filter_masker_data_); + DCHECK_EQ(clipper_filter_masker_data_->masker, resource); + clipper_filter_masker_data_->masker = nullptr; + break; + case kMarkerResourceType: + DCHECK(marker_data_); + DCHECK(resource == MarkerStart() || resource == MarkerMid() || + resource == MarkerEnd()); + if (marker_data_->marker_start == resource) + marker_data_->marker_start = nullptr; + if (marker_data_->marker_mid == resource) + marker_data_->marker_mid = nullptr; + if (marker_data_->marker_end == resource) + marker_data_->marker_end = nullptr; + break; + case kPatternResourceType: + case kLinearGradientResourceType: + case kRadialGradientResourceType: + DCHECK(fill_stroke_data_); + DCHECK(resource == Fill() || resource == Stroke()); + if (fill_stroke_data_->fill == resource) + fill_stroke_data_->fill = nullptr; + if (fill_stroke_data_->stroke == resource) + fill_stroke_data_->stroke = nullptr; + break; + case kFilterResourceType: + DCHECK(clipper_filter_masker_data_); + DCHECK_EQ(clipper_filter_masker_data_->filter, resource); + clipper_filter_masker_data_->filter = nullptr; + break; + case kClipperResourceType: + DCHECK(clipper_filter_masker_data_); + DCHECK_EQ(clipper_filter_masker_data_->clipper, resource); + clipper_filter_masker_data_->clipper = nullptr; + break; + default: + NOTREACHED(); + } +} + void SVGResources::BuildSetOfResources( HashSet<LayoutSVGResourceContainer*>& set) { if (!HasResourceData()) @@ -469,12 +521,6 @@ clipper_filter_masker_data_->clipper = clipper; } -void SVGResources::ResetClipper() { - DCHECK(clipper_filter_masker_data_); - DCHECK(clipper_filter_masker_data_->clipper); - clipper_filter_masker_data_->clipper = nullptr; -} - void SVGResources::SetFilter(LayoutSVGResourceFilter* filter) { if (!filter) return; @@ -487,12 +533,6 @@ clipper_filter_masker_data_->filter = filter; } -void SVGResources::ResetFilter() { - DCHECK(clipper_filter_masker_data_); - DCHECK(clipper_filter_masker_data_->filter); - clipper_filter_masker_data_->filter = nullptr; -} - void SVGResources::SetMarkerStart(LayoutSVGResourceMarker* marker_start) { if (!marker_start) return; @@ -505,12 +545,6 @@ marker_data_->marker_start = marker_start; } -void SVGResources::ResetMarkerStart() { - DCHECK(marker_data_); - DCHECK(marker_data_->marker_start); - marker_data_->marker_start = nullptr; -} - void SVGResources::SetMarkerMid(LayoutSVGResourceMarker* marker_mid) { if (!marker_mid) return; @@ -523,12 +557,6 @@ marker_data_->marker_mid = marker_mid; } -void SVGResources::ResetMarkerMid() { - DCHECK(marker_data_); - DCHECK(marker_data_->marker_mid); - marker_data_->marker_mid = nullptr; -} - void SVGResources::SetMarkerEnd(LayoutSVGResourceMarker* marker_end) { if (!marker_end) return; @@ -541,12 +569,6 @@ marker_data_->marker_end = marker_end; } -void SVGResources::ResetMarkerEnd() { - DCHECK(marker_data_); - DCHECK(marker_data_->marker_end); - marker_data_->marker_end = nullptr; -} - void SVGResources::SetMasker(LayoutSVGResourceMasker* masker) { if (!masker) return; @@ -559,12 +581,6 @@ clipper_filter_masker_data_->masker = masker; } -void SVGResources::ResetMasker() { - DCHECK(clipper_filter_masker_data_); - DCHECK(clipper_filter_masker_data_->masker); - clipper_filter_masker_data_->masker = nullptr; -} - void SVGResources::SetFill(LayoutSVGResourcePaintServer* fill) { if (!fill) return; @@ -575,12 +591,6 @@ fill_stroke_data_->fill = fill; } -void SVGResources::ResetFill() { - DCHECK(fill_stroke_data_); - DCHECK(fill_stroke_data_->fill); - fill_stroke_data_->fill = nullptr; -} - void SVGResources::SetStroke(LayoutSVGResourcePaintServer* stroke) { if (!stroke) return; @@ -591,12 +601,6 @@ fill_stroke_data_->stroke = stroke; } -void SVGResources::ResetStroke() { - DCHECK(fill_stroke_data_); - DCHECK(fill_stroke_data_->stroke); - fill_stroke_data_->stroke = nullptr; -} - void SVGResources::SetLinkedResource( LayoutSVGResourceContainer* linked_resource) { if (!linked_resource) @@ -605,11 +609,6 @@ linked_resource_ = linked_resource; } -void SVGResources::ResetLinkedResource() { - DCHECK(linked_resource_); - linked_resource_ = nullptr; -} - #ifndef NDEBUG void SVGResources::Dump(const LayoutObject* object) { DCHECK(object);
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResources.h b/third_party/WebKit/Source/core/layout/svg/SVGResources.h index 41af41f5..276203ba 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResources.h +++ b/third_party/WebKit/Source/core/layout/svg/SVGResources.h
@@ -99,27 +99,15 @@ LayoutObject*, bool mark_for_invalidation = true) const; void ResourceDestroyed(LayoutSVGResourceContainer*); + void ClearReferencesTo(LayoutSVGResourceContainer*); #ifndef NDEBUG void Dump(const LayoutObject*); #endif private: - friend class SVGResourcesCycleSolver; - bool HasResourceData() const; - // Only used by SVGResourcesCache cycle detection logic - void ResetClipper(); - void ResetFilter(); - void ResetMarkerStart(); - void ResetMarkerMid(); - void ResetMarkerEnd(); - void ResetMasker(); - void ResetFill(); - void ResetStroke(); - void ResetLinkedResource(); - void SetClipper(LayoutSVGResourceClipper*); void SetFilter(LayoutSVGResourceFilter*); void SetMarkerStart(LayoutSVGResourceMarker*);
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResourcesCycleSolver.cpp b/third_party/WebKit/Source/core/layout/svg/SVGResourcesCycleSolver.cpp index bda16fa1..94986229 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResourcesCycleSolver.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGResourcesCycleSolver.cpp
@@ -19,14 +19,7 @@ #include "core/layout/svg/SVGResourcesCycleSolver.h" -// Set to a value > 0, to debug the resource cache. -#define DEBUG_CYCLE_DETECTION 0 - -#include "core/layout/svg/LayoutSVGResourceClipper.h" -#include "core/layout/svg/LayoutSVGResourceFilter.h" -#include "core/layout/svg/LayoutSVGResourceMarker.h" -#include "core/layout/svg/LayoutSVGResourceMasker.h" -#include "core/layout/svg/LayoutSVGResourcePaintServer.h" +#include "core/layout/svg/LayoutSVGResourceContainer.h" #include "core/layout/svg/SVGResources.h" #include "core/layout/svg/SVGResourcesCache.h" @@ -108,58 +101,10 @@ for (auto* local_resource : local_resources) { if (active_resources_.Contains(local_resource) || ResourceContainsCycles(local_resource)) - BreakCycle(local_resource); + resources_->ClearReferencesTo(local_resource); } active_resources_.Clear(); } -void SVGResourcesCycleSolver::BreakCycle( - LayoutSVGResourceContainer* resource_leading_to_cycle) { - DCHECK(resource_leading_to_cycle); - if (resource_leading_to_cycle == resources_->LinkedResource()) { - resources_->ResetLinkedResource(); - return; - } - - switch (resource_leading_to_cycle->ResourceType()) { - case kMaskerResourceType: - DCHECK_EQ(resource_leading_to_cycle, resources_->Masker()); - resources_->ResetMasker(); - break; - case kMarkerResourceType: - DCHECK(resource_leading_to_cycle == resources_->MarkerStart() || - resource_leading_to_cycle == resources_->MarkerMid() || - resource_leading_to_cycle == resources_->MarkerEnd()); - if (resources_->MarkerStart() == resource_leading_to_cycle) - resources_->ResetMarkerStart(); - if (resources_->MarkerMid() == resource_leading_to_cycle) - resources_->ResetMarkerMid(); - if (resources_->MarkerEnd() == resource_leading_to_cycle) - resources_->ResetMarkerEnd(); - break; - case kPatternResourceType: - case kLinearGradientResourceType: - case kRadialGradientResourceType: - DCHECK(resource_leading_to_cycle == resources_->Fill() || - resource_leading_to_cycle == resources_->Stroke()); - if (resources_->Fill() == resource_leading_to_cycle) - resources_->ResetFill(); - if (resources_->Stroke() == resource_leading_to_cycle) - resources_->ResetStroke(); - break; - case kFilterResourceType: - DCHECK_EQ(resource_leading_to_cycle, resources_->Filter()); - resources_->ResetFilter(); - break; - case kClipperResourceType: - DCHECK_EQ(resource_leading_to_cycle, resources_->Clipper()); - resources_->ResetClipper(); - break; - default: - NOTREACHED(); - break; - } -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResourcesCycleSolver.h b/third_party/WebKit/Source/core/layout/svg/SVGResourcesCycleSolver.h index 8ce080e..ca02bbe 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResourcesCycleSolver.h +++ b/third_party/WebKit/Source/core/layout/svg/SVGResourcesCycleSolver.h
@@ -44,7 +44,6 @@ private: bool ResourceContainsCycles(LayoutSVGResourceContainer*); - void BreakCycle(LayoutSVGResourceContainer*); LayoutObject* layout_object_; SVGResources* resources_;
diff --git a/third_party/WebKit/Source/core/loader/BUILD.gn b/third_party/WebKit/Source/core/loader/BUILD.gn index 393c8b9..c5ec0ea2 100644 --- a/third_party/WebKit/Source/core/loader/BUILD.gn +++ b/third_party/WebKit/Source/core/loader/BUILD.gn
@@ -79,6 +79,10 @@ "modulescript/ModuleScriptLoaderClient.h", "modulescript/ModuleScriptLoaderRegistry.cpp", "modulescript/ModuleScriptLoaderRegistry.h", + "modulescript/ModuleTreeLinker.cpp", + "modulescript/ModuleTreeLinker.h", + "modulescript/ModuleTreeLinkerRegistry.cpp", + "modulescript/ModuleTreeLinkerRegistry.h", "private/CrossOriginPreflightResultCache.cpp", "private/CrossOriginPreflightResultCache.h", "private/FrameClientHintsPreferencesContext.cpp",
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinker.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinker.cpp new file mode 100644 index 0000000..470f28b0 --- /dev/null +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinker.cpp
@@ -0,0 +1,460 @@ +// Copyright 2017 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 "core/loader/modulescript/ModuleTreeLinker.h" + +#include "bindings/core/v8/ScriptModule.h" +#include "core/dom/AncestorList.h" +#include "core/dom/ModuleScript.h" +#include "core/loader/modulescript/ModuleScriptFetchRequest.h" +#include "core/loader/modulescript/ModuleTreeLinkerRegistry.h" +#include "platform/loader/fetch/ResourceLoadingLog.h" +#include "platform/wtf/HashSet.h" + +namespace blink { + +ModuleTreeLinker* ModuleTreeLinker::Fetch( + const ModuleScriptFetchRequest& request, + const AncestorList& ancestor_list, + ModuleGraphLevel level, + Modulator* modulator, + ModuleTreeLinkerRegistry* registry, + ModuleTreeClient* client) { + AncestorList ancestor_list_with_url = ancestor_list; + ancestor_list_with_url.insert(request.Url()); + + ModuleTreeLinker* fetcher = + new ModuleTreeLinker(ancestor_list_with_url, modulator, registry, client); + fetcher->FetchSelf(request, level); + return fetcher; +} + +ModuleTreeLinker::ModuleTreeLinker(const AncestorList& ancestor_list_with_url, + Modulator* modulator, + ModuleTreeLinkerRegistry* registry, + ModuleTreeClient* client) + : modulator_(modulator), + registry_(registry), + client_(client), + ancestor_list_with_url_(ancestor_list_with_url) { + CHECK(modulator); + CHECK(registry); + CHECK(client); +} + +DEFINE_TRACE(ModuleTreeLinker) { + visitor->Trace(modulator_); + visitor->Trace(registry_); + visitor->Trace(client_); + visitor->Trace(module_script_); + visitor->Trace(descendants_module_script_); + visitor->Trace(dependency_clients_); + SingleModuleClient::Trace(visitor); +} + +#if DCHECK_IS_ON() +const char* ModuleTreeLinker::StateToString(ModuleTreeLinker::State state) { + switch (state) { + case State::kInitial: + return "Initial"; + case State::kFetchingSelf: + return "FetchingSelf"; + case State::kFetchingDependencies: + return "FetchingDependencies"; + case State::kInstantiating: + return "Instantiating"; + case State::kFinished: + return "Finished"; + } + NOTREACHED(); + return ""; +} +#endif + +void ModuleTreeLinker::AdvanceState(State new_state) { +#if DCHECK_IS_ON() + RESOURCE_LOADING_DVLOG(1) + << "ModuleTreeLinker[" << this << "]::advanceState(" + << StateToString(state_) << " -> " << StateToString(new_state) << ")"; +#endif + + switch (state_) { + case State::kInitial: + CHECK_EQ(num_incomplete_descendants_, 0u); + CHECK_EQ(new_state, State::kFetchingSelf); + break; + case State::kFetchingSelf: + CHECK_EQ(num_incomplete_descendants_, 0u); + CHECK(new_state == State::kFetchingDependencies || + (!descendants_module_script_ && new_state == State::kFinished)); + break; + case State::kFetchingDependencies: + CHECK_EQ(new_state, State::kInstantiating); + DCHECK(!num_incomplete_descendants_ || !descendants_module_script_) + << num_incomplete_descendants_ + << " outstanding descendant loads found, but the descendant module " + "script load procedure unexpectedly finished with " + << (!!descendants_module_script_ ? "success." : "failure."); + break; + case State::kInstantiating: + CHECK(num_incomplete_descendants_ == 0u || !descendants_module_script_); + CHECK_EQ(new_state, State::kFinished); + break; + case State::kFinished: + NOTREACHED(); + break; + } + + state_ = new_state; + + if (state_ == State::kFinished) { + registry_->ReleaseFinishedFetcher(this); + + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + // Step 8. Asynchronously complete this algorithm with descendants result. + client_->NotifyModuleTreeLoadFinished(descendants_module_script_); + } +} + +void ModuleTreeLinker::FetchSelf(const ModuleScriptFetchRequest& request, + ModuleGraphLevel level) { + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + + // Step 1. Fetch a single module script given url, fetch client settings + // object, destination, cryptographic nonce, parser state, credentials mode, + // module map settings object, referrer, and the top-level module fetch flag. + // If the caller of this algorithm specified custom perform the fetch steps, + // pass those along while fetching a single module script. + AdvanceState(State::kFetchingSelf); + modulator_->FetchSingle(request, level, this); + + // Step 2. Return from this algorithm, and run the following steps when + // fetching a single module script asynchronously completes with result. + // Note: Modulator::fetchSingle asynchronously notifies result to + // ModuleTreeLinker::notifyModuleLoadFinished(). +} + +void ModuleTreeLinker::NotifyModuleLoadFinished(ModuleScript* module_script) { + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + + // Step 3. "If result is null, ..." + if (!module_script) { + // "asynchronously complete this algorithm with null and abort these steps." + // Note: The return variable for "internal module script graph fetching + // procedure" is descendants_module_script_ per Step 8. + DCHECK(!descendants_module_script_); + AdvanceState(State::kFinished); + return; + } + + // Step 4. Otherwise, result is a module script. Fetch the descendants of + // result given destination and an ancestor list obtained by appending url to + // ancestor list. Wait for fetching the descendants of a module script to + // asynchronously complete with descendants result before proceeding to the + // next step. + module_script_ = module_script; + + FetchDescendants(); + + // Note: Step 5- continues in instantiate() method, after + // "fetch the descendants of a module script" procedure completes. +} + +class ModuleTreeLinker::DependencyModuleClient + : public GarbageCollectedFinalized< + ModuleTreeLinker::DependencyModuleClient>, + public ModuleTreeClient { + USING_GARBAGE_COLLECTED_MIXIN(ModuleTreeLinker::DependencyModuleClient); + + public: + static DependencyModuleClient* Create(ModuleTreeLinker* module_tree_linker) { + return new DependencyModuleClient(module_tree_linker); + } + virtual ~DependencyModuleClient() = default; + + DEFINE_INLINE_TRACE() { + visitor->Trace(module_tree_linker_); + ModuleTreeClient::Trace(visitor); + } + + private: + DependencyModuleClient(ModuleTreeLinker* module_tree_linker) + : module_tree_linker_(module_tree_linker) { + CHECK(module_tree_linker); + } + + // Implements ModuleTreeClient + void NotifyModuleTreeLoadFinished(ModuleScript*) override; + + Member<ModuleTreeLinker> module_tree_linker_; +}; + +void ModuleTreeLinker::FetchDescendants() { + CHECK(module_script_); + AdvanceState(State::kFetchingDependencies); + + // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-the-descendants-of-a-module-script + + // Step 1. Let record be module script's module record. + ScriptModule record = module_script_->Record(); + + // Step 2. If record.[[RequestedModules]] is empty, asynchronously complete + // this algorithm with module script. + Vector<String> module_requests = + modulator_->ModuleRequestsFromScriptModule(record); + + // Step 3. Let urls be a new empty list. + HashSet<KURL> urls; + + // Step 4. For each string requested of record.[[RequestedModules]], + for (const auto& module_request : module_requests) { + // Step 4.1. Let url be the result of resolving a module specifier given + // module script and requested. + KURL url = Modulator::ResolveModuleSpecifier(module_request, + module_script_->BaseURL()); + + // Step 4.2. If the result is error: ... + if (url.IsNull()) { + // Let error be a new TypeError exception. + // Report the exception error for module script. + // TODO(kouhei): Implement the exception. + + // Abort this algorithm, and asynchronously complete it with null. + // Note: The return variable for "internal module script graph fetching + // procedure" is descendants_module_script_ per Step 8. + DCHECK(!descendants_module_script_); + // Note: while we complete "fetch the descendants of a module script" + // algorithm here, we still need to continue to the rest of the + // steps in "internal module script graph fetching procedure" + Instantiate(); + return; + } + + // Step 4.3. Otherwise, if ancestor list does not contain url, append url to + // urls. + + // Modulator::resolveModuleSpecifier() impl must return either a valid url + // or null. + CHECK(url.IsValid()); + if (!ancestor_list_with_url_.Contains(url)) + urls.insert(url); + } + + // Step 5. For each url in urls, perform the internal module script graph + // fetching procedure given url, module script's credentials mode, module + // script's cryptographic nonce, module script's parser state, destination, + // module script's settings object, module script's settings object, ancestor + // list, module script's base URL, and with the top-level module fetch flag + // unset. If the caller of this algorithm specified custom perform the fetch + // steps, pass those along while performing the internal module script graph + // fetching procedure. + // TODO(kouhei): handle "destination". + CHECK_EQ(num_incomplete_descendants_, 0u); + if (urls.IsEmpty()) { + // Continue to instantiate() to process "internal module script graph + // fetching procedure" Step 5-. + descendants_module_script_ = module_script_; + Instantiate(); + return; + } + num_incomplete_descendants_ = urls.size(); + for (const KURL& url : urls) { + DependencyModuleClient* dependency_client = + DependencyModuleClient::Create(this); + dependency_clients_.insert(dependency_client); + + ModuleScriptFetchRequest request(url, module_script_->Nonce(), + module_script_->ParserState(), + module_script_->CredentialsMode(), + module_script_->BaseURL().GetString()); + modulator_->FetchTreeInternal(request, ancestor_list_with_url_, + ModuleGraphLevel::kDependentModuleFetch, + dependency_client); + } + + // Asynchronously continue processing after notifyOneDescendantFinished() is + // called m_numIncompleteDescendants times. + CHECK_GT(num_incomplete_descendants_, 0u); +} + +void ModuleTreeLinker::DependencyModuleClient::NotifyModuleTreeLoadFinished( + ModuleScript* module_script) { + DescendantLoad was_success = + !!module_script ? DescendantLoad::kSuccess : DescendantLoad::kFailed; + module_tree_linker_->NotifyOneDescendantFinished(was_success); +} + +void ModuleTreeLinker::NotifyOneDescendantFinished(DescendantLoad was_success) { + CHECK(!descendants_module_script_); + + if (state_ == State::kFinished) { + // We may reach here if one of the descendant failed to load, and the other + // descendants fetches were in flight. + return; + } + CHECK_EQ(state_, State::kFetchingDependencies); + + CHECK_GT(num_incomplete_descendants_, 0u); + --num_incomplete_descendants_; + + // TODO(kouhei): Potential room for optimization. Cancel inflight descendants + // fetch if a descendant load failed. + + CHECK(module_script_); + RESOURCE_LOADING_DVLOG(1) + << "ModuleTreeLinker[" << this << "]::NotifyOneDescendantFinished with " + << (was_success == DescendantLoad::kSuccess ? "success. " : "failure. ") + << num_incomplete_descendants_ << " remaining descendants."; + + // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-the-descendants-of-a-module-script + // Step 5. "... If any of them asynchronously complete with null, then + // asynchronously complete this algorithm with null" + if (was_success == DescendantLoad::kFailed) { + DCHECK(!descendants_module_script_); + // Note: while we complete "fetch the descendants of a module script" + // algorithm here, we still need to continue to the rest of the steps + // in "internal module script graph fetching procedure" + Instantiate(); + return; + } + + // Step 5. "Wait for all of the internal module script graph fetching + // procedure invocations to asynchronously complete..." + if (!num_incomplete_descendants_) { + descendants_module_script_ = module_script_; + Instantiate(); + return; + } +} + +void ModuleTreeLinker::Instantiate() { + CHECK(module_script_); + AdvanceState(State::kInstantiating); + + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + + // Step 5. Let record be result's module record. + ScriptModule record = module_script_->Record(); + + // Step 6. Let instantiationStatus be record.ModuleDeclarationInstantiation(). + // Note: The |error| variable corresponds to spec variable + // "instantiationStatus". If |error| is empty, it indicates successful + // completion. + ScriptValue error = modulator_->InstantiateModule(record); + + // Step 7. For each module script script in result's uninstantiated inclusive + // descendant module scripts, perform the following steps: + HeapHashSet<Member<ModuleScript>> uninstantiated_set = + UninstantiatedInclusiveDescendants(); + for (const auto& descendant : uninstantiated_set) { + if (!error.IsEmpty()) { + // Step 7.1. If instantiationStatus is an abrupt completion, then set + // script's instantiation state to "errored", its instantiation error to + // instantiationStatus.[[Value]], and its module record to null. + descendant->SetInstantiationErrorAndClearRecord(error); + } else { + // Step 7.2. Otherwise, set script's instantiation state to + // "instantiated". + descendant->SetInstantiationSuccess(); + } + } + + // Step 8. Asynchronously complete this algorithm with descendants result. + AdvanceState(State::kFinished); +} + +HeapHashSet<Member<ModuleScript>> +ModuleTreeLinker::UninstantiatedInclusiveDescendants() { + // https://html.spec.whatwg.org/multipage/webappapis.html#uninstantiated-inclusive-descendant-module-scripts + // Step 1. Let moduleMap be script's settings object's module map. + // Note: Modulator is our "settings object". + // Note: We won't reference the ModuleMap directly here to aid testing. + + // Step 2. Let stack be the stack « script ». + // TODO(kouhei): Make stack a HeapLinkedHashSet for O(1) lookups. + HeapDeque<Member<ModuleScript>> stack; + stack.push_front(module_script_); + + // Step 3. Let inclusive descendants be an empty set. + // Note: We use unordered set here as the order is not observable from web + // platform. + // This is allowed per spec: https://infra.spec.whatwg.org/#sets + HeapHashSet<Member<ModuleScript>> inclusive_descendants; + + // Step 4. While stack is not empty: + while (!stack.IsEmpty()) { + // Step 4.1. Let current the result of popping from stack. + ModuleScript* current = stack.TakeFirst(); + + // Step 4.2. Assert: current is a module script (i.e., it is not "fetching" + // or null). + DCHECK(current); + + // Step 4.3. If inclusive descendants and stack both do not contain current, + // then: + if (inclusive_descendants.Contains(current)) + continue; + if (std::find(stack.begin(), stack.end(), current) != stack.end()) + continue; + + // Step 4.3.1. Append current to inclusive descendants. + inclusive_descendants.insert(current); + + // TODO(kouhei): This implementation is a direct transliteration of the + // spec. Omit intermediate vectors at the least. + + // Step 4.3.2. Let child specifiers be the value of current's module + // record's [[RequestedModules]] internal slot. + Vector<String> child_specifiers = + modulator_->ModuleRequestsFromScriptModule(current->Record()); + // Step 4.3.3. Let child URLs be the list obtained by calling resolve a + // module specifier once for each item of child specifiers, given current + // and that item. Omit any failures. + Vector<KURL> child_urls; + for (const auto& child_specifier : child_specifiers) { + KURL child_url = modulator_->ResolveModuleSpecifier(child_specifier, + current->BaseURL()); + if (child_url.IsValid()) + child_urls.push_back(child_url); + } + // Step 4.3.4. Let child modules be the list obtained by getting each value + // in moduleMap whose key is given by an item of child URLs. + HeapVector<Member<ModuleScript>> child_modules; + for (const auto& child_url : child_urls) { + ModuleScript* module_script = + modulator_->GetFetchedModuleScript(child_url); + + child_modules.push_back(module_script); + } + // Step 4.3.5. For each s of child modules: + for (const auto& s : child_modules) { + // Step 4.3.5.2. If s is null, continue. + // Note: We do null check first, as Blink HashSet can't contain nullptr. + // Step 4.3.5.3. Assert: s is a module script (i.e., it is not "fetching", + // since by this point all child modules must have been fetched). Note: + // GetFetchedModuleScript returns nullptr if "fetching" + if (!s) + continue; + + // Step 4.3.5.1. If inclusive descendants already contains s, continue. + if (inclusive_descendants.Contains(s)) + continue; + + // Step 4.3.5.4. Push s onto satck. + stack.push_front(s); + } + } + + // Step 5. Return a set containing all items of inclusive descendants whose + // instantiation state is "uninstantiated". + HeapHashSet<Member<ModuleScript>> uninstantiated_set; + for (const auto& script : inclusive_descendants) { + if (script->InstantiationState() == + ModuleInstantiationState::kUninstantiated) + uninstantiated_set.insert(script); + } + return uninstantiated_set; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinker.h b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinker.h new file mode 100644 index 0000000..6fdd1a1 --- /dev/null +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinker.h
@@ -0,0 +1,94 @@ +// Copyright 2017 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 ModuleTreeLinker_h +#define ModuleTreeLinker_h + +#include "core/CoreExport.h" +#include "core/dom/AncestorList.h" +#include "core/dom/Modulator.h" + +namespace blink { + +class ModuleScriptFetchRequest; +enum class ModuleGraphLevel; +class ModuleTreeLinkerRegistry; + +// A ModuleTreeLinker is responsible for running and keeping intermediate states +// for "internal module script graph fetching procedure" for a module graph tree +// node. +// https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure +class CORE_EXPORT ModuleTreeLinker final + : public GarbageCollectedFinalized<ModuleTreeLinker>, + public SingleModuleClient { + USING_GARBAGE_COLLECTED_MIXIN(ModuleTreeLinker); + + public: + static ModuleTreeLinker* Fetch(const ModuleScriptFetchRequest&, + const AncestorList&, + ModuleGraphLevel, + Modulator*, + ModuleTreeLinkerRegistry*, + ModuleTreeClient*); + virtual ~ModuleTreeLinker() = default; + DECLARE_TRACE(); + + bool IsFetching() const { + return State::kFetchingSelf <= state_ && state_ < State::kFinished; + } + bool HasFinished() const { return state_ == State::kFinished; } + + private: + ModuleTreeLinker(const AncestorList& ancestor_list_with_url, + Modulator*, + ModuleTreeLinkerRegistry*, + ModuleTreeClient*); + + enum class State { + kInitial, + // Running fetch of the module script corresponding to the target node. + kFetchingSelf, + // Running fetch of descendants of the target node. + kFetchingDependencies, + // Instantiating m_moduleScript and the node descendants. + kInstantiating, + kFinished, + }; +#if DCHECK_IS_ON() + static const char* StateToString(State); +#endif + void AdvanceState(State); + + void FetchSelf(const ModuleScriptFetchRequest&, ModuleGraphLevel); + // Implements SingleModuleClient + void NotifyModuleLoadFinished(ModuleScript*) override; + + void FetchDescendants(); + enum class DescendantLoad { kFailed, kSuccess }; + void NotifyOneDescendantFinished(DescendantLoad was_success); + + void Instantiate(); + HeapHashSet<Member<ModuleScript>> UninstantiatedInclusiveDescendants(); + + class DependencyModuleClient; + friend class DependencyModuleClient; + + Member<Modulator> modulator_; + Member<ModuleTreeLinkerRegistry> registry_; + Member<ModuleTreeClient> client_; + HashSet<KURL> ancestor_list_with_url_; + State state_ = State::kInitial; + // Correspond to _result_ in + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + Member<ModuleScript> module_script_; + // Correspond to _descendants result_ in + // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-script-graph-fetching-procedure + Member<ModuleScript> descendants_module_script_; + size_t num_incomplete_descendants_ = 0; + HeapHashSet<Member<DependencyModuleClient>> dependency_clients_; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerRegistry.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerRegistry.cpp new file mode 100644 index 0000000..7c9c6669b --- /dev/null +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerRegistry.cpp
@@ -0,0 +1,39 @@ +// Copyright 2017 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 "core/loader/modulescript/ModuleTreeLinkerRegistry.h" + +#include "core/loader/modulescript/ModuleTreeLinker.h" +#include "platform/weborigin/KURL.h" +#include "platform/weborigin/KURLHash.h" + +namespace blink { + +DEFINE_TRACE(ModuleTreeLinkerRegistry) { + visitor->Trace(active_tree_linkers_); +} + +ModuleTreeLinker* ModuleTreeLinkerRegistry::Fetch( + const ModuleScriptFetchRequest& request, + const AncestorList& ancestor_list, + ModuleGraphLevel level, + Modulator* modulator, + ModuleTreeClient* client) { + ModuleTreeLinker* fetcher = ModuleTreeLinker::Fetch( + request, ancestor_list, level, modulator, this, client); + DCHECK(fetcher->IsFetching()); + active_tree_linkers_.insert(fetcher); + return fetcher; +} + +void ModuleTreeLinkerRegistry::ReleaseFinishedFetcher( + ModuleTreeLinker* fetcher) { + DCHECK(fetcher->HasFinished()); + + auto it = active_tree_linkers_.Find(fetcher); + DCHECK_NE(it, active_tree_linkers_.end()); + active_tree_linkers_.erase(it); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerRegistry.h b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerRegistry.h new file mode 100644 index 0000000..a038896 --- /dev/null +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerRegistry.h
@@ -0,0 +1,46 @@ +// Copyright 2017 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 ModuleTreeLinkerRegistry_h +#define ModuleTreeLinkerRegistry_h + +#include "core/CoreExport.h" +#include "core/dom/AncestorList.h" +#include "platform/heap/Handle.h" + +namespace blink { + +class Modulator; +class ModuleScriptFetchRequest; +class ModuleTreeClient; +class ModuleTreeLinker; +enum class ModuleGraphLevel; + +// ModuleTreeLinkerRegistry keeps active ModuleTreeLinkers alive. +class CORE_EXPORT ModuleTreeLinkerRegistry + : public GarbageCollected<ModuleTreeLinkerRegistry> { + public: + static ModuleTreeLinkerRegistry* Create() { + return new ModuleTreeLinkerRegistry; + } + DECLARE_TRACE(); + + ModuleTreeLinker* Fetch(const ModuleScriptFetchRequest&, + const AncestorList&, + ModuleGraphLevel, + Modulator*, + ModuleTreeClient*); + + private: + ModuleTreeLinkerRegistry() = default; + + friend class ModuleTreeLinker; + void ReleaseFinishedFetcher(ModuleTreeLinker*); + + HeapHashSet<Member<ModuleTreeLinker>> active_tree_linkers_; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerTest.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerTest.cpp new file mode 100644 index 0000000..ef8355dc --- /dev/null +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerTest.cpp
@@ -0,0 +1,451 @@ +// Copyright 2017 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 "core/loader/modulescript/ModuleTreeLinker.h" + +#include "bindings/core/v8/ScriptModule.h" +#include "bindings/core/v8/ScriptState.h" +#include "bindings/core/v8/V8Binding.h" +#include "bindings/core/v8/V8BindingForTesting.h" +#include "bindings/core/v8/V8ThrowException.h" +#include "core/dom/Modulator.h" +#include "core/dom/ModuleScript.h" +#include "core/loader/modulescript/ModuleScriptFetchRequest.h" +#include "core/loader/modulescript/ModuleTreeLinkerRegistry.h" +#include "core/testing/DummyModulator.h" +#include "core/testing/DummyPageHolder.h" +#include "platform/heap/Handle.h" +#include "platform/weborigin/KURL.h" +#include "platform/wtf/text/StringBuilder.h" +#include "public/platform/Platform.h" +#include "public/platform/scheduler/renderer/renderer_scheduler.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +namespace { + +class TestModuleTreeClient final + : public GarbageCollectedFinalized<TestModuleTreeClient>, + public ModuleTreeClient { + USING_GARBAGE_COLLECTED_MIXIN(TestModuleTreeClient); + + public: + TestModuleTreeClient() = default; + + DEFINE_INLINE_TRACE() { visitor->Trace(module_script_); } + + void NotifyModuleTreeLoadFinished(ModuleScript* module_script) override { + was_notify_finished_ = true; + module_script_ = module_script; + } + + bool WasNotifyFinished() const { return was_notify_finished_; } + ModuleScript* GetModuleScript() { return module_script_; } + + private: + bool was_notify_finished_ = false; + Member<ModuleScript> module_script_; +}; + +class ModuleTreeLinkerTestModulator final : public DummyModulator { + public: + ModuleTreeLinkerTestModulator(RefPtr<ScriptState> script_state) + : script_state_(std::move(script_state)) {} + ~ModuleTreeLinkerTestModulator() override {} + + DECLARE_TRACE(); + + enum class ResolveResult { kFailure, kSuccess }; + + // Resolve last |Modulator::FetchSingle()| call. + ModuleScript* ResolveSingleModuleScriptFetch( + const KURL& url, + const Vector<String>& dependency_module_requests) { + ScriptState::Scope scope(script_state_.Get()); + + StringBuilder source_text; + for (const auto& request : dependency_module_requests) { + source_text.Append("import '"); + source_text.Append(request); + source_text.Append("';\n"); + } + source_text.Append("export default 'grapes';"); + + ScriptModule script_module = ScriptModule::Compile( + script_state_->GetIsolate(), source_text.ToString(), url.GetString(), + kSharableCrossOrigin); + ModuleScript* module_script = + ModuleScript::Create(this, script_module, url, "", kParserInserted, + WebURLRequest::kFetchCredentialsModeOmit); + auto result_request = dependency_module_requests_map_.insert( + script_module, dependency_module_requests); + EXPECT_TRUE(result_request.is_new_entry); + auto result_map = module_map_.insert(url, module_script); + EXPECT_TRUE(result_map.is_new_entry); + + EXPECT_EQ(url, pending_request_url_); + EXPECT_TRUE(pending_client_); + pending_client_->NotifyModuleLoadFinished(module_script); + pending_client_.Clear(); + + return module_script; + } + + // Get AncestorList specified in |Modulator::FetchTreeInternal()| call for + // request matching |url|. + AncestorList GetAncestorListForTreeFetch(const KURL& url) const { + const auto& it = pending_tree_ancestor_list_.Find(url); + if (it == pending_tree_ancestor_list_.end()) + return AncestorList(); + return it->value; + } + + // Resolve |Modulator::FetchTreeInternal()| for given url. + void ResolveDependentTreeFetch(const KURL& url, ResolveResult result) { + const auto& it = pending_tree_client_map_.Find(url); + EXPECT_NE(pending_tree_client_map_.end(), it); + auto pending_client = it->value; + EXPECT_TRUE(pending_client); + pending_tree_client_map_.erase(it); + + if (result == ResolveResult::kFailure) { + pending_client->NotifyModuleTreeLoadFinished(nullptr); + return; + } + EXPECT_EQ(ResolveResult::kSuccess, result); + + ScriptState::Scope scope(script_state_.Get()); + + ScriptModule script_module = ScriptModule::Compile( + script_state_->GetIsolate(), "export default 'pineapples';", + url.GetString(), kSharableCrossOrigin); + ModuleScript* module_script = + ModuleScript::Create(this, script_module, url, "", kParserInserted, + WebURLRequest::kFetchCredentialsModeOmit); + auto result_map = module_map_.insert(url, module_script); + EXPECT_TRUE(result_map.is_new_entry); + + pending_client->NotifyModuleTreeLoadFinished(module_script); + } + + void SetInstantiateShouldFail(bool b) { instantiate_should_fail_ = b; } + + private: + // Implements Modulator: + + void FetchSingle(const ModuleScriptFetchRequest& request, + ModuleGraphLevel, + SingleModuleClient* client) override { + pending_request_url_ = request.Url(); + EXPECT_FALSE(pending_client_); + pending_client_ = client; + } + + void FetchTreeInternal(const ModuleScriptFetchRequest& request, + const AncestorList& list, + ModuleGraphLevel level, + ModuleTreeClient* client) override { + const auto& url = request.Url(); + + auto ancestor_result = pending_tree_ancestor_list_.insert(url, list); + EXPECT_TRUE(ancestor_result.is_new_entry); + + EXPECT_EQ(ModuleGraphLevel::kDependentModuleFetch, level); + + auto result_map = pending_tree_client_map_.insert(url, client); + EXPECT_TRUE(result_map.is_new_entry); + } + + ModuleScript* GetFetchedModuleScript(const KURL& url) override { + const auto& it = module_map_.Find(url); + if (it == module_map_.end()) + return nullptr; + + return it->value; + } + + ScriptValue InstantiateModule(ScriptModule) override { + if (instantiate_should_fail_) { + ScriptState::Scope scope(script_state_.Get()); + v8::Local<v8::Value> error = V8ThrowException::CreateError( + script_state_->GetIsolate(), "Instantiation failure."); + return ScriptValue(script_state_.Get(), error); + } + return ScriptValue(); + } + + Vector<String> ModuleRequestsFromScriptModule( + ScriptModule script_module) override { + const auto& it = dependency_module_requests_map_.Find(script_module); + if (it == dependency_module_requests_map_.end()) + return Vector<String>(); + + return it->value; + } + + RefPtr<ScriptState> script_state_; + KURL pending_request_url_; + Member<SingleModuleClient> pending_client_; + HashMap<ScriptModule, Vector<String>> dependency_module_requests_map_; + HeapHashMap<KURL, Member<ModuleScript>> module_map_; + HeapHashMap<KURL, Member<ModuleTreeClient>> pending_tree_client_map_; + HashMap<KURL, AncestorList> pending_tree_ancestor_list_; + bool instantiate_should_fail_ = false; +}; + +DEFINE_TRACE(ModuleTreeLinkerTestModulator) { + visitor->Trace(pending_client_); + visitor->Trace(module_map_); + visitor->Trace(pending_tree_client_map_); + DummyModulator::Trace(visitor); +} + +} // namespace + +class ModuleTreeLinkerTest : public ::testing::Test { + DISALLOW_COPY_AND_ASSIGN(ModuleTreeLinkerTest); + + public: + ModuleTreeLinkerTest() = default; + void SetUp() override; + + ModuleTreeLinkerTestModulator* GetModulator() { return modulator_.Get(); } + + protected: + std::unique_ptr<DummyPageHolder> dummy_page_holder_; + Persistent<ModuleTreeLinkerTestModulator> modulator_; +}; + +void ModuleTreeLinkerTest::SetUp() { + dummy_page_holder_ = DummyPageHolder::Create(IntSize(500, 500)); + RefPtr<ScriptState> script_state = + ToScriptStateForMainWorld(&dummy_page_holder_->GetFrame()); + modulator_ = new ModuleTreeLinkerTestModulator(script_state); +} + +TEST_F(ModuleTreeLinkerTest, fetchTreeNoDeps) { + ModuleTreeLinkerRegistry* registry = ModuleTreeLinkerRegistry::Create(); + + KURL url(kParsedURLString, "http://example.com/root.js"); + ModuleScriptFetchRequest module_request( + url, String(), kParserInserted, WebURLRequest::kFetchCredentialsModeOmit); + TestModuleTreeClient* client = new TestModuleTreeClient; + registry->Fetch(module_request, AncestorList(), + ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(), + client); + + EXPECT_FALSE(client->WasNotifyFinished()) + << "ModuleTreeLinker should always finish asynchronously."; + EXPECT_FALSE(client->GetModuleScript()); + + GetModulator()->ResolveSingleModuleScriptFetch(url, {}); + EXPECT_TRUE(client->WasNotifyFinished()); + ASSERT_TRUE(client->GetModuleScript()); + EXPECT_EQ(client->GetModuleScript()->InstantiationState(), + ModuleInstantiationState::kInstantiated); +} + +TEST_F(ModuleTreeLinkerTest, fetchTreeInstantiationFailure) { + GetModulator()->SetInstantiateShouldFail(true); + + ModuleTreeLinkerRegistry* registry = ModuleTreeLinkerRegistry::Create(); + + KURL url(kParsedURLString, "http://example.com/root.js"); + ModuleScriptFetchRequest module_request( + url, String(), kParserInserted, WebURLRequest::kFetchCredentialsModeOmit); + TestModuleTreeClient* client = new TestModuleTreeClient; + registry->Fetch(module_request, AncestorList(), + ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(), + client); + + EXPECT_FALSE(client->WasNotifyFinished()) + << "ModuleTreeLinker should always finish asynchronously."; + EXPECT_FALSE(client->GetModuleScript()); + + GetModulator()->ResolveSingleModuleScriptFetch(url, {}); + EXPECT_TRUE(client->WasNotifyFinished()); + ASSERT_TRUE(client->GetModuleScript()); + EXPECT_EQ(client->GetModuleScript()->InstantiationState(), + ModuleInstantiationState::kErrored); +} + +TEST_F(ModuleTreeLinkerTest, fetchTreeWithSingleDependency) { + ModuleTreeLinkerRegistry* registry = ModuleTreeLinkerRegistry::Create(); + + KURL url(kParsedURLString, "http://example.com/root.js"); + ModuleScriptFetchRequest module_request( + url, String(), kParserInserted, WebURLRequest::kFetchCredentialsModeOmit); + TestModuleTreeClient* client = new TestModuleTreeClient; + registry->Fetch(module_request, AncestorList(), + ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(), + client); + + EXPECT_FALSE(client->WasNotifyFinished()) + << "ModuleTreeLinker should always finish asynchronously."; + EXPECT_FALSE(client->GetModuleScript()); + + GetModulator()->ResolveSingleModuleScriptFetch(url, {"./dep1.js"}); + EXPECT_FALSE(client->WasNotifyFinished()); + + KURL url_dep1(kParsedURLString, "http://example.com/dep1.js"); + auto ancestor_list = GetModulator()->GetAncestorListForTreeFetch(url_dep1); + EXPECT_EQ(1u, ancestor_list.size()); + EXPECT_TRUE(ancestor_list.Contains( + KURL(kParsedURLString, "http://example.com/root.js"))); + + GetModulator()->ResolveDependentTreeFetch( + url_dep1, ModuleTreeLinkerTestModulator::ResolveResult::kSuccess); + EXPECT_TRUE(client->WasNotifyFinished()); + + ASSERT_TRUE(client->GetModuleScript()); + EXPECT_EQ(client->GetModuleScript()->InstantiationState(), + ModuleInstantiationState::kInstantiated); +} + +TEST_F(ModuleTreeLinkerTest, fetchTreeWith3Deps) { + ModuleTreeLinkerRegistry* registry = ModuleTreeLinkerRegistry::Create(); + + KURL url(kParsedURLString, "http://example.com/root.js"); + ModuleScriptFetchRequest module_request( + url, String(), kParserInserted, WebURLRequest::kFetchCredentialsModeOmit); + TestModuleTreeClient* client = new TestModuleTreeClient; + registry->Fetch(module_request, AncestorList(), + ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(), + client); + + EXPECT_FALSE(client->WasNotifyFinished()) + << "ModuleTreeLinker should always finish asynchronously."; + EXPECT_FALSE(client->GetModuleScript()); + + GetModulator()->ResolveSingleModuleScriptFetch( + url, {"./dep1.js", "./dep2.js", "./dep3.js"}); + EXPECT_FALSE(client->WasNotifyFinished()); + + Vector<KURL> url_deps; + for (int i = 1; i <= 3; ++i) { + StringBuilder url_dep_str; + url_dep_str.Append("http://example.com/dep"); + url_dep_str.AppendNumber(i); + url_dep_str.Append(".js"); + + KURL url_dep(kParsedURLString, url_dep_str.ToString()); + url_deps.push_back(url_dep); + } + + for (const auto& url_dep : url_deps) { + SCOPED_TRACE(url_dep.GetString()); + auto ancestor_list = GetModulator()->GetAncestorListForTreeFetch(url_dep); + EXPECT_EQ(1u, ancestor_list.size()); + EXPECT_TRUE(ancestor_list.Contains( + KURL(kParsedURLString, "http://example.com/root.js"))); + } + + for (const auto& url_dep : url_deps) { + EXPECT_FALSE(client->WasNotifyFinished()); + GetModulator()->ResolveDependentTreeFetch( + url_dep, ModuleTreeLinkerTestModulator::ResolveResult::kSuccess); + } + + EXPECT_TRUE(client->WasNotifyFinished()); + ASSERT_TRUE(client->GetModuleScript()); + EXPECT_EQ(client->GetModuleScript()->InstantiationState(), + ModuleInstantiationState::kInstantiated); +} + +TEST_F(ModuleTreeLinkerTest, fetchTreeWith3Deps1Fail) { + ModuleTreeLinkerRegistry* registry = ModuleTreeLinkerRegistry::Create(); + + KURL url(kParsedURLString, "http://example.com/root.js"); + ModuleScriptFetchRequest module_request( + url, String(), kParserInserted, WebURLRequest::kFetchCredentialsModeOmit); + TestModuleTreeClient* client = new TestModuleTreeClient; + registry->Fetch(module_request, AncestorList(), + ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(), + client); + + EXPECT_FALSE(client->WasNotifyFinished()) + << "ModuleTreeLinker should always finish asynchronously."; + EXPECT_FALSE(client->GetModuleScript()); + + GetModulator()->ResolveSingleModuleScriptFetch( + url, {"./dep1.js", "./dep2.js", "./dep3.js"}); + EXPECT_FALSE(client->WasNotifyFinished()); + + Vector<KURL> url_deps; + for (int i = 1; i <= 3; ++i) { + StringBuilder url_dep_str; + url_dep_str.Append("http://example.com/dep"); + url_dep_str.AppendNumber(i); + url_dep_str.Append(".js"); + + KURL url_dep(kParsedURLString, url_dep_str.ToString()); + url_deps.push_back(url_dep); + } + + for (const auto& url_dep : url_deps) { + SCOPED_TRACE(url_dep.GetString()); + auto ancestor_list = GetModulator()->GetAncestorListForTreeFetch(url_dep); + EXPECT_EQ(1u, ancestor_list.size()); + EXPECT_TRUE(ancestor_list.Contains( + KURL(kParsedURLString, "http://example.com/root.js"))); + } + + auto url_dep = url_deps.back(); + url_deps.pop_back(); + GetModulator()->ResolveDependentTreeFetch( + url_dep, ModuleTreeLinkerTestModulator::ResolveResult::kSuccess); + EXPECT_FALSE(client->WasNotifyFinished()); + url_dep = url_deps.back(); + url_deps.pop_back(); + GetModulator()->ResolveDependentTreeFetch( + url_dep, ModuleTreeLinkerTestModulator::ResolveResult::kFailure); + + EXPECT_TRUE(client->WasNotifyFinished()); + EXPECT_FALSE(client->GetModuleScript()); + + // Check below doesn't crash. + url_dep = url_deps.back(); + url_deps.pop_back(); + GetModulator()->ResolveDependentTreeFetch( + url_dep, ModuleTreeLinkerTestModulator::ResolveResult::kSuccess); + EXPECT_TRUE(url_deps.IsEmpty()); +} + +TEST_F(ModuleTreeLinkerTest, fetchDependencyTree) { + ModuleTreeLinkerRegistry* registry = ModuleTreeLinkerRegistry::Create(); + + KURL url(kParsedURLString, "http://example.com/depth1.js"); + ModuleScriptFetchRequest module_request( + url, String(), kParserInserted, WebURLRequest::kFetchCredentialsModeOmit); + TestModuleTreeClient* client = new TestModuleTreeClient; + registry->Fetch( + module_request, + AncestorList{KURL(kParsedURLString, "http://example.com/root.js")}, + ModuleGraphLevel::kDependentModuleFetch, GetModulator(), client); + + EXPECT_FALSE(client->WasNotifyFinished()) + << "ModuleTreeLinker should always finish asynchronously."; + EXPECT_FALSE(client->GetModuleScript()); + + GetModulator()->ResolveSingleModuleScriptFetch(url, {"./depth2.js"}); + + KURL url_dep2(kParsedURLString, "http://example.com/depth2.js"); + auto ancestor_list = GetModulator()->GetAncestorListForTreeFetch(url_dep2); + EXPECT_EQ(2u, ancestor_list.size()); + EXPECT_TRUE(ancestor_list.Contains( + KURL(kParsedURLString, "http://example.com/root.js"))); + EXPECT_TRUE(ancestor_list.Contains( + KURL(kParsedURLString, "http://example.com/depth1.js"))); + + GetModulator()->ResolveDependentTreeFetch( + url_dep2, ModuleTreeLinkerTestModulator::ResolveResult::kSuccess); + + EXPECT_TRUE(client->WasNotifyFinished()); + ASSERT_TRUE(client->GetModuleScript()); + EXPECT_EQ(client->GetModuleScript()->InstantiationState(), + ModuleInstantiationState::kInstantiated); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/page/EventWithHitTestResults.h b/third_party/WebKit/Source/core/page/EventWithHitTestResults.h index 0b1c2f44..c967ea65 100644 --- a/third_party/WebKit/Source/core/page/EventWithHitTestResults.h +++ b/third_party/WebKit/Source/core/page/EventWithHitTestResults.h
@@ -47,6 +47,7 @@ return hit_test_result_.IsOverFrameViewBase(); } Node* InnerNode() const { return hit_test_result_.InnerNode(); } + Element* InnerElement() const { return hit_test_result_.InnerElement(); } const String& CanvasRegionId() const { return hit_test_result_.CanvasRegionId(); }
diff --git a/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp b/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp index fdb7993..f0fae6b 100644 --- a/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp
@@ -59,7 +59,7 @@ return AdoptRef(new Canvas2DLayerBridge( WTF::WrapUnique(new FakeWebGraphicsContext3DProvider(&gl_)), size, 0, kNonOpaque, Canvas2DLayerBridge::kForceAccelerationForTesting, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType)); + CanvasColorParams())); } private:
diff --git a/third_party/WebKit/Source/core/streams/WritableStream.js b/third_party/WebKit/Source/core/streams/WritableStream.js index 4a4429c..f12192b 100644 --- a/third_party/WebKit/Source/core/streams/WritableStream.js +++ b/third_party/WebKit/Source/core/streams/WritableStream.js
@@ -41,14 +41,16 @@ const _strategySize = v8.createPrivateSymbol('[[strategySize]]'); const _underlyingSink = v8.createPrivateSymbol('[[underlyingSink]]'); - // Numeric encodings of states + // Numeric encodings of stream states. Stored in the _stateAndFlags slot. const WRITABLE = 0; const CLOSED = 1; - const ERRORED = 2; + const ERRORING = 2; + const ERRORED = 3; - // Mask to extract or assign states to _stateAndFlags + // Mask to extract or assign states to _stateAndFlags. const STATE_MASK = 0xF; + // Also stored in _stateAndFlags. const BACKPRESSURE_FLAG = 0x10; // Javascript functions. It is important to use these copies, as the ones on @@ -105,8 +107,8 @@ const stateNames = {[CLOSED]: 'closed', [ERRORED]: 'errored'}; function createCannotActionOnStateStreamError(action, state) { - TEMP_ASSERT(stateNames[state] !== undefined, - `name for state ${state} exists in stateNames`); + // assert(stateNames[state] !== undefined, + // `name for state ${state} exists in stateNames`); return new TypeError( templateErrorCannotActionOnStateStream(action, stateNames[state])); } @@ -115,27 +117,6 @@ queue.forEach(promise => v8.rejectPromise(promise, e)); } - // https://tc39.github.io/ecma262/#sec-ispropertykey - // TODO(ricea): Remove this when the asserts using it are removed. - function IsPropertyKey(argument) { - return typeof argument === 'string' || typeof argument === 'symbol'; - } - - // TODO(ricea): Remove all asserts once the implementation has stabilised. - function TEMP_ASSERT(predicate, message) { - if (predicate) { - return; - } - v8.log(`Assertion failed: ${message}\n`); - v8.logStackTrace(); - class WritableStreamInternalError extends Error { - constructor(message) { - super(message); - } - } - throw new WritableStreamInternalError(message); - } - class WritableStream { constructor(underlyingSink = {}, { size, highWaterMark = 1 } = {}) { this[_stateAndFlags] = WRITABLE; @@ -193,8 +174,8 @@ } function IsWritableStreamLocked(stream) { - TEMP_ASSERT(IsWritableStream(stream), - '! IsWritableStream(stream) is true.'); + // assert(IsWritableStream(stream), + // '! IsWritableStream(stream) is true.'); return stream[_writer] !== undefined; } @@ -206,136 +187,184 @@ if (state === ERRORED) { return Promise_reject(stream[_storedError]); } - TEMP_ASSERT(state === WRITABLE, - 'state is "writable".'); const error = new TypeError(errStreamAborting); if (stream[_pendingAbortRequest] !== undefined) { return Promise_reject(error); } - const controller = stream[_writableStreamController]; - TEMP_ASSERT(controller !== undefined, - 'controller is not undefined'); - if (!WritableStreamHasOperationMarkedInFlight(stream) && - controller[_started]) { - WritableStreamFinishAbort(stream); - return WritableStreamDefaultControllerAbortSteps(controller, reason); + // assert(state === WRITABLE || state === ERRORING, + // '_state_ is `"writable"` or `"erroring"`'); + + const wasAlreadyErroring = state === ERRORING; + if (wasAlreadyErroring) { + reason = undefined; } - const writer = stream[_writer]; - if (writer !== undefined) { - WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error); - } + const promise = v8.createPromise(); - stream[_pendingAbortRequest] = {promise, reason}; + stream[_pendingAbortRequest] = {promise, reason, wasAlreadyErroring}; + + if (!wasAlreadyErroring) { + WritableStreamStartErroring(stream, error); + } return promise; } - function WritableStreamError(stream, error) { - stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORED; - stream[_storedError] = error; - WritableStreamDefaultControllerErrorSteps(stream[_writableStreamController]); - if (stream[_pendingAbortRequest] === undefined) { - const writer = stream[_writer]; - if (writer !== undefined) { - WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error); - } - } - if (!WritableStreamHasOperationMarkedInFlight(stream)) { - WritableStreamRejectPromisesInReactionToError(stream); - } - } - - function WritableStreamFinishAbort(stream) { - const error = new TypeError(errStreamAborted); - WritableStreamError(stream, error); - } - // Writable Stream Abstract Operations Used by Controllers function WritableStreamAddWriteRequest(stream) { - TEMP_ASSERT(IsWritableStreamLocked(stream), - '! IsWritableStreamLocked(writer) is true.'); - TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, - 'stream.[[state]] is "writable".'); + // assert(IsWritableStreamLocked(stream), + // '! IsWritableStreamLocked(writer) is true.'); + // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, + // 'stream.[[state]] is "writable".'); const promise = v8.createPromise(); stream[_writeRequests].push(promise); return promise; } - function WritableStreamFinishInFlightWrite(stream) { - TEMP_ASSERT(stream[_inFlightWriteRequest] !== undefined, - '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); - v8.resolvePromise(stream[_inFlightWriteRequest], undefined); - stream[_inFlightWriteRequest] = undefined; + function WritableStreamDealWithRejection(stream, error) { const state = stream[_stateAndFlags] & STATE_MASK; - if (state === ERRORED) { - WritableStreamFinishInFlightWriteInErroredState(stream); + if (state === WRITABLE) { + WritableStreamStartErroring(stream, error); return; } - TEMP_ASSERT(state === WRITABLE, '_state_ is `"writable"`.'); - WritableStreamHandleAbortRequestIfPending(stream); + + // assert(state === ERRORING, '_state_ is `"erroring"`'); + WritableStreamFinishErroring(stream); } - function WritableStreamFinishInFlightWriteInErroredState(stream) { - WritableStreamRejectAbortRequestIfPending(stream); - WritableStreamRejectPromisesInReactionToError(stream); + function WritableStreamStartErroring(stream, reason) { + // assert(stream[_storedError] === undefined, + // '_stream_.[[storedError]] is *undefined*'); + // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, + // '_stream_.[[state]] is `"writable"`'); + + const controller = stream[_writableStreamController]; + // assert(controller !== undefined, '_controller_ is not *undefined*'); + + stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORING; + stream[_storedError] = reason; + + const writer = stream[_writer]; + if (writer !== undefined) { + WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason); + } + + if (!WritableStreamHasOperationMarkedInFlight(stream) && + controller[_started]) { + WritableStreamFinishErroring(stream); + } + } + + function WritableStreamFinishErroring(stream) { + // assert((stream[_stateAndFlags] & STATE_MASK) === ERRORING, + // '_stream_.[[state]] is `"erroring"`'); + // assert(!WritableStreamHasOperationMarkedInFlight(stream), + // '! WritableStreamHasOperationMarkedInFlight(_stream_) is *false*'); + + stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORED; + + WritableStreamDefaultControllerErrorSteps( + stream[_writableStreamController]); + + const storedError = stream[_storedError]; + rejectPromises(stream[_writeRequests], storedError); + stream[_writeRequests] = new binding.SimpleQueue(); + + if (stream[_pendingAbortRequest] === undefined) { + WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); + return; + } + + const abortRequest = stream[_pendingAbortRequest]; + stream[_pendingAbortRequest] = undefined; + + if (abortRequest.wasAlreadyErroring === true) { + v8.rejectPromise(abortRequest.promise, storedError); + WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); + return; + } + + const promise = WritableStreamDefaultControllerAbortSteps( + stream[_writableStreamController], abortRequest.reason); + + thenPromise( + promise, + () => { + v8.resolvePromise(abortRequest.promise, undefined); + WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); + }, + reason => { + v8.rejectPromise(abortRequest.promise, reason); + WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); + }); + } + + function WritableStreamFinishInFlightWrite(stream) { + // assert(stream[_inFlightWriteRequest] !== undefined, + // '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); + v8.resolvePromise(stream[_inFlightWriteRequest], undefined); + stream[_inFlightWriteRequest] = undefined; } function WritableStreamFinishInFlightWriteWithError(stream, error) { - TEMP_ASSERT(stream[_inFlightWriteRequest] !== undefined, - '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); + // assert(stream[_inFlightWriteRequest] !== undefined, + // '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); v8.rejectPromise(stream[_inFlightWriteRequest], error); stream[_inFlightWriteRequest] = undefined; - const state = stream[_stateAndFlags] & STATE_MASK; - if (state === ERRORED) { - WritableStreamFinishInFlightWriteInErroredState(stream); - return; - } - TEMP_ASSERT(state === WRITABLE, '_state_ is `"writable"`.'); - WritableStreamError(stream, error); - WritableStreamRejectAbortRequestIfPending(stream); + + let state = stream[_stateAndFlags] & STATE_MASK; + // assert(state === WRITABLE || state === ERRORING, + // '_stream_.[[state]] is `"writable"` or `"erroring"`'); + + WritableStreamDealWithRejection(stream, error); } function WritableStreamFinishInFlightClose(stream) { - TEMP_ASSERT(stream[_inFlightCloseRequest] !== undefined, - '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); + // assert(stream[_inFlightCloseRequest] !== undefined, + // '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); v8.resolvePromise(stream[_inFlightCloseRequest], undefined); stream[_inFlightCloseRequest] = undefined; + const state = stream[_stateAndFlags] & STATE_MASK; - if (state === ERRORED) { - WritableStreamFinishInFlightCloseInErroredState(stream); - return; + // assert(state === WRITABLE || state === ERRORING, + // '_stream_.[[state]] is `"writable"` or `"erroring"`'); + + if (state === ERRORING) { + stream[_storedError] = undefined; + if (stream[_pendingAbortRequest] !== undefined) { + v8.resolvePromise(stream[_pendingAbortRequest].promise, undefined); + stream[_pendingAbortRequest] = undefined; + } } - TEMP_ASSERT(state === WRITABLE, '_state_ is `"writable"`.'); + stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | CLOSED; const writer = stream[_writer]; if (writer !== undefined) { v8.resolvePromise(writer[_closedPromise], undefined); } - if (stream[_pendingAbortRequest] !== undefined) { - v8.resolvePromise(stream[_pendingAbortRequest].promise, undefined); - stream[_pendingAbortRequest] = undefined; - } - } - function WritableStreamFinishInFlightCloseInErroredState(stream) { - WritableStreamRejectAbortRequestIfPending(stream); - WritableStreamRejectClosedPromiseInReactionToError(stream); + // assert(stream[_pendingAbortRequest] === undefined, + // '_stream_.[[pendingAbortRequest]] is *undefined*'); + // assert(stream[_storedError] === undefined, + // '_stream_.[[storedError]] is *undefined*'); } function WritableStreamFinishInFlightCloseWithError(stream, error) { - TEMP_ASSERT(stream[_inFlightCloseRequest] !== undefined, - '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); + // assert(stream[_inFlightCloseRequest] !== undefined, + // '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); v8.rejectPromise(stream[_inFlightCloseRequest], error); stream[_inFlightCloseRequest] = undefined; + const state = stream[_stateAndFlags] & STATE_MASK; - if (state === ERRORED) { - WritableStreamFinishInFlightCloseInErroredState(stream); - return; + // assert(state === WRITABLE || state === ERRORING, + // '_stream_.[[state]] is `"writable"` or `"erroring"`'); + + if (stream[_pendingAbortRequest] !== undefined) { + v8.rejectPromise(stream[_pendingAbortRequest].promise, error); + stream[_pendingAbortRequest] = undefined; } - TEMP_ASSERT(state === WRITABLE, '_state_ is `"writable"`.'); - WritableStreamError(stream, error); - WritableStreamRejectAbortRequestIfPending(stream); + + WritableStreamDealWithRejection(stream, error); } function WritableStreamCloseQueuedOrInFlight(stream) { @@ -343,45 +372,40 @@ stream[_inFlightCloseRequest] !== undefined; } - function WritableStreamHandleAbortRequestIfPending(stream) { - if (stream[_pendingAbortRequest] === undefined) { - return; - } - WritableStreamFinishAbort(stream); - const abortRequest = stream[_pendingAbortRequest]; - stream[_pendingAbortRequest] = undefined; - const promise = - WritableStreamDefaultControllerAbortSteps(stream[_writableStreamController], - abortRequest.reason); - thenPromise(promise, - result => v8.resolvePromise(abortRequest.promise, result), - reason => v8.rejectPromise(abortRequest.promise, reason)); - } - function WritableStreamHasOperationMarkedInFlight(stream) { return stream[_inFlightWriteRequest] !== undefined || stream[_inFlightCloseRequest] !== undefined; } function WritableStreamMarkCloseRequestInFlight(stream) { - TEMP_ASSERT(stream[_inFlightCloseRequest] === undefined, - '_stream_.[[inFlightCloseRequest]] is *undefined*.'); - TEMP_ASSERT(stream[_closeRequest] !== undefined, - '_stream_.[[closeRequest]] is not *undefined*.'); + // assert(stream[_inFlightCloseRequest] === undefined, + // '_stream_.[[inFlightCloseRequest]] is *undefined*.'); + // assert(stream[_closeRequest] !== undefined, + // '_stream_.[[closeRequest]] is not *undefined*.'); stream[_inFlightCloseRequest] = stream[_closeRequest]; stream[_closeRequest] = undefined; } function WritableStreamMarkFirstWriteRequestInFlight(stream) { - TEMP_ASSERT(stream[_inFlightWriteRequest] === undefined, - '_stream_.[[inFlightWriteRequest]] is *undefined*.'); - TEMP_ASSERT(stream[_writeRequests].length !== 0, - '_stream_.[[writeRequests]] is not empty.'); + // assert(stream[_inFlightWriteRequest] === undefined, + // '_stream_.[[inFlightWriteRequest]] is *undefined*.'); + // assert(stream[_writeRequests].length !== 0, + // '_stream_.[[writeRequests]] is not empty.'); const writeRequest = stream[_writeRequests].shift(); stream[_inFlightWriteRequest] = writeRequest; } - function WritableStreamRejectClosedPromiseInReactionToError(stream) { + function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) { + // assert((stream[_stateAndFlags] & STATE_MASK) === ERRORED, + // '_stream_.[[state]] is `"errored"`'); + + if (stream[_closeRequest] !== undefined) { + // assert(stream[_inFlightCloseRequest] === undefined, + // '_stream_.[[inFlightCloseRequest]] is *undefined*'); + v8.rejectPromise(stream[_closeRequest], stream[_storedError]); + stream[_closeRequest] = undefined; + } + const writer = stream[_writer]; if (writer !== undefined) { v8.rejectPromise(writer[_closedPromise], stream[_storedError]); @@ -389,41 +413,18 @@ } } - function WritableStreamRejectAbortRequestIfPending(stream) { - if (stream[_pendingAbortRequest] !== undefined) { - v8.rejectPromise(stream[_pendingAbortRequest].promise, - stream[_storedError]); - stream[_pendingAbortRequest] = undefined; - } - } - - function WritableStreamRejectPromisesInReactionToError(stream) { - const storedError = stream[_storedError]; - rejectPromises(stream[_writeRequests], storedError); - stream[_writeRequests] = new binding.SimpleQueue(); - - if (stream[_closeRequest] !== undefined) { - TEMP_ASSERT(stream[_inFlightCloseRequest] === undefined, - '_stream_.[[inFlightCloseRequest]] is *undefined*.'); - v8.rejectPromise(stream[_closeRequest], storedError); - stream[_closeRequest] = undefined; - } - - WritableStreamRejectClosedPromiseInReactionToError(stream); - } - function WritableStreamUpdateBackpressure(stream, backpressure) { - TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, - 'stream.[[state]] is "writable".'); - TEMP_ASSERT(!WritableStreamCloseQueuedOrInFlight(stream), - 'WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); + // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, + // 'stream.[[state]] is "writable".'); + // assert(!WritableStreamCloseQueuedOrInFlight(stream), + // 'WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); const writer = stream[_writer]; if (writer !== undefined && backpressure !== Boolean(stream[_stateAndFlags] & BACKPRESSURE_FLAG)) { if (backpressure) { writer[_readyPromise] = v8.createPromise(); } else { - TEMP_ASSERT(!backpressure, '_backpressure_ is *false*.'); + // assert(!backpressure, '_backpressure_ is *false*.'); v8.resolvePromise(writer[_readyPromise], undefined); } } @@ -437,21 +438,21 @@ // Functions to expose internals for ReadableStream.pipeTo. These are not // part of the standard. function isWritableStreamErrored(stream) { - TEMP_ASSERT( - IsWritableStream(stream), '! IsWritableStream(stream) is true.'); + // assert( + // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); return (stream[_stateAndFlags] & STATE_MASK) === ERRORED; } function isWritableStreamClosingOrClosed(stream) { - TEMP_ASSERT( - IsWritableStream(stream), '! IsWritableStream(stream) is true.'); + // assert( + // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); return WritableStreamCloseQueuedOrInFlight(stream) || (stream[_stateAndFlags] & STATE_MASK) === CLOSED; } function getWritableStreamStoredError(stream) { - TEMP_ASSERT( - IsWritableStream(stream), '! IsWritableStream(stream) is true.'); + // assert( + // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); return stream[_storedError]; } @@ -466,28 +467,44 @@ this[_ownerWritableStream] = stream; stream[_writer] = this; const state = stream[_stateAndFlags] & STATE_MASK; - if (state === WRITABLE) { - if (stream[_pendingAbortRequest] !== undefined) { - const error = new TypeError(errStreamAborting); - this[_readyPromise] = Promise_reject(error); - v8.markPromiseAsHandled(this[_readyPromise]); - } else if (!WritableStreamCloseQueuedOrInFlight(stream) && - stream[_stateAndFlags] & BACKPRESSURE_FLAG) { - this[_readyPromise] = v8.createPromise(); - } else { - this[_readyPromise] = Promise_resolve(undefined); + switch (state) { + case WRITABLE: + { + if (!WritableStreamCloseQueuedOrInFlight(stream) && + stream[_stateAndFlags] & BACKPRESSURE_FLAG) { + this[_readyPromise] = v8.createPromise(); + } else { + this[_readyPromise] = Promise_resolve(undefined); + } + this[_closedPromise] = v8.createPromise(); + break; } - this[_closedPromise] = v8.createPromise(); - } else if (state === CLOSED) { - this[_readyPromise] = Promise_resolve(undefined); - this[_closedPromise] = Promise_resolve(undefined); - } else { - TEMP_ASSERT(state === ERRORED, '_state_ is `"errored"`.'); - const storedError = stream[_storedError]; - this[_readyPromise] = Promise_reject(storedError); - v8.markPromiseAsHandled(this[_readyPromise]); - this[_closedPromise] = Promise_reject(storedError); - v8.markPromiseAsHandled(this[_closedPromise]); + + case ERRORING: + { + this[_readyPromise] = Promise_reject(stream[_storedError]); + v8.markPromiseAsHandled(this[_readyPromise]); + this[_closedPromise] = v8.createPromise(); + break; + } + + case CLOSED: + { + this[_readyPromise] = Promise_resolve(undefined); + this[_closedPromise] = Promise_resolve(undefined); + break; + } + + default: + { + // assert(state === ERRORED, '_state_ is `"errored"`.'); + const storedError = stream[_storedError]; + this[_readyPromise] = Promise_reject(storedError); + v8.markPromiseAsHandled(this[_readyPromise]); + this[_closedPromise] = Promise_reject(storedError); + v8.markPromiseAsHandled(this[_closedPromise]); + break; + } } } @@ -547,8 +564,8 @@ if (stream === undefined) { return; } - TEMP_ASSERT(stream[_writer] !== undefined, - 'stream.[[writer]] is not undefined.'); + // assert(stream[_writer] !== undefined, + // 'stream.[[writer]] is not undefined.'); WritableStreamDefaultWriterRelease(this); } @@ -571,28 +588,29 @@ function WritableStreamDefaultWriterAbort(writer, reason) { const stream = writer[_ownerWritableStream]; - TEMP_ASSERT(stream !== undefined, - 'stream is not undefined.'); + // assert(stream !== undefined, + // 'stream is not undefined.'); return WritableStreamAbort(stream, reason); } function WritableStreamDefaultWriterClose(writer) { const stream = writer[_ownerWritableStream]; - TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); + // assert(stream !== undefined, 'stream is not undefined.'); const state = stream[_stateAndFlags] & STATE_MASK; if (state === CLOSED || state === ERRORED) { return Promise_reject( createCannotActionOnStateStreamError('close', state)); } - if (stream[_pendingAbortRequest] !== undefined) { - return Promise_reject(new TypeError(errStreamAborting)); - } - TEMP_ASSERT(state === WRITABLE, '_state_ is `"writable"`.'); - TEMP_ASSERT(!WritableStreamCloseQueuedOrInFlight(stream), - '! WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); + + // assert(state === WRITABLE || state === ERRORING, + // '_state_ is `"writable"` or `"erroring"`.'); + // assert(!WritableStreamCloseQueuedOrInFlight(stream), + // '! WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); const promise = v8.createPromise(); stream[_closeRequest] = promise; - if (stream[_stateAndFlags] & BACKPRESSURE_FLAG) { + + if ((stream[_stateAndFlags] & BACKPRESSURE_FLAG) && + state === WRITABLE) { v8.resolvePromise(writer[_readyPromise], undefined); } WritableStreamDefaultControllerClose(stream[_writableStreamController]); @@ -601,7 +619,7 @@ function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { const stream = writer[_ownerWritableStream]; - TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); + // assert(stream !== undefined, 'stream is not undefined.'); const state = stream[_stateAndFlags] & STATE_MASK; if (WritableStreamCloseQueuedOrInFlight(stream) || state === CLOSED) { return Promise_resolve(undefined); @@ -609,12 +627,26 @@ if (state === ERRORED) { return Promise_reject(stream[_storedError]); } - TEMP_ASSERT(state === WRITABLE, 'state is "writable".'); + + // assert(state === WRITABLE || state === ERRORING, + // '_state_ is `"writable"` or `"erroring"`.'); + return WritableStreamDefaultWriterClose(writer); } - function WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, - error) { + function WritableStreamDefaultWriterEnsureClosedPromiseRejected( + writer, error) { + if (v8.promiseState(writer[_closedPromise]) === v8.kPROMISE_PENDING) { + v8.rejectPromise(writer[_closedPromise], error); + } else { + writer[_closedPromise] = Promise_reject(error); + } + v8.markPromiseAsHandled(writer[_closedPromise]); + } + + + function WritableStreamDefaultWriterEnsureReadyPromiseRejected( + writer, error) { if (v8.promiseState(writer[_readyPromise]) === v8.kPROMISE_PENDING) { v8.rejectPromise(writer[_readyPromise], error); } else { @@ -626,7 +658,7 @@ function WritableStreamDefaultWriterGetDesiredSize(writer) { const stream = writer[_ownerWritableStream]; const state = stream[_stateAndFlags] & STATE_MASK; - if (state === ERRORED || stream[_pendingAbortRequest] !== undefined) { + if (state === ERRORED || state === ERRORING) { return null; } if (state === CLOSED) { @@ -638,28 +670,22 @@ function WritableStreamDefaultWriterRelease(writer) { const stream = writer[_ownerWritableStream]; - TEMP_ASSERT(stream !== undefined, - 'stream is not undefined.'); - TEMP_ASSERT(stream[_writer] === writer, - 'stream.[[writer]] is writer.'); + // assert(stream !== undefined, + // 'stream is not undefined.'); + // assert(stream[_writer] === writer, + // 'stream.[[writer]] is writer.'); const releasedError = new TypeError(errReleasedWriterClosedPromise); - const state = stream[_stateAndFlags] & STATE_MASK; - WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, - releasedError); - if (state === WRITABLE || - WritableStreamHasOperationMarkedInFlight(stream)) { - v8.rejectPromise(writer[_closedPromise], releasedError); - } else { - writer[_closedPromise] = Promise_reject(releasedError); - } - v8.markPromiseAsHandled(writer[_closedPromise]); + WritableStreamDefaultWriterEnsureReadyPromiseRejected( + writer, releasedError); + WritableStreamDefaultWriterEnsureClosedPromiseRejected( + writer, releasedError); stream[_writer] = undefined; writer[_ownerWritableStream] = undefined; } function WritableStreamDefaultWriterWrite(writer, chunk) { const stream = writer[_ownerWritableStream]; - TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); + // assert(stream !== undefined, 'stream is not undefined.'); const controller = stream[_writableStreamController]; const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk); @@ -678,9 +704,10 @@ return Promise_reject( createCannotActionOnStateStreamError('write to', CLOSED)); } - if (stream[_pendingAbortRequest] !== undefined) { - return Promise_reject(new TypeError(errStreamAborting)); + if (state === ERRORING) { + return Promise_reject(stream[_storedError]); } + // assert(state === WRITABLE, '_state_ is `"writable"`'); const promise = WritableStreamAddWriteRequest(stream); WritableStreamDefaultControllerWrite(controller, chunk, chunkSize); return promise; @@ -689,16 +716,16 @@ // Functions to expose internals for ReadableStream.pipeTo. These do not // appear in the standard. function getWritableStreamDefaultWriterClosedPromise(writer) { - TEMP_ASSERT( - IsWritableStreamDefaultWriter(writer), - 'writer is a WritableStreamDefaultWriter.'); + // assert( + // IsWritableStreamDefaultWriter(writer), + // 'writer is a WritableStreamDefaultWriter.'); return writer[_closedPromise]; } function getWritableStreamDefaultWriterReadyPromise(writer) { - TEMP_ASSERT( - IsWritableStreamDefaultWriter(writer), - 'writer is a WritableStreamDefaultWriter.'); + // assert( + // IsWritableStreamDefaultWriter(writer), + // 'writer is a WritableStreamDefaultWriter.'); return writer[_readyPromise]; } @@ -730,9 +757,10 @@ if (!IsWritableStreamDefaultController(this)) { throw new TypeError(streamErrors.illegalInvocation); } - const state = this[_controlledWritableStream][_stateAndFlags] & STATE_MASK; - if (state === CLOSED || state === ERRORED) { - throw createCannotActionOnStateStreamError('error', state); + const state = + this[_controlledWritableStream][_stateAndFlags] & STATE_MASK; + if (state !== WRITABLE) { + return; } WritableStreamDefaultControllerError(this, e); } @@ -744,9 +772,7 @@ // or impossible, so use static dispatch for now. This will have to be fixed // when adding a byte controller. function WritableStreamDefaultControllerAbortSteps(controller, reason) { - const sinkAbortPromise = - PromiseInvokeOrNoop(controller[_underlyingSink], 'abort', [reason]); - return thenPromise(sinkAbortPromise, () => undefined); + return PromiseInvokeOrNoop(controller[_underlyingSink], 'abort', [reason]); } function WritableStreamDefaultControllerErrorSteps(controller) { @@ -761,21 +787,18 @@ thenPromise( startPromise, () => { + const state = stream[_stateAndFlags] & STATE_MASK; + // assert(state === WRITABLE || state === ERRORING, + // '_stream_.[[state]] is `"writable"` or `"erroring"`'); controller[_started] = true; - if ((stream[_stateAndFlags] & STATE_MASK) === ERRORED) { - WritableStreamRejectAbortRequestIfPending(stream); - } else { - WritableStreamHandleAbortRequestIfPending(stream); - } WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); }, r => { - TEMP_ASSERT( - (stream[_stateAndFlags] & STATE_MASK) === WRITABLE || - (stream[_stateAndFlags] & STATE_MASK) === ERRORED, - '_stream_.[[state]] is `"writable"` or `"errored"`.'); - WritableStreamDefaultControllerErrorIfNeeded(controller, r); - WritableStreamRejectAbortRequestIfPending(stream); + const state = stream[_stateAndFlags] & STATE_MASK; + // assert(state === WRITABLE || state === ERRORING, + // '_stream_.[[state]] is `"writable"` or `"erroring"`'); + controller[_started] = true; + WritableStreamDealWithRejection(stream, r); }); } @@ -818,7 +841,8 @@ return; } const stream = controller[_controlledWritableStream]; - if (!WritableStreamCloseQueuedOrInFlight(stream)) { + if (!WritableStreamCloseQueuedOrInFlight(stream) && + (stream[_stateAndFlags] & STATE_MASK) === WRITABLE) { const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); WritableStreamUpdateBackpressure(stream, backpressure); @@ -828,16 +852,20 @@ function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) { const stream = controller[_controlledWritableStream]; - const state = stream[_stateAndFlags] & STATE_MASK; - if (state === CLOSED || state === ERRORED) { - return; - } if (!controller[_started]) { return; } if (stream[_inFlightWriteRequest] !== undefined) { return; } + const state = stream[_stateAndFlags] & STATE_MASK; + if (state === CLOSED || state === ERRORED) { + return; + } + if (state === ERRORING) { + WritableStreamFinishErroring(stream); + return; + } if (controller[_queue].length === 0) { return; } @@ -851,7 +879,8 @@ } function WritableStreamDefaultControllerErrorIfNeeded(controller, error) { - const state = controller[_controlledWritableStream][_stateAndFlags] & STATE_MASK; + const state = + controller[_controlledWritableStream][_stateAndFlags] & STATE_MASK; if (state === WRITABLE) { WritableStreamDefaultControllerError(controller, error); } @@ -861,10 +890,10 @@ const stream = controller[_controlledWritableStream]; WritableStreamMarkCloseRequestInFlight(stream); DequeueValue(controller); - TEMP_ASSERT(controller[_queue].length === 0, - 'controller.[[queue]] is empty.'); - const sinkClosePromise = PromiseInvokeOrNoop(controller[_underlyingSink], - 'close', [controller]); + // assert(controller[_queue].length === 0, + // 'controller.[[queue]] is empty.'); + const sinkClosePromise = PromiseInvokeOrNoop( + controller[_underlyingSink], 'close', []); thenPromise( sinkClosePromise, () => WritableStreamFinishInFlightClose(stream), @@ -882,12 +911,11 @@ () => { WritableStreamFinishInFlightWrite(stream); const state = stream[_stateAndFlags] & STATE_MASK; - if (state === ERRORED) { - return; - } - TEMP_ASSERT(state === WRITABLE, '_state_ is `"writable"`.'); + // assert(state === WRITABLE || state === ERRORING, + // '_state_ is `"writable"` or `"erroring"`'); DequeueValue(controller); - if (!WritableStreamCloseQueuedOrInFlight(stream)) { + if (!WritableStreamCloseQueuedOrInFlight(stream) && + state === WRITABLE) { const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); WritableStreamUpdateBackpressure(stream, backpressure); @@ -895,13 +923,7 @@ WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); }, reason => { - const wasErrored = (stream[_stateAndFlags] & STATE_MASK) === ERRORED; WritableStreamFinishInFlightWriteWithError(stream, reason); - TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === ERRORED, - '_stream_.[[state]] is `"errored"`.'); - if (!wasErrored) { - ResetQueue(controller); - } }); } @@ -913,22 +935,22 @@ function WritableStreamDefaultControllerError(controller, error) { const stream = controller[_controlledWritableStream]; - TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, - '_stream_.[[state]] is `"writable"`.'); - WritableStreamError(stream, error); + // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, + // '_stream_.[[state]] is `"writable"`.'); + WritableStreamStartErroring(stream, error); } // Queue-with-Sizes Operations // // TODO(ricea): Share these operations with ReadableStream.js. function DequeueValue(container) { - TEMP_ASSERT( - hasOwnProperty(container, _queue) && - hasOwnProperty(container, _queueTotalSize), - 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + - 'slots.'); - TEMP_ASSERT(container[_queue].length !== 0, - '_container_.[[queue]] is not empty.'); + // assert( + // hasOwnProperty(container, _queue) && + // hasOwnProperty(container, _queueTotalSize), + // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + + // 'slots.'); + // assert(container[_queue].length !== 0, + // '_container_.[[queue]] is not empty.'); const pair = container[_queue].shift(); container[_queueTotalSize] -= pair.size; if (container[_queueTotalSize] < 0) { @@ -938,11 +960,11 @@ } function EnqueueValueWithSize(container, value, size) { - TEMP_ASSERT( - hasOwnProperty(container, _queue) && - hasOwnProperty(container, _queueTotalSize), - 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + - 'slots.'); + // assert( + // hasOwnProperty(container, _queue) && + // hasOwnProperty(container, _queueTotalSize), + // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + + // 'slots.'); size = Number(size); if (!IsFiniteNonNegativeNumber(size)) { throw new RangeError(streamErrors.invalidSize); @@ -953,23 +975,23 @@ } function PeekQueueValue(container) { - TEMP_ASSERT( - hasOwnProperty(container, _queue) && - hasOwnProperty(container, _queueTotalSize), - 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + - 'slots.'); - TEMP_ASSERT(container[_queue].length !== 0, - '_container_.[[queue]] is not empty.'); + // assert( + // hasOwnProperty(container, _queue) && + // hasOwnProperty(container, _queueTotalSize), + // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + + // 'slots.'); + // assert(container[_queue].length !== 0, + // '_container_.[[queue]] is not empty.'); const pair = container[_queue].peek(); return pair.value; } function ResetQueue(container) { - TEMP_ASSERT( - hasOwnProperty(container, _queue) && - hasOwnProperty(container, _queueTotalSize), - 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + - 'slots.'); + // assert( + // hasOwnProperty(container, _queue) && + // hasOwnProperty(container, _queueTotalSize), + // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + + // 'slots.'); container[_queue] = new binding.SimpleQueue(); container[_queueTotalSize] = 0; } @@ -982,8 +1004,8 @@ // // TODO(ricea): Consolidate with ReadableStream implementation. function InvokeOrNoop(O, P, args) { - TEMP_ASSERT(IsPropertyKey(P), - 'P is a valid property key.'); + // assert(IsPropertyKey(P), + // 'P is a valid property key.'); if (args === undefined) { args = []; }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index 2a287ca..96c46e9 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -1089,6 +1089,8 @@ ->VisitedLinkTextEmphasisColor() || rare_inherited_data_->text_emphasis_fill != other.rare_inherited_data_->text_emphasis_fill || + rare_inherited_data_->text_underline_position_ != + other.rare_inherited_data_->text_underline_position_ || rare_inherited_data_->text_decoration_skip_ != other.rare_inherited_data_->text_decoration_skip_ || rare_inherited_data_->applied_text_decorations !=
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index 3f8e4e3..1c86397 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -1091,23 +1091,26 @@ } // Margin properties. - static Length InitialMargin() { return Length(kFixed); } // margin-top + static Length InitialMarginTop() { return Length(kFixed); } const Length& MarginTop() const { return surround_->margin_.Top(); } void SetMarginTop(const Length& v) { SET_VAR(surround_, margin_.top_, v); } // margin-bottom + static Length InitialMarginBottom() { return Length(kFixed); } const Length& MarginBottom() const { return surround_->margin_.Bottom(); } void SetMarginBottom(const Length& v) { SET_VAR(surround_, margin_.bottom_, v); } // margin-left + static Length InitialMarginLeft() { return Length(kFixed); } const Length& MarginLeft() const { return surround_->margin_.Left(); } void SetMarginLeft(const Length& v) { SET_VAR(surround_, margin_.left_, v); } // margin-right + static Length InitialMarginRight() { return Length(kFixed); } const Length& MarginRight() const { return surround_->margin_.Right(); } void SetMarginRight(const Length& v) { SET_VAR(surround_, margin_.right_, v);
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp index deb6671..594c44d4 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -987,7 +987,7 @@ settings.setAlpha(CreationAttributes().alpha()); settings.setColorSpace(ColorSpaceAsString()); settings.setPixelFormat(PixelFormatAsString()); - settings.setLinearPixelMath(LinearPixelMath()); + settings.setLinearPixelMath(color_params().LinearPixelMath()); } void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element) {
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp index 0df9635..1105d69 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -252,9 +252,9 @@ std::unique_ptr<FakeWebGraphicsContext3DProvider> provider, const IntSize& size, Canvas2DLayerBridge::AccelerationMode acceleration_mode) { - return AdoptRef(new Canvas2DLayerBridge( - std::move(provider), size, 0, kNonOpaque, acceleration_mode, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType)); + return AdoptRef(new Canvas2DLayerBridge(std::move(provider), size, 0, + kNonOpaque, acceleration_mode, + CanvasColorParams())); } //============================================================================ @@ -355,12 +355,11 @@ std::unique_ptr<ImageBufferSurface> CreateSurface( const IntSize& size, OpacityMode mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type) override { + const CanvasColorParams& color_params) override { EXPECT_EQ(kExpectFallback, expectation_); did_fallback_ = true; return WTF::WrapUnique(new UnacceleratedImageBufferSurface( - size, mode, kInitializeImagePixels, color_space, color_type)); + size, mode, kInitializeImagePixels, color_params)); } ~MockSurfaceFactory() override { @@ -558,7 +557,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); @@ -570,7 +569,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization @@ -589,7 +588,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization @@ -608,7 +607,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); NonThrowableExceptionState exception_state; @@ -643,7 +642,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); NonThrowableExceptionState exception_state; @@ -680,7 +679,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->beginPath(); @@ -705,7 +704,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->beginPath(); @@ -729,7 +728,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->beginPath(); @@ -752,7 +751,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->beginPath(); @@ -769,7 +768,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->beginPath(); @@ -793,7 +792,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->setShadowColor(String("red")); @@ -813,7 +812,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->setShadowColor(String("red")); @@ -829,7 +828,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect @@ -849,7 +848,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect @@ -873,7 +872,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectFallback), - kOpaque, nullptr)); + kOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->fillText("Text", 0, 5); @@ -886,7 +885,7 @@ WTF::WrapUnique(new RecordingImageBufferSurface( IntSize(10, 10), MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), - kNonOpaque, nullptr)); + kNonOpaque)); CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); Context2d()->fillText("Text", 0, 5);
diff --git a/third_party/WebKit/Source/modules/fetch/FetchHeaderList.cpp b/third_party/WebKit/Source/modules/fetch/FetchHeaderList.cpp index 4ef2381c..42111cf 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchHeaderList.cpp +++ b/third_party/WebKit/Source/modules/fetch/FetchHeaderList.cpp
@@ -99,8 +99,7 @@ resultBuilder.Append(header->second); found = true; } else { - // TODO(rakuco): This must be ", " instead. crbug.com/700434. - resultBuilder.Append(','); + resultBuilder.Append(", "); resultBuilder.Append(header->second); } }
diff --git a/third_party/WebKit/Source/modules/fetch/FetchHeaderListTest.cpp b/third_party/WebKit/Source/modules/fetch/FetchHeaderListTest.cpp index 70de823..e8bfdf78 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchHeaderListTest.cpp +++ b/third_party/WebKit/Source/modules/fetch/FetchHeaderListTest.cpp
@@ -87,7 +87,7 @@ EXPECT_TRUE(headerList->Get("X-Foo", combinedValue)); EXPECT_EQ("bar", combinedValue); EXPECT_TRUE(headerList->Get("content-TYPE", combinedValue)); - EXPECT_EQ("text/plain,application/xml,foo", combinedValue); + EXPECT_EQ("text/plain, application/xml, foo", combinedValue); } // This is going to be removed: see crbug.com/645492. @@ -146,7 +146,7 @@ headerList->Append("X-Foo", "bar"); const std::pair<String, String> expectedHeaders[] = { std::make_pair("accept", "XYZ"), - std::make_pair("content-type", "multipart/form-data,application/xml"), + std::make_pair("content-type", "multipart/form-data, application/xml"), std::make_pair("x-foo", "bar")}; const Vector<FetchHeaderList::Header> sortedAndCombined = headerList->SortAndCombine();
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index bfbd9ea..8216a1f 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -1132,11 +1132,11 @@ } else { NOTREACHED(); } - return DrawingBuffer::Create(std::move(context_provider), this, - ClampedCanvasSize(), premultiplied_alpha, - want_alpha_channel, want_depth_buffer, - want_stencil_buffer, want_antialiasing, preserve, - web_gl_version, chromium_image_usage); + return DrawingBuffer::Create( + std::move(context_provider), this, ClampedCanvasSize(), + premultiplied_alpha, want_alpha_channel, want_depth_buffer, + want_stencil_buffer, want_antialiasing, preserve, web_gl_version, + chromium_image_usage, color_params()); } void WebGLRenderingContextBase::InitializeNewContext() {
diff --git a/third_party/WebKit/Source/modules/webusb/USBEndpoint.cpp b/third_party/WebKit/Source/modules/webusb/USBEndpoint.cpp index 16babb2..81f7a50d 100644 --- a/third_party/WebKit/Source/modules/webusb/USBEndpoint.cpp +++ b/third_party/WebKit/Source/modules/webusb/USBEndpoint.cpp
@@ -9,7 +9,7 @@ #include "device/usb/public/interfaces/device.mojom-blink.h" #include "modules/webusb/USBAlternateInterface.h" -using device::mojom::blink::UsbEndpointType; +using device::mojom::blink::UsbTransferType; using device::mojom::blink::UsbTransferDirection; namespace blink { @@ -28,13 +28,13 @@ } } -String ConvertTypeToEnum(const UsbEndpointType& type) { +String ConvertTypeToEnum(const UsbTransferType& type) { switch (type) { - case UsbEndpointType::BULK: + case UsbTransferType::BULK: return "bulk"; - case UsbEndpointType::INTERRUPT: + case UsbTransferType::INTERRUPT: return "interrupt"; - case UsbEndpointType::ISOCHRONOUS: + case UsbTransferType::ISOCHRONOUS: return "isochronous"; default: ASSERT_NOT_REACHED();
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 index 18cde98..ce58ba9b 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -68,7 +68,7 @@ { name: "AccessibilityObjectModel", settable_from_internals: true, - status: "experimental", + status: "test", }, { name: "AudioOutputDevices",
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/Canvas2DImageBufferSurface.h index 942c9d4..270e51e 100644 --- a/third_party/WebKit/Source/platform/graphics/Canvas2DImageBufferSurface.h +++ b/third_party/WebKit/Source/platform/graphics/Canvas2DImageBufferSurface.h
@@ -47,24 +47,15 @@ int msaa_sample_count, OpacityMode opacity_mode, Canvas2DLayerBridge::AccelerationMode acceleration_mode, - const gfx::ColorSpace& color_space, - bool sk_surfaces_use_color_space, - SkColorType color_type) - : ImageBufferSurface(size, - opacity_mode, - sk_surfaces_use_color_space - ? color_space.ToSkColorSpace() - : nullptr, - color_type), + const CanvasColorParams& color_params) + : ImageBufferSurface(size, opacity_mode, color_params), layer_bridge_( AdoptRef(new Canvas2DLayerBridge(std::move(context_provider), size, msaa_sample_count, opacity_mode, acceleration_mode, - color_space, - sk_surfaces_use_color_space, - color_type))) { + color_params))) { Init(); } @@ -72,8 +63,7 @@ const IntSize& size) : ImageBufferSurface(size, bridge->GetOpacityMode(), - bridge->SkSurfaceColorSpace(), - bridge->ColorType()), + bridge->color_params()), layer_bridge_(std::move(bridge)) { Init(); }
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp index d29e539..eaf8e1bd 100644 --- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp +++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -87,16 +87,16 @@ const IntSize& size, int msaa_sample_count, OpacityMode opacity_mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type, + const CanvasColorParams& color_params, bool* surface_is_accelerated) { if (gr) gr->resetContext(); SkAlphaType alpha_type = (kOpaque == opacity_mode) ? kOpaque_SkAlphaType : kPremul_SkAlphaType; - SkImageInfo info = SkImageInfo::Make(size.Width(), size.Height(), color_type, - alpha_type, color_space); + SkImageInfo info = SkImageInfo::Make( + size.Width(), size.Height(), color_params.GetSkColorType(), alpha_type, + color_params.GetSkColorSpaceForSkSurfaces()); SkSurfaceProps disable_lcd_props(0, kUnknown_SkPixelGeometry); sk_sp<SkSurface> surface; @@ -129,9 +129,7 @@ int msaa_sample_count, OpacityMode opacity_mode, AccelerationMode acceleration_mode, - const gfx::ColorSpace& color_space, - bool sk_surfaces_use_color_space, - SkColorType color_type) + const CanvasColorParams& color_params) : context_provider_(std::move(context_provider)), logger_(WTF::WrapUnique(new Logger)), weak_ptr_factory_(this), @@ -149,12 +147,10 @@ acceleration_mode_(acceleration_mode), opacity_mode_(opacity_mode), size_(size), - color_space_(color_space), - sk_surfaces_use_color_space_(sk_surfaces_use_color_space), - color_type_(color_type) { + color_params_(color_params) { DCHECK(context_provider_); DCHECK(!context_provider_->IsSoftwareRendering()); - DCHECK(color_space_.IsValid()); + DCHECK(color_params_.GetGfxColorSpace().IsValid()); // Used by browser tests to detect the use of a Canvas2DLayerBridge. TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_SCOPE_GLOBAL); @@ -286,8 +282,9 @@ cc::TextureMailbox(mailbox, sync_token, texture_target, gfx::Size(size_), is_overlay_candidate, secure_output_only); if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) { - out_mailbox->set_color_space(color_space_); - image_info->gpu_memory_buffer_->SetColorSpaceForScanout(color_space_); + gfx::ColorSpace color_space = color_params_.GetGfxColorSpace(); + out_mailbox->set_color_space(color_space); + image_info->gpu_memory_buffer_->SetColorSpaceForScanout(color_space); } gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); @@ -534,12 +531,6 @@ logger_->DidStartHibernating(); } -sk_sp<SkColorSpace> Canvas2DLayerBridge::SkSurfaceColorSpace() const { - if (sk_surfaces_use_color_space_) - return color_space_.ToSkColorSpace(); - return nullptr; -} - void Canvas2DLayerBridge::ReportSurfaceCreationFailure() { if (!surface_creation_failed_at_least_once_) { // Only count the failure once per instance so that the histogram may @@ -570,7 +561,7 @@ bool surface_is_accelerated; surface_ = CreateSkSurface( want_acceleration ? context_provider_->GetGrContext() : nullptr, size_, - msaa_sample_count_, opacity_mode_, SkSurfaceColorSpace(), color_type_, + msaa_sample_count_, opacity_mode_, color_params_, &surface_is_accelerated); surface_paint_canvas_ = WTF::WrapUnique(new SkiaPaintCanvas(surface_->getCanvas())); @@ -794,9 +785,9 @@ SkCanvas* canvas = GetOrCreateSurface()->getCanvas(); std::unique_ptr<SkCanvas> color_transform_canvas; if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled() && - !sk_surfaces_use_color_space_) { - color_transform_canvas = - SkCreateColorSpaceXformCanvas(canvas, color_space_.ToSkColorSpace()); + color_params_.UsesOutputSpaceBlending()) { + color_transform_canvas = SkCreateColorSpaceXformCanvas( + canvas, color_params_.GetSkColorSpace()); canvas = color_transform_canvas.get(); } @@ -883,9 +874,9 @@ if (shared_gl && shared_gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { GrContext* gr_ctx = context_provider_->GetGrContext(); bool surface_is_accelerated; - sk_sp<SkSurface> surface(CreateSkSurface( - gr_ctx, size_, msaa_sample_count_, opacity_mode_, SkSurfaceColorSpace(), - color_type_, &surface_is_accelerated)); + sk_sp<SkSurface> surface(CreateSkSurface(gr_ctx, size_, msaa_sample_count_, + opacity_mode_, color_params_, + &surface_is_accelerated)); if (!surface_) ReportSurfaceCreationFailure(); @@ -952,7 +943,7 @@ if (!PrepareMailboxFromImage(std::move(image), out_mailbox)) return false; out_mailbox->set_nearest_neighbor(GetGLFilter() == GL_NEAREST); - out_mailbox->set_color_space(color_space_); + out_mailbox->set_color_space(color_params_.GetGfxColorSpace()); auto func = WTF::Bind(&Canvas2DLayerBridge::MailboxReleased,
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h index 9417d67..eec71a5 100644 --- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h +++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h
@@ -93,9 +93,7 @@ int msaa_sample_count, OpacityMode, AccelerationMode, - const gfx::ColorSpace&, - bool sk_surfaces_use_color_space, - SkColorType); + const CanvasColorParams&); ~Canvas2DLayerBridge() override; @@ -141,8 +139,7 @@ void BeginDestruction(); void Hibernate(); bool IsHibernating() const { return hibernation_image_.get(); } - sk_sp<SkColorSpace> SkSurfaceColorSpace() const; - SkColorType ColorType() const { return color_type_; } + const CanvasColorParams& color_params() const { return color_params_; } bool HasRecordedDrawCommands() { return have_recorded_draw_commands_; } @@ -286,11 +283,7 @@ AccelerationMode acceleration_mode_; OpacityMode opacity_mode_; const IntSize size_; - // The color space that the compositor is to use. This will always be - // defined. - gfx::ColorSpace color_space_; - bool sk_surfaces_use_color_space_ = false; - SkColorType color_type_; + CanvasColorParams color_params_; int recording_pixel_count_; #if USE_IOSURFACE_FOR_2D_CANVAS
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp index c54f8d7..17ba8fe6 100644 --- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
@@ -124,9 +124,9 @@ std::unique_ptr<FakeWebGraphicsContext3DProvider> provider, const IntSize& size, Canvas2DLayerBridge::AccelerationMode acceleration_mode) { - RefPtr<Canvas2DLayerBridge> bridge = AdoptRef(new Canvas2DLayerBridge( - std::move(provider), size, 0, kNonOpaque, acceleration_mode, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType)); + RefPtr<Canvas2DLayerBridge> bridge = AdoptRef( + new Canvas2DLayerBridge(std::move(provider), size, 0, kNonOpaque, + acceleration_mode, CanvasColorParams())); bridge->DontUseIdleSchedulingForTesting(); return bridge.Release(); } @@ -139,8 +139,7 @@ Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, - Canvas2DLayerBridge::kDisableAcceleration, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + Canvas2DLayerBridge::kDisableAcceleration, CanvasColorParams()))); const GrGLTextureInfo* texture_info = skia::GrBackendObjectToGrGLTextureInfo( @@ -160,8 +159,7 @@ gl.setIsContextLost(true); Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, - Canvas2DLayerBridge::kEnableAcceleration, gfx::ColorSpace::CreateSRGB(), - false, kN32_SkColorType))); + Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()))); EXPECT_TRUE(bridge->CheckSurfaceValid()); EXPECT_FALSE(bridge->IsAccelerated()); } @@ -174,8 +172,7 @@ WTF::WrapUnique(new FakeWebGraphicsContext3DProvider(&gl)); Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, - Canvas2DLayerBridge::kEnableAcceleration, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()))); EXPECT_TRUE(bridge->CheckSurfaceValid()); EXPECT_TRUE(bridge->IsAccelerated()); sk_sp<SkImage> snapshot = bridge->NewImageSnapshot( @@ -192,8 +189,7 @@ GrContext* gr = context_provider->GetGrContext(); Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, - Canvas2DLayerBridge::kEnableAcceleration, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()))); EXPECT_TRUE(bridge->CheckSurfaceValid()); EXPECT_TRUE(bridge->IsAccelerated()); // We don't yet know that // allocation will fail. @@ -215,7 +211,7 @@ Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, Canvas2DLayerBridge::kForceAccelerationForTesting, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + CanvasColorParams()))); EXPECT_TRUE(bridge->CheckSurfaceValid()); PaintFlags flags; uint32_t gen_id = bridge->GetOrCreateSurface()->generationID(); @@ -241,7 +237,7 @@ Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, Canvas2DLayerBridge::kForceAccelerationForTesting, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + CanvasColorParams()))); EXPECT_TRUE(bridge->IsAccelerated()); @@ -262,7 +258,7 @@ Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, Canvas2DLayerBridge::kForceAccelerationForTesting, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + CanvasColorParams()))); bridge->GetOrCreateSurface(); EXPECT_TRUE(bridge->CheckSurfaceValid()); @@ -293,7 +289,7 @@ Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, Canvas2DLayerBridge::kForceAccelerationForTesting, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + CanvasColorParams()))); cc::TextureMailbox texture_mailbox; std::unique_ptr<cc::SingleReleaseCallback> release_callback; @@ -317,7 +313,7 @@ Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, Canvas2DLayerBridge::kForceAccelerationForTesting, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + CanvasColorParams()))); bridge->PrepareTextureMailbox(&texture_mailbox, &release_callback); // |bridge| goes out of scope and would normally be destroyed, but // object is kept alive by self references. @@ -339,8 +335,7 @@ WTF::WrapUnique(new FakeWebGraphicsContext3DProvider(&gl)); Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 300), 0, kNonOpaque, - Canvas2DLayerBridge::kEnableAcceleration, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()))); PaintFlags flags; bridge->Canvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags); sk_sp<SkImage> image = bridge->NewImageSnapshot(kPreferAcceleration, @@ -355,8 +350,7 @@ WTF::WrapUnique(new FakeWebGraphicsContext3DProvider(&gl)); Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 300), 0, kNonOpaque, - Canvas2DLayerBridge::kEnableAcceleration, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()))); PaintFlags flags; bridge->Canvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags); sk_sp<SkImage> image = bridge->NewImageSnapshot(kPreferNoAcceleration, @@ -1320,7 +1314,7 @@ Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, Canvas2DLayerBridge::kForceAccelerationForTesting, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + CanvasColorParams()))); bridge->PrepareTextureMailbox(&texture_mailbox, &release_callback); } @@ -1344,8 +1338,7 @@ EXPECT_CALL(gl, Flush()).Times(0); Canvas2DLayerBridgePtr bridge(AdoptRef(new Canvas2DLayerBridge( std::move(context_provider), IntSize(300, 150), 0, kNonOpaque, - Canvas2DLayerBridge::kForceAccelerationForTesting, - gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType))); + Canvas2DLayerBridge::kForceAccelerationForTesting, CanvasColorParams()))); EXPECT_FALSE(bridge->HasRecordedDrawCommands()); ::testing::Mock::VerifyAndClearExpectations(&gl);
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp index ea864676..80edcb1 100644 --- a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp +++ b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp
@@ -8,10 +8,16 @@ namespace blink { +CanvasColorParams::CanvasColorParams() = default; + CanvasColorParams::CanvasColorParams(CanvasColorSpace color_space, CanvasPixelFormat pixel_format) : color_space_(color_space), pixel_format_(pixel_format) {} +bool CanvasColorParams::UsesOutputSpaceBlending() const { + return color_space_ == kLegacyCanvasColorSpace; +} + sk_sp<SkColorSpace> CanvasColorParams::GetSkColorSpaceForSkSurfaces() const { if (color_space_ == kLegacyCanvasColorSpace) return nullptr; @@ -24,6 +30,10 @@ return kN32_SkColorType; } +uint8_t CanvasColorParams::BytesPerPixel() const { + return SkColorTypeBytesPerPixel(GetSkColorType()); +} + gfx::ColorSpace CanvasColorParams::GetGfxColorSpace() const { switch (color_space_) { case kLegacyCanvasColorSpace: @@ -42,6 +52,10 @@ return gfx::ColorSpace(); } +sk_sp<SkColorSpace> CanvasColorParams::GetSkColorSpace() const { + return GetGfxColorSpace().ToSkColorSpace(); +} + bool CanvasColorParams::LinearPixelMath() const { return pixel_format_ == kF16CanvasPixelFormat; }
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.h b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.h index daf034a..32d2c1b 100644 --- a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.h +++ b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.h
@@ -31,22 +31,33 @@ class PLATFORM_EXPORT CanvasColorParams { public: + // The default constructor will create an output-blended 8-bit surface. + CanvasColorParams(); CanvasColorParams(CanvasColorSpace, CanvasPixelFormat); CanvasColorSpace color_space() const { return color_space_; } CanvasPixelFormat pixel_format() const { return pixel_format_; } + // Returns true if the canvas uses blends output color space values (that is, + // not linear space colors). + bool UsesOutputSpaceBlending() const; + // The SkColorSpace to use in the SkImageInfo for allocated SkSurfaces. This // is nullptr in legacy rendering mode. sk_sp<SkColorSpace> GetSkColorSpaceForSkSurfaces() const; // The pixel format to use for allocating SkSurfaces. SkColorType GetSkColorType() const; + uint8_t BytesPerPixel() const; - // The color space to use for compositing. + // The color space to use for compositing. This will always return a valid + // gfx or skia color space. gfx::ColorSpace GetGfxColorSpace() const; + sk_sp<SkColorSpace> GetSkColorSpace() const; // This matches CanvasRenderingContext::LinearPixelMath, and is true only when // the pixel format is half-float linear. + // TODO(ccameron): This is not the same as !UsesOutputSpaceBlending, but + // perhaps should be. bool LinearPixelMath() const; private:
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp index ee46ab4..bb1a4cc 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp +++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
@@ -80,16 +80,10 @@ const IntSize& size, OpacityMode opacity_mode, ImageInitializationMode initialization_mode, - sk_sp<SkColorSpace> color_space) { - SkColorType color_type = kN32_SkColorType; - if (color_space && SkColorSpace::Equals(color_space.get(), - SkColorSpace::MakeSRGBLinear().get())) - color_type = kRGBA_F16_SkColorType; - + const CanvasColorParams& color_params) { std::unique_ptr<ImageBufferSurface> surface( WTF::WrapUnique(new UnacceleratedImageBufferSurface( - size, opacity_mode, initialization_mode, std::move(color_space), - color_type))); + size, opacity_mode, initialization_mode, color_params))); if (!surface->IsValid()) return nullptr; @@ -354,9 +348,7 @@ bool ImageBuffer::GetImageData(Multiply multiplied, const IntRect& rect, WTF::ArrayBufferContents& contents) const { - uint8_t bytes_per_pixel = 4; - if (surface_->ColorSpace()) - bytes_per_pixel = SkColorTypeBytesPerPixel(surface_->ColorType()); + uint8_t bytes_per_pixel = surface_->color_params().BytesPerPixel(); CheckedNumeric<int> data_size = bytes_per_pixel; data_size *= rect.Width(); data_size *= rect.Height(); @@ -399,7 +391,8 @@ WTF::ArrayBufferContents::kNotShared); // Skia does not support unpremultiplied read with an F16 to 8888 conversion - bool use_f16_workaround = surface_->ColorType() == kRGBA_F16_SkColorType; + bool use_f16_workaround = + surface_->color_params().GetSkColorType() == kRGBA_F16_SkColorType; SkAlphaType alpha_type = (multiplied == kPremultiplied || use_f16_workaround) ? kPremul_SkAlphaType @@ -411,10 +404,8 @@ // Only use sRGB when the surface has a color space. Converting untagged // pixels to a particular color space is not well-defined in Skia. - sk_sp<SkColorSpace> color_space = nullptr; - if (surface_->ColorSpace()) { - color_space = SkColorSpace::MakeSRGB(); - } + sk_sp<SkColorSpace> color_space = + surface_->color_params().GetSkColorSpaceForSkSurfaces(); SkImageInfo info = SkImageInfo::Make(rect.Width(), rect.Height(), color_type, alpha_type, std::move(color_space)); @@ -455,9 +446,7 @@ const IntPoint& dest_point) { if (!IsSurfaceValid()) return; - uint8_t bytes_per_pixel = 4; - if (surface_->ColorSpace()) - bytes_per_pixel = SkColorTypeBytesPerPixel(surface_->ColorType()); + uint8_t bytes_per_pixel = surface_->color_params().BytesPerPixel(); DCHECK_GT(source_rect.Width(), 0); DCHECK_GT(source_rect.Height(), 0); @@ -494,10 +483,11 @@ } SkImageInfo info; - if (surface_->ColorSpace()) { - info = SkImageInfo::Make(source_rect.Width(), source_rect.Height(), - surface_->ColorType(), alpha_type, - surface_->ColorSpace()); + if (surface_->color_params().GetSkColorSpaceForSkSurfaces()) { + info = SkImageInfo::Make( + source_rect.Width(), source_rect.Height(), + surface_->color_params().GetSkColorType(), alpha_type, + surface_->color_params().GetSkColorSpaceForSkSurfaces()); } else { info = SkImageInfo::Make(source_rect.Width(), source_rect.Height(), kRGBA_8888_SkColorType, alpha_type, @@ -511,7 +501,7 @@ // If image buffer is accelerated, we should keep track of GPU memory usage. int gpu_buffer_count = 2; CheckedNumeric<intptr_t> checked_gpu_usage = - SkColorTypeBytesPerPixel(surface_->ColorType()) * gpu_buffer_count; + surface_->color_params().BytesPerPixel() * gpu_buffer_count; checked_gpu_usage *= this->size().Width(); checked_gpu_usage *= this->size().Height(); intptr_t gpu_memory_usage = @@ -543,11 +533,9 @@ virtual std::unique_ptr<ImageBufferSurface> CreateSurface( const IntSize& size, OpacityMode opacity_mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type) { + const CanvasColorParams& color_params) { return WTF::WrapUnique(new UnacceleratedImageBufferSurface( - size, opacity_mode, kInitializeImagePixels, std::move(color_space), - color_type)); + size, opacity_mode, kInitializeImagePixels, color_params)); } virtual ~UnacceleratedSurfaceFactory() {} @@ -565,8 +553,7 @@ std::unique_ptr<ImageBufferSurface> surface = WTF::WrapUnique(new RecordingImageBufferSurface( surface_->size(), std::move(surface_factory), - surface_->GetOpacityMode(), surface_->ColorSpace(), - surface_->ColorType())); + surface_->GetOpacityMode(), surface_->color_params())); SetSurface(std::move(surface)); }
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h index 0d18f76..cbf3e35 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h +++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
@@ -78,7 +78,7 @@ const IntSize&, OpacityMode = kNonOpaque, ImageInitializationMode = kInitializeImagePixels, - sk_sp<SkColorSpace> = nullptr); + const CanvasColorParams& = CanvasColorParams()); static std::unique_ptr<ImageBuffer> Create( std::unique_ptr<ImageBufferSurface>);
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.cpp index 9139f79..10858cc 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.cpp +++ b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.cpp
@@ -41,12 +41,8 @@ ImageBufferSurface::ImageBufferSurface(const IntSize& size, OpacityMode opacity_mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type) - : opacity_mode_(opacity_mode), - size_(size), - color_space_(color_space), - color_type_(color_type) { + const CanvasColorParams& color_params) + : opacity_mode_(opacity_mode), size_(size), color_params_(color_params) { SetIsHidden(false); }
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h index 9ac1b57..bc4af9dd 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h +++ b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h
@@ -33,6 +33,7 @@ #include "platform/PlatformExport.h" #include "platform/geometry/IntSize.h" +#include "platform/graphics/CanvasColorParams.h" #include "platform/graphics/GraphicsTypes.h" #include "platform/graphics/paint/PaintCanvas.h" #include "platform/graphics/paint/PaintFlags.h" @@ -43,7 +44,6 @@ #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkRefCnt.h" -class SkColorSpace; class SkImage; struct SkImageInfo; @@ -104,22 +104,17 @@ OpacityMode GetOpacityMode() const { return opacity_mode_; } const IntSize& size() const { return size_; } - const sk_sp<SkColorSpace> ColorSpace() const { return color_space_; } - SkColorType ColorType() const { return color_type_; } + const CanvasColorParams& color_params() const { return color_params_; } void NotifyIsValidChanged(bool is_valid) const; protected: - ImageBufferSurface(const IntSize&, - OpacityMode, - sk_sp<SkColorSpace>, - SkColorType); + ImageBufferSurface(const IntSize&, OpacityMode, const CanvasColorParams&); void Clear(); private: OpacityMode opacity_mode_; IntSize size_; - sk_sp<SkColorSpace> color_space_; - SkColorType color_type_; + CanvasColorParams color_params_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp index 1973c948..4b0bb49 100644 --- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp +++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
@@ -21,12 +21,8 @@ std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> fallback_factory, OpacityMode opacity_mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type) - : ImageBufferSurface(size, - opacity_mode, - std::move(color_space), - color_type), + const CanvasColorParams& color_params) + : ImageBufferSurface(size, opacity_mode, color_params), image_buffer_(0), current_frame_pixel_count_(0), previous_frame_pixel_count_(0), @@ -97,8 +93,8 @@ kFallbackReasonCount)); canvas_fallback_histogram.Count(reason); - fallback_surface_ = fallback_factory_->CreateSurface( - size(), GetOpacityMode(), ColorSpace(), ColorType()); + fallback_surface_ = fallback_factory_->CreateSurface(size(), GetOpacityMode(), + color_params()); fallback_surface_->SetImageBuffer(image_buffer_); if (previous_frame_) {
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h index a3cf0efb..a0b8f493 100644 --- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h +++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h
@@ -23,10 +23,8 @@ WTF_MAKE_NONCOPYABLE(RecordingImageBufferFallbackSurfaceFactory); public: - virtual std::unique_ptr<ImageBufferSurface> CreateSurface(const IntSize&, - OpacityMode, - sk_sp<SkColorSpace>, - SkColorType) = 0; + virtual std::unique_ptr<ImageBufferSurface> + CreateSurface(const IntSize&, OpacityMode, const CanvasColorParams&) = 0; virtual ~RecordingImageBufferFallbackSurfaceFactory() {} protected: @@ -47,8 +45,7 @@ std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> fallback_factory = nullptr, OpacityMode = kNonOpaque, - sk_sp<SkColorSpace> = nullptr, - SkColorType = kN32_SkColorType); + const CanvasColorParams& = CanvasColorParams()); ~RecordingImageBufferSurface() override; // Implementation of ImageBufferSurface interfaces
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp index 8430490..b37d903 100644 --- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp
@@ -32,12 +32,10 @@ virtual std::unique_ptr<ImageBufferSurface> CreateSurface( const IntSize& size, OpacityMode opacity_mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type) { + const CanvasColorParams& color_params) { create_surface_count_++; return WTF::WrapUnique(new UnacceleratedImageBufferSurface( - size, opacity_mode, kInitializeImagePixels, std::move(color_space), - color_type)); + size, opacity_mode, kInitializeImagePixels, color_params)); } virtual ~MockSurfaceFactory() {} @@ -56,7 +54,7 @@ surface_factory_ = surface_factory.get(); std::unique_ptr<RecordingImageBufferSurface> test_surface = WTF::WrapUnique(new RecordingImageBufferSurface( - IntSize(10, 10), std::move(surface_factory), kNonOpaque, nullptr)); + IntSize(10, 10), std::move(surface_factory), kNonOpaque)); test_surface_ = test_surface.get(); // We create an ImageBuffer in order for the testSurface to be // properly initialized with a GraphicsContext
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp index b047754..ce38fa85 100644 --- a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp +++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp
@@ -40,13 +40,13 @@ const IntSize& size, OpacityMode opacity_mode, ImageInitializationMode initialization_mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type) - : ImageBufferSurface(size, opacity_mode, color_space, color_type) { + const CanvasColorParams& color_params) + : ImageBufferSurface(size, opacity_mode, color_params) { SkAlphaType alpha_type = (kOpaque == opacity_mode) ? kOpaque_SkAlphaType : kPremul_SkAlphaType; - SkImageInfo info = SkImageInfo::Make(size.Width(), size.Height(), color_type, - alpha_type, color_space); + SkImageInfo info = SkImageInfo::Make( + size.Width(), size.Height(), color_params.GetSkColorType(), alpha_type, + color_params.GetSkColorSpaceForSkSurfaces()); SkSurfaceProps disable_lcd_props(0, kUnknown_SkPixelGeometry); surface_ = SkSurface::MakeRaster( info, kOpaque == opacity_mode ? 0 : &disable_lcd_props);
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h index 31c143f9..2a6cf946 100644 --- a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h +++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h
@@ -47,8 +47,8 @@ const IntSize&, OpacityMode = kNonOpaque, ImageInitializationMode = kInitializeImagePixels, - sk_sp<SkColorSpace> = nullptr, - SkColorType = kN32_SkColorType); + const CanvasColorParams& = CanvasColorParams(kLegacyCanvasColorSpace, + kRGBA8CanvasPixelFormat)); ~UnacceleratedImageBufferSurface() override; PaintCanvas* Canvas() override;
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp index e15d266..fd5a436f 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp +++ b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp
@@ -42,9 +42,8 @@ AcceleratedImageBufferSurface::AcceleratedImageBufferSurface( const IntSize& size, OpacityMode opacity_mode, - sk_sp<SkColorSpace> color_space, - SkColorType color_type) - : ImageBufferSurface(size, opacity_mode, color_space, color_type) { + const CanvasColorParams& color_params) + : ImageBufferSurface(size, opacity_mode, color_params) { if (!SharedGpuContext::IsValid()) return; GrContext* gr_context = SharedGpuContext::Gr(); @@ -53,8 +52,9 @@ SkAlphaType alpha_type = (kOpaque == opacity_mode) ? kOpaque_SkAlphaType : kPremul_SkAlphaType; - SkImageInfo info = SkImageInfo::Make(size.Width(), size.Height(), color_type, - alpha_type, color_space); + SkImageInfo info = SkImageInfo::Make( + size.Width(), size.Height(), color_params.GetSkColorType(), alpha_type, + color_params.GetSkColorSpaceForSkSurfaces()); SkSurfaceProps disable_lcd_props(0, kUnknown_SkPixelGeometry); surface_ = SkSurface::MakeRenderTarget( gr_context, SkBudgeted::kYes, info, 0 /* sampleCount */,
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h index 2fe2f6f..91ee454 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h +++ b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h
@@ -48,8 +48,7 @@ public: AcceleratedImageBufferSurface(const IntSize&, OpacityMode = kNonOpaque, - sk_sp<SkColorSpace> = nullptr, - SkColorType = kN32_SkColorType); + const CanvasColorParams& = CanvasColorParams()); ~AcceleratedImageBufferSurface() override {} PaintCanvas* Canvas() override { return canvas_.get(); }
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp index 7a26d0f..e4d34d37 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -77,7 +77,8 @@ bool want_antialiasing, PreserveDrawingBuffer preserve, WebGLVersion web_gl_version, - ChromiumImageUsage chromium_image_usage) { + ChromiumImageUsage chromium_image_usage, + const CanvasColorParams& color_params) { DCHECK(context_provider); if (g_should_fail_drawing_buffer_creation_for_testing) { @@ -119,7 +120,7 @@ std::move(context_provider), std::move(extensions_util), client, discard_framebuffer_supported, want_alpha_channel, premultiplied_alpha, preserve, web_gl_version, want_depth_buffer, want_stencil_buffer, - chromium_image_usage)); + chromium_image_usage, color_params)); if (!drawing_buffer->Initialize(size, multisample_supported)) { drawing_buffer->BeginDestruction(); return PassRefPtr<DrawingBuffer>(); @@ -142,7 +143,8 @@ WebGLVersion web_gl_version, bool want_depth, bool want_stencil, - ChromiumImageUsage chromium_image_usage) + ChromiumImageUsage chromium_image_usage, + const CanvasColorParams& color_params) : client_(client), preserve_drawing_buffer_(preserve), web_gl_version_(web_gl_version), @@ -156,7 +158,7 @@ software_rendering_(this->ContextProvider()->IsSoftwareRendering()), want_depth_(want_depth), want_stencil_(want_stencil), - color_space_(gfx::ColorSpace::CreateSRGB()), + color_space_(color_params.GetGfxColorSpace()), chromium_image_usage_(chromium_image_usage) { // Used by browser tests to detect the use of a DrawingBuffer. TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation",
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h index 16e778c..938c0c3 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
@@ -66,6 +66,7 @@ } namespace blink { +class CanvasColorParams; class Extensions3DUtil; class StaticBitmapImage; class WebExternalTextureLayer; @@ -121,7 +122,8 @@ bool want_antialiasing, PreserveDrawingBuffer, WebGLVersion, - ChromiumImageUsage); + ChromiumImageUsage, + const CanvasColorParams&); static void ForceNextDrawingBufferCreationToFail(); ~DrawingBuffer() override; @@ -241,7 +243,8 @@ WebGLVersion, bool wants_depth, bool wants_stencil, - ChromiumImageUsage); + ChromiumImageUsage, + const CanvasColorParams&); bool Initialize(const IntSize&, bool use_multisampling);
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp index d05d2335..6cd8201 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp
@@ -37,6 +37,7 @@ #include "gpu/command_buffer/client/gles2_interface_stub.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/sync_token.h" +#include "platform/graphics/CanvasColorParams.h" #include "platform/graphics/ImageBuffer.h" #include "platform/graphics/UnacceleratedImageBufferSurface.h" #include "platform/graphics/gpu/DrawingBufferTestHelpers.h" @@ -653,7 +654,7 @@ std::move(provider), nullptr, IntSize(10, 10), premultiplied_alpha, want_alpha_channel, want_depth_buffer, want_stencil_buffer, want_antialiasing, preserve, DrawingBuffer::kWebGL1, - DrawingBuffer::kAllowChromiumImage); + DrawingBuffer::kAllowChromiumImage, CanvasColorParams()); // When we request a depth or a stencil buffer, we will get both. EXPECT_EQ(cases[i].request_depth || cases[i].request_stencil,
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h index 7cc062f..35c078cc 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h
@@ -4,6 +4,7 @@ #include "gpu/command_buffer/common/capabilities.h" #include "platform/RuntimeEnabledFeatures.h" +#include "platform/graphics/CanvasColorParams.h" #include "platform/graphics/gpu/DrawingBuffer.h" #include "platform/graphics/gpu/Extensions3DUtil.h" #include "public/platform/WebGraphicsContext3DProvider.h" @@ -61,7 +62,8 @@ kWebGL1, false /* wantDepth */, false /* wantStencil */, - DrawingBuffer::kAllowChromiumImage /* ChromiumImageUsage */), + DrawingBuffer::kAllowChromiumImage /* ChromiumImageUsage */, + CanvasColorParams()), live_(0) {} ~DrawingBufferForTests() override {
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceRequest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceRequest.cpp index c67d741..60db8457 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceRequest.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceRequest.cpp
@@ -328,7 +328,7 @@ const AtomicString& value) { HTTPHeaderMap::AddResult result = http_header_fields_.Add(name, value); if (!result.is_new_entry) - result.stored_value->value = result.stored_value->value + ',' + value; + result.stored_value->value = result.stored_value->value + ", " + value; } void ResourceRequest::AddHTTPHeaderFields(const HTTPHeaderMap& header_fields) {
diff --git a/third_party/WebKit/Source/web/BUILD.gn b/third_party/WebKit/Source/web/BUILD.gn index 22fd373b..a709fe17 100644 --- a/third_party/WebKit/Source/web/BUILD.gn +++ b/third_party/WebKit/Source/web/BUILD.gn
@@ -73,8 +73,6 @@ "ExternalDateTimeChooser.h", "ExternalPopupMenu.cpp", "ExternalPopupMenu.h", - "FindInPageCoordinates.cpp", - "FindInPageCoordinates.h", "FullscreenController.cpp", "FullscreenController.h", "IndexedDBClientImpl.cpp",
diff --git a/third_party/WebKit/Source/web/TextFinder.cpp b/third_party/WebKit/Source/web/TextFinder.cpp index bf22601..905d4bd 100644 --- a/third_party/WebKit/Source/web/TextFinder.cpp +++ b/third_party/WebKit/Source/web/TextFinder.cpp
@@ -34,6 +34,7 @@ #include "core/dom/TaskRunnerHelper.h" #include "core/dom/shadow/ShadowRoot.h" #include "core/editing/Editor.h" +#include "core/editing/FindInPageCoordinates.h" #include "core/editing/VisibleSelection.h" #include "core/editing/iterators/SearchBuffer.h" #include "core/editing/markers/DocumentMarker.h" @@ -52,7 +53,6 @@ #include "public/web/WebFindOptions.h" #include "public/web/WebFrameClient.h" #include "public/web/WebViewClient.h" -#include "web/FindInPageCoordinates.h" #include "web/WebLocalFrameImpl.h" #include "web/WebViewImpl.h"
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp index d8e9cc2..0c15266 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -111,6 +111,7 @@ #include "core/dom/shadow/ShadowRoot.h" #include "core/editing/EditingUtilities.h" #include "core/editing/Editor.h" +#include "core/editing/FindInPageCoordinates.h" #include "core/editing/FrameSelection.h" #include "core/editing/InputMethodController.h" #include "core/editing/PlainTextRange.h" @@ -219,7 +220,6 @@ #include "public/web/WebTreeScopeType.h" #include "skia/ext/platform_canvas.h" #include "web/CompositionUnderlineVectorBuilder.h" -#include "web/FindInPageCoordinates.h" #include "web/RemoteFrameOwner.h" #include "web/SharedWorkerRepositoryClientImpl.h" #include "web/SuspendableScriptExecutor.h"
diff --git a/third_party/WebKit/Source/web/tests/TextFinderTest.cpp b/third_party/WebKit/Source/web/tests/TextFinderTest.cpp index 12360428..3c3cf1a 100644 --- a/third_party/WebKit/Source/web/tests/TextFinderTest.cpp +++ b/third_party/WebKit/Source/web/tests/TextFinderTest.cpp
@@ -9,6 +9,7 @@ #include "core/dom/NodeList.h" #include "core/dom/Range.h" #include "core/dom/shadow/ShadowRoot.h" +#include "core/editing/FindInPageCoordinates.h" #include "core/frame/FrameView.h" #include "core/frame/VisualViewport.h" #include "core/html/HTMLElement.h" @@ -19,7 +20,6 @@ #include "public/platform/Platform.h" #include "public/web/WebDocument.h" #include "testing/gtest/include/gtest/gtest.h" -#include "web/FindInPageCoordinates.h" #include "web/WebLocalFrameImpl.h" #include "web/tests/FrameTestHelpers.h"
diff --git a/third_party/WebKit/public/default_100_percent/blink/mediaremoting_cast.png b/third_party/WebKit/public/default_100_percent/blink/mediaremoting_cast.png index 6188c7af..583f1a8 100644 --- a/third_party/WebKit/public/default_100_percent/blink/mediaremoting_cast.png +++ b/third_party/WebKit/public/default_100_percent/blink/mediaremoting_cast.png Binary files differ
diff --git a/third_party/WebKit/public/default_200_percent/blink/mediaremoting_cast.png b/third_party/WebKit/public/default_200_percent/blink/mediaremoting_cast.png index 377c4e4..b2c5864 100644 --- a/third_party/WebKit/public/default_200_percent/blink/mediaremoting_cast.png +++ b/third_party/WebKit/public/default_200_percent/blink/mediaremoting_cast.png Binary files differ
diff --git a/third_party/WebKit/public/platform/WebPrivatePtr.h b/third_party/WebKit/public/platform/WebPrivatePtr.h index 6de994e..1349d00 100644 --- a/third_party/WebKit/public/platform/WebPrivatePtr.h +++ b/third_party/WebKit/public/platform/WebPrivatePtr.h
@@ -305,12 +305,12 @@ T* Get() const { return Storage().Get(); } T& operator*() const { - ASSERT(storage_); + DCHECK(storage_); return *Get(); } T* operator->() const { - ASSERT(storage_); + DCHECK(storage_); return Get(); } #endif
diff --git a/third_party/WebKit/public/web/WebTextDirection.h b/third_party/WebKit/public/web/WebTextDirection.h index 39686c8..c3718ec 100644 --- a/third_party/WebKit/public/web/WebTextDirection.h +++ b/third_party/WebKit/public/web/WebTextDirection.h
@@ -53,7 +53,7 @@ case TextDirection::kRtl: return kWebTextDirectionRightToLeft; } - ASSERT_NOT_REACHED(); + NOTREACHED(); return kWebTextDirectionDefault; } #endif
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index 4e3fd2d2..aae74a7 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -172,10 +172,10 @@ "structures": [15920], }, "components/resources/components_resources.grd": { - "includes": [15930], + "includes": [16030], }, "components/resources/components_scaled_resources.grd": { - "structures": [16050], + "structures": [16150], }, # END components/ section.
diff --git a/tools/licenses.py b/tools/licenses.py index 97600d4..8d0310aa 100755 --- a/tools/licenses.py +++ b/tools/licenses.py
@@ -19,6 +19,7 @@ import cgi import os import shutil +import re import subprocess import sys import tempfile @@ -480,6 +481,22 @@ return os.path.join(_REPOSITORY_ROOT, 'buildtools', subdir, exe) +def GetThirdPartyDepsFromGNDepsOutput(gn_deps): + """Returns third_party/foo directories given the output of "gn desc deps". + + Note that it always returns the direct sub-directory of third_party + where README.chromium and LICENSE files are, so that it can be passed to + ParseDir(). e.g.: + .../third_party/cld_3/src/src/BUILD.gn -> .../third_party/cld_3 + """ + third_party_deps = set() + for build_dep in gn_deps.split(): + m = re.search(r'^(.+/third_party/[^/]+)/(.+/)?BUILD\.gn$', build_dep) + if m: + third_party_deps.add(m.group(1)) + return third_party_deps + + def FindThirdPartyDeps(gn_out_dir, gn_target): if not gn_out_dir: raise RuntimeError("--gn-out-dir is required if --gn-target is used.") @@ -500,12 +517,7 @@ if tmp_dir and os.path.exists(tmp_dir): shutil.rmtree(tmp_dir) - third_party_deps = set() - for build_dep in gn_deps.split(): - if ("third_party" in build_dep and - os.path.basename(build_dep) == "BUILD.gn"): - third_party_deps.add(os.path.dirname(build_dep)) - return third_party_deps + return GetThirdPartyDepsFromGNDepsOutput(gn_deps) def ScanThirdPartyDirs(root=None):
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 97b63fd..d89cbc6 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -20550,6 +20550,16 @@ </summary> </histogram> +<histogram base="true" name="Favicons.DownloadAttempts" units="attempts"> + <owner>fhorschig@chromium.org</owner> + <summary> + Records the number of icons requested until the best-fitting candidate was + found or there were no candidates left to check. More than 15 attempts are + unlikely and will be stored in overflow bucket 16. Less than 1 attempt means + an error happened; these cases are in bucket 0. + </summary> +</histogram> + <histogram name="Favicons.LargeIconService.DownloadedSize" units="pixels"> <owner>jkrcal@chromium.org</owner> <summary> @@ -28435,6 +28445,14 @@ <summary>Pixel format used in HTML5 video. Emitted on video load.</summary> </histogram> +<histogram base="true" name="Media.VideoHeight.Initial" units="pixels"> + <owner>media-dev@chromium.org</owner> + <summary> + The height of the first video frame in an HTML5 video. Reported when the + first video frame is available. + </summary> +</histogram> + <histogram name="Media.VideoPersistence.AttemptResult" enum="VideoPersistenceAttemptResult"> <owner>mlamouri@chromium.org</owner> @@ -120618,6 +120636,13 @@ <affected-histogram name="Extensions.ExternalExtensionEvent"/> </histogram_suffixes> +<histogram_suffixes name="FaviconIconType" separator="."> + <suffix name="Favicons" label="Metrics for regular favicons."/> + <suffix name="LargeIcons" label="Metrics for large non-touch icons."/> + <suffix name="TouchIcons" label="Metrics for large touch icons."/> + <affected-histogram name="Favicons.DownloadAttempts"/> +</histogram_suffixes> + <histogram_suffixes name="FieldPredictionSubmissionEvents" separator="."> <suffix name="NoSubmission" label="No observed submission."/> <suffix name="BasedOnAutocomplete" @@ -121657,6 +121682,14 @@ <affected-histogram name="Media.VideoCaptureManager"/> </histogram_suffixes> +<histogram_suffixes name="MediaVideoCategories" separator="."> + <suffix name="All" label="All media with a video track."/> + <suffix name="EME" label="EME media with a video track."/> + <suffix name="MSE" label="MSE media with a video track."/> + <suffix name="SRC" label="SRC media with a video track."/> + <affected-histogram name="Media.VideoHeight.Initial"/> +</histogram_suffixes> + <histogram_suffixes name="MediaWatchTimeCategories" separator="."> <suffix name="Audio.All" label="Watch time for all media with only an audio track."/>
diff --git a/tools/tests/OWNERS b/tools/tests/OWNERS new file mode 100644 index 0000000..68295e64 --- /dev/null +++ b/tools/tests/OWNERS
@@ -0,0 +1 @@ +per-file licenses_test.py=file://tools/copyright_scanner/OWNERS
diff --git a/tools/tests/licenses_test.py b/tools/tests/licenses_test.py new file mode 100755 index 0000000..3a25f88 --- /dev/null +++ b/tools/tests/licenses_test.py
@@ -0,0 +1,41 @@ +#!/usr/bin/env python +# Copyright (c) 2017 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. + +"""Unit tests for //tools/licenses.py. +""" + +import os +import sys +import unittest + +REPOSITORY_ROOT = os.path.abspath(os.path.join( + os.path.dirname(__file__), '..', '..')) +sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools')) + +import licenses + + +class LicensesTest(unittest.TestCase): + + def test_get_third_party_deps_from_gn_deps_output(self): + third_party_deps = licenses.GetThirdPartyDepsFromGNDepsOutput( + '/home/example/src/net/BUILD.gn\n' + '/home/example/src/third_party/zlib/BUILD.gn\n' + '/home/example/src/third_party/cld_3/src/src/BUILD.gn\n') + + # '/home/example/src/net' is not in the output because it's not a + # third_party dependency. + # + # It must return the direct sub-directory of "third_party". So it should + # return '/home/example/src/third_party/cld_3', not + # '/home/example/src/third_party/cld_3/src/src'. + assert third_party_deps == set([ + '/home/example/src/third_party/zlib', + '/home/example/src/third_party/cld_3', + ]) + + +if __name__ == '__main__': + unittest.main()
diff --git a/ui/gfx/generic_shared_memory_id.cc b/ui/gfx/generic_shared_memory_id.cc index 33a5ef0..e9ed1c9 100644 --- a/ui/gfx/generic_shared_memory_id.cc +++ b/ui/gfx/generic_shared_memory_id.cc
@@ -9,7 +9,8 @@ namespace gfx { -base::trace_event::MemoryAllocatorDumpGuid GetGenericSharedMemoryGUIDForTracing( +base::trace_event::MemoryAllocatorDumpGuid +GetGenericSharedGpuMemoryGUIDForTracing( uint64_t tracing_process_id, GenericSharedMemoryId generic_shared_memory_id) { return base::trace_event::MemoryAllocatorDumpGuid(
diff --git a/ui/gfx/generic_shared_memory_id.h b/ui/gfx/generic_shared_memory_id.h index b18c869e..c9675af 100644 --- a/ui/gfx/generic_shared_memory_id.h +++ b/ui/gfx/generic_shared_memory_id.h
@@ -41,7 +41,7 @@ // Generates GUID which can be used to trace shared memory using its // GenericSharedMemoryId. GFX_EXPORT base::trace_event::MemoryAllocatorDumpGuid -GetGenericSharedMemoryGUIDForTracing( +GetGenericSharedGpuMemoryGUIDForTracing( uint64_t tracing_process_id, GenericSharedMemoryId generic_shared_memory_id);
diff --git a/ui/gfx/gpu_memory_buffer.cc b/ui/gfx/gpu_memory_buffer.cc index 3b85d06..185d461 100644 --- a/ui/gfx/gpu_memory_buffer.cc +++ b/ui/gfx/gpu_memory_buffer.cc
@@ -4,6 +4,8 @@ #include "ui/gfx/gpu_memory_buffer.h" +#include "ui/gfx/generic_shared_memory_id.h" + namespace gfx { GpuMemoryBufferHandle::GpuMemoryBufferHandle() @@ -49,4 +51,10 @@ return gfx::GpuMemoryBufferHandle(); } +base::trace_event::MemoryAllocatorDumpGuid GpuMemoryBuffer::GetGUIDForTracing( + uint64_t tracing_process_id) const { + return gfx::GetGenericSharedGpuMemoryGUIDForTracing(tracing_process_id, + GetId()); +} + } // namespace gfx
diff --git a/ui/gfx/gpu_memory_buffer.h b/ui/gfx/gpu_memory_buffer.h index df0112d..6d23c84 100644 --- a/ui/gfx/gpu_memory_buffer.h +++ b/ui/gfx/gpu_memory_buffer.h
@@ -9,6 +9,7 @@ #include <stdint.h> #include "base/memory/shared_memory.h" +#include "base/trace_event/memory_allocator_dump_guid.h" #include "build/build_config.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/generic_shared_memory_id.h" @@ -97,6 +98,10 @@ // Type-checking downcast routine. virtual ClientBuffer AsClientBuffer() = 0; + + // Returns the GUID for tracing. + virtual base::trace_event::MemoryAllocatorDumpGuid GetGUIDForTracing( + uint64_t tracing_process_id) const; }; // Returns an instance of |handle| which can be sent over IPC. This duplicates
diff --git a/ui/gfx/gpu_memory_buffer_tracing.cc b/ui/gfx/gpu_memory_buffer_tracing.cc index 86642b60..5f58707 100644 --- a/ui/gfx/gpu_memory_buffer_tracing.cc +++ b/ui/gfx/gpu_memory_buffer_tracing.cc
@@ -4,16 +4,18 @@ #include "ui/gfx/gpu_memory_buffer_tracing.h" +#include "base/format_macros.h" +#include "base/strings/stringprintf.h" + namespace gfx { -base::trace_event::MemoryAllocatorDumpGuid GetGpuMemoryBufferGUIDForTracing( +base::trace_event::MemoryAllocatorDumpGuid GetSharedMemoryGUIDForTracing( uint64_t tracing_process_id, GpuMemoryBufferId buffer_id) { - // TODO(ericrk): Currently this function just wraps - // GetGenericSharedMemoryGUIDForTracing, we may want to special case this if - // the GPU memory buffer is not backed by shared memory. - return gfx::GetGenericSharedMemoryGUIDForTracing(tracing_process_id, - buffer_id); + // TODO(hajimehoshi): This should be unified to shared memory GUIDs in + // base/memory/shared_memory_tracker.cc + return base::trace_event::MemoryAllocatorDumpGuid(base::StringPrintf( + "shared_memory_gpu/%" PRIx64 "/%d", tracing_process_id, buffer_id.id)); } } // namespace gfx
diff --git a/ui/gfx/gpu_memory_buffer_tracing.h b/ui/gfx/gpu_memory_buffer_tracing.h index 5ea918c..0b66a91a 100644 --- a/ui/gfx/gpu_memory_buffer_tracing.h +++ b/ui/gfx/gpu_memory_buffer_tracing.h
@@ -9,7 +9,7 @@ namespace gfx { base::trace_event::MemoryAllocatorDumpGuid GFX_EXPORT -GetGpuMemoryBufferGUIDForTracing(uint64_t tracing_process_id, - GpuMemoryBufferId buffer_id); +GetSharedMemoryGUIDForTracing(uint64_t tracing_process_id, + GpuMemoryBufferId buffer_id); } // namespace gfx
diff --git a/ui/gl/gl_image_io_surface.mm b/ui/gl/gl_image_io_surface.mm index 7bcb9626..8e20830 100644 --- a/ui/gl/gl_image_io_surface.mm +++ b/ui/gl/gl_image_io_surface.mm
@@ -375,8 +375,8 @@ base::trace_event::MemoryDumpManager::kInvalidTracingProcessId; } - auto guid = - GetGenericSharedMemoryGUIDForTracing(process_tracing_id, io_surface_id_); + auto guid = GetGenericSharedGpuMemoryGUIDForTracing(process_tracing_id, + io_surface_id_); pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid); }
diff --git a/ui/gl/gl_image_shared_memory.cc b/ui/gl/gl_image_shared_memory.cc index 83c8e5e..03f5aa87 100644 --- a/ui/gl/gl_image_shared_memory.cc +++ b/ui/gl/gl_image_shared_memory.cc
@@ -13,6 +13,7 @@ #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" #include "ui/gfx/buffer_format_util.h" +#include "ui/gfx/gpu_memory_buffer_tracing.h" namespace gl { @@ -87,8 +88,8 @@ base::trace_event::MemoryAllocatorDump::kUnitsBytes, static_cast<uint64_t>(size_in_bytes)); - auto guid = GetGenericSharedMemoryGUIDForTracing(process_tracing_id, - shared_memory_id_); + auto guid = + gfx::GetSharedMemoryGUIDForTracing(process_tracing_id, shared_memory_id_); pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid); }
diff --git a/ui/gl/yuv_to_rgb_converter.cc b/ui/gl/yuv_to_rgb_converter.cc index 1cb715d..daef399 100644 --- a/ui/gl/yuv_to_rgb_converter.cc +++ b/ui/gl/yuv_to_rgb_converter.cc
@@ -129,6 +129,7 @@ glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_texture1_binding); // Allocate the rgb texture. + glActiveTexture(old_active_texture); glBindTexture(target, rgb_texture); glTexImage2D(target, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
diff --git a/ui/message_center/views/message_list_view.cc b/ui/message_center/views/message_list_view.cc index 2551fab8..bd731b7 100644 --- a/ui/message_center/views/message_list_view.cc +++ b/ui/message_center/views/message_list_view.cc
@@ -312,7 +312,8 @@ } if (!clearing_all_views_.empty()) { - AnimateClearingOneNotification(); + if (!clear_all_started_) + AnimateClearingOneNotification(); return; }