diff --git a/.gitignore b/.gitignore index 42847de..d12ac93b 100644 --- a/.gitignore +++ b/.gitignore
@@ -439,6 +439,7 @@ /third_party/retrolambda/*.jar /third_party/robolectric/lib/*.jar /third_party/robolectric/robolectric +/third_party/scan-build/src /third_party/scons-2.0.1 /third_party/sfntly/src /third_party/shaderc/src
diff --git a/.gn b/.gn index 264ffac..be1fb72 100644 --- a/.gn +++ b/.gn
@@ -31,8 +31,10 @@ "//third_party/WebKit/Source/core/streams/CountQueuingStrategy.js", "//third_party/WebKit/Source/core/streams/ReadableStream.js", ] - v8_experimental_extra_library_files = - [ "//third_party/WebKit/Source/core/streams/WritableStream.js" ] + v8_experimental_extra_library_files = [ + "//third_party/WebKit/Source/core/streams/ReadableStreamExperimentalPipeTo.js", + "//third_party/WebKit/Source/core/streams/WritableStream.js", + ] v8_enable_inspector = true v8_enable_gdbjit = false v8_imminent_deprecation_warnings = false
diff --git a/DEPS b/DEPS index 23ba0d55..b7ac0c8 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': 'd6016013bdf843013f7fb8648fc5a64ce7e77005', + 'skia_revision': '964dec3948721808491b21b4ff4ff41a466443ec', # 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': 'f1c62827c0ce39bdef8c4e6dc7b5dc4df5397dd6', + 'v8_revision': '9b59b4b58270e9f5009b124e450cca2bd95ce6c7', # 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. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '5c1673db6deae2e1858c4ffc3b3a0b79901dd827', + 'pdfium_revision': '98909bf9f458614abc1bb7f4df34a319a1d5ce3f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -232,7 +232,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'd68fcc42256f0f6483d562aa69531091560ff9f2', # commit position 16134 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'eed2ae257f91a209b6fbe313903aec83250a6a63', # commit position 16296 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/base/BUILD.gn b/base/BUILD.gn index 7f46e71..fa5e369d 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -149,8 +149,6 @@ "allocator/allocator_check.h", "allocator/allocator_extension.cc", "allocator/allocator_extension.h", - "allocator/allocator_interception_mac.h", - "allocator/allocator_interception_mac.mm", "allocator/allocator_shim.h", "allocator/oom.h", "android/animation_frame_time_histogram.cc",
diff --git a/base/allocator/allocator_interception_mac.h b/base/allocator/allocator_interception_mac.h deleted file mode 100644 index 87cbf489..0000000 --- a/base/allocator/allocator_interception_mac.h +++ /dev/null
@@ -1,55 +0,0 @@ -// 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 BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_ -#define BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_ - -#include <malloc/malloc.h> -#include <stddef.h> - -#include "third_party/apple_apsl/malloc.h" - -namespace base { -namespace allocator { - -typedef void* (*malloc_type)(struct _malloc_zone_t* zone, size_t size); -typedef void* (*calloc_type)(struct _malloc_zone_t* zone, - size_t num_items, - size_t size); -typedef void* (*valloc_type)(struct _malloc_zone_t* zone, size_t size); -typedef void (*free_type)(struct _malloc_zone_t* zone, void* ptr); -typedef void* (*realloc_type)(struct _malloc_zone_t* zone, - void* ptr, - size_t size); -typedef void* (*memalign_type)(struct _malloc_zone_t* zone, - size_t alignment, - size_t size); - -struct MallocZoneFunctions { - malloc_type malloc = nullptr; - calloc_type calloc = nullptr; - valloc_type valloc = nullptr; - free_type free = nullptr; - realloc_type realloc = nullptr; - memalign_type memalign = nullptr; -}; - -// Saves the function pointers currently used by |zone| into |functions|. -void StoreZoneFunctions(ChromeMallocZone* zone, MallocZoneFunctions* functions); - -// Updates the malloc zone to use the functions specified by |functions|. -void ReplaceZoneFunctions(ChromeMallocZone* zone, - const MallocZoneFunctions* functions); - -// Calls the original implementation of malloc/calloc prior to interception. -bool UncheckedMallocMac(size_t size, void** result); -bool UncheckedCallocMac(size_t num_items, size_t size, void** result); - -// Intercepts calls to default and purgeable malloc zones. Intercepts Core -// Foundation and Objective-C allocations. -void InterceptAllocationsMac(); -} // namespace allocator -} // namespace base - -#endif // BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
diff --git a/base/allocator/allocator_interception_mac.mm b/base/allocator/allocator_interception_mac.mm deleted file mode 100644 index 941c5b4a..0000000 --- a/base/allocator/allocator_interception_mac.mm +++ /dev/null
@@ -1,471 +0,0 @@ -// 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. - -// This file contains all the logic necessary to intercept allocations on -// macOS. "malloc zones" are an abstraction that allows the process to intercept -// all malloc-related functions. There is no good mechanism [short of -// interposition] to determine new malloc zones are added, so there's no clean -// mechanism to intercept all malloc zones. This file contains logic to -// intercept the default and purgeable zones, which always exist. A cursory -// review of Chrome seems to imply that non-default zones are almost never used. -// -// This file also contains logic to intercept Core Foundation and Objective-C -// allocations. The implementations forward to the default malloc zone, so the -// only reason to intercept these calls is to re-label OOM crashes with slightly -// more details. - -#include "base/allocator/allocator_interception_mac.h" - -#include <CoreFoundation/CoreFoundation.h> -#import <Foundation/Foundation.h> -#include <errno.h> -#include <mach/mach.h> -#include <mach/mach_vm.h> -#import <objc/runtime.h> -#include <stddef.h> - -#include <new> - -#include "base/logging.h" -#include "base/mac/mac_util.h" -#include "base/mac/mach_logging.h" -#include "base/process/memory.h" -#include "base/scoped_clear_errno.h" -#include "build/build_config.h" -#include "third_party/apple_apsl/CFBase.h" - -namespace base { -namespace allocator { - -namespace { - -bool g_oom_killer_enabled; - -#if !defined(ADDRESS_SANITIZER) - -// Starting with Mac OS X 10.7, the zone allocators set up by the system are -// read-only, to prevent them from being overwritten in an attack. However, -// blindly unprotecting and reprotecting the zone allocators fails with -// GuardMalloc because GuardMalloc sets up its zone allocator using a block of -// memory in its bss. Explicit saving/restoring of the protection is required. -// -// This function takes a pointer to a malloc zone, de-protects it if necessary, -// and returns (in the out parameters) a region of memory (if any) to be -// re-protected when modifications are complete. This approach assumes that -// there is no contention for the protection of this memory. -void DeprotectMallocZone(ChromeMallocZone* default_zone, - mach_vm_address_t* reprotection_start, - mach_vm_size_t* reprotection_length, - vm_prot_t* reprotection_value) { - mach_port_t unused; - *reprotection_start = reinterpret_cast<mach_vm_address_t>(default_zone); - struct vm_region_basic_info_64 info; - mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; - kern_return_t result = mach_vm_region( - mach_task_self(), reprotection_start, reprotection_length, - VM_REGION_BASIC_INFO_64, reinterpret_cast<vm_region_info_t>(&info), - &count, &unused); - MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_region"; - - // The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but - // balance it with a deallocate in case this ever changes. See 10.9.2 - // xnu-2422.90.20/osfmk/vm/vm_map.c vm_map_region. - mach_port_deallocate(mach_task_self(), unused); - - // Does the region fully enclose the zone pointers? Possibly unwarranted - // simplification used: using the size of a full version 8 malloc zone rather - // than the actual smaller size if the passed-in zone is not version 8. - CHECK(*reprotection_start <= - reinterpret_cast<mach_vm_address_t>(default_zone)); - mach_vm_size_t zone_offset = - reinterpret_cast<mach_vm_size_t>(default_zone) - - reinterpret_cast<mach_vm_size_t>(*reprotection_start); - CHECK(zone_offset + sizeof(ChromeMallocZone) <= *reprotection_length); - - if (info.protection & VM_PROT_WRITE) { - // No change needed; the zone is already writable. - *reprotection_start = 0; - *reprotection_length = 0; - *reprotection_value = VM_PROT_NONE; - } else { - *reprotection_value = info.protection; - result = mach_vm_protect(mach_task_self(), *reprotection_start, - *reprotection_length, false, - info.protection | VM_PROT_WRITE); - MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect"; - } -} - -MallocZoneFunctions g_old_zone; -MallocZoneFunctions g_old_purgeable_zone; - -void* oom_killer_malloc(struct _malloc_zone_t* zone, size_t size) { - void* result = g_old_zone.malloc(zone, size); - if (!result && size) - TerminateBecauseOutOfMemory(size); - return result; -} - -void* oom_killer_calloc(struct _malloc_zone_t* zone, - size_t num_items, - size_t size) { - void* result = g_old_zone.calloc(zone, num_items, size); - if (!result && num_items && size) - TerminateBecauseOutOfMemory(num_items * size); - return result; -} - -void* oom_killer_valloc(struct _malloc_zone_t* zone, size_t size) { - void* result = g_old_zone.valloc(zone, size); - if (!result && size) - TerminateBecauseOutOfMemory(size); - return result; -} - -void oom_killer_free(struct _malloc_zone_t* zone, void* ptr) { - g_old_zone.free(zone, ptr); -} - -void* oom_killer_realloc(struct _malloc_zone_t* zone, void* ptr, size_t size) { - void* result = g_old_zone.realloc(zone, ptr, size); - if (!result && size) - TerminateBecauseOutOfMemory(size); - return result; -} - -void* oom_killer_memalign(struct _malloc_zone_t* zone, - size_t alignment, - size_t size) { - void* result = g_old_zone.memalign(zone, alignment, size); - // Only die if posix_memalign would have returned ENOMEM, since there are - // other reasons why NULL might be returned (see - // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ). - if (!result && size && alignment >= sizeof(void*) && - (alignment & (alignment - 1)) == 0) { - TerminateBecauseOutOfMemory(size); - } - return result; -} - -void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone, size_t size) { - void* result = g_old_purgeable_zone.malloc(zone, size); - if (!result && size) - TerminateBecauseOutOfMemory(size); - return result; -} - -void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone, - size_t num_items, - size_t size) { - void* result = g_old_purgeable_zone.calloc(zone, num_items, size); - if (!result && num_items && size) - TerminateBecauseOutOfMemory(num_items * size); - return result; -} - -void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone, size_t size) { - void* result = g_old_purgeable_zone.valloc(zone, size); - if (!result && size) - TerminateBecauseOutOfMemory(size); - return result; -} - -void oom_killer_free_purgeable(struct _malloc_zone_t* zone, void* ptr) { - g_old_purgeable_zone.free(zone, ptr); -} - -void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone, - void* ptr, - size_t size) { - void* result = g_old_purgeable_zone.realloc(zone, ptr, size); - if (!result && size) - TerminateBecauseOutOfMemory(size); - return result; -} - -void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone, - size_t alignment, - size_t size) { - void* result = g_old_purgeable_zone.memalign(zone, alignment, size); - // Only die if posix_memalign would have returned ENOMEM, since there are - // other reasons why NULL might be returned (see - // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ). - if (!result && size && alignment >= sizeof(void*) && - (alignment & (alignment - 1)) == 0) { - TerminateBecauseOutOfMemory(size); - } - return result; -} - -#endif // !defined(ADDRESS_SANITIZER) - -// === C++ operator new === - -void oom_killer_new() { - TerminateBecauseOutOfMemory(0); -} - -#if !defined(ADDRESS_SANITIZER) - -// === Core Foundation CFAllocators === - -bool CanGetContextForCFAllocator() { - return !base::mac::IsOSLaterThan10_12_DontCallThis(); -} - -CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) { - ChromeCFAllocatorLions* our_allocator = const_cast<ChromeCFAllocatorLions*>( - reinterpret_cast<const ChromeCFAllocatorLions*>(allocator)); - return &our_allocator->_context; -} - -CFAllocatorAllocateCallBack g_old_cfallocator_system_default; -CFAllocatorAllocateCallBack g_old_cfallocator_malloc; -CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone; - -void* oom_killer_cfallocator_system_default(CFIndex alloc_size, - CFOptionFlags hint, - void* info) { - void* result = g_old_cfallocator_system_default(alloc_size, hint, info); - if (!result) - TerminateBecauseOutOfMemory(alloc_size); - return result; -} - -void* oom_killer_cfallocator_malloc(CFIndex alloc_size, - CFOptionFlags hint, - void* info) { - void* result = g_old_cfallocator_malloc(alloc_size, hint, info); - if (!result) - TerminateBecauseOutOfMemory(alloc_size); - return result; -} - -void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size, - CFOptionFlags hint, - void* info) { - void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info); - if (!result) - TerminateBecauseOutOfMemory(alloc_size); - return result; -} - -#endif // !defined(ADDRESS_SANITIZER) - -// === Cocoa NSObject allocation === - -typedef id (*allocWithZone_t)(id, SEL, NSZone*); -allocWithZone_t g_old_allocWithZone; - -id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) { - id result = g_old_allocWithZone(self, _cmd, zone); - if (!result) - TerminateBecauseOutOfMemory(0); - return result; -} - -} // namespace - -bool UncheckedMallocMac(size_t size, void** result) { -#if defined(ADDRESS_SANITIZER) - *result = malloc(size); -#else - if (g_old_zone.malloc) { - *result = g_old_zone.malloc(malloc_default_zone(), size); - } else { - *result = malloc(size); - } -#endif // defined(ADDRESS_SANITIZER) - - return *result != NULL; -} - -bool UncheckedCallocMac(size_t num_items, size_t size, void** result) { -#if defined(ADDRESS_SANITIZER) - *result = calloc(num_items, size); -#else - if (g_old_zone.calloc) { - *result = g_old_zone.calloc(malloc_default_zone(), num_items, size); - } else { - *result = calloc(num_items, size); - } -#endif // defined(ADDRESS_SANITIZER) - - return *result != NULL; -} - -void StoreZoneFunctions(ChromeMallocZone* zone, - MallocZoneFunctions* functions) { - functions->malloc = zone->malloc; - functions->calloc = zone->calloc; - functions->valloc = zone->valloc; - functions->free = zone->free; - functions->realloc = zone->realloc; - CHECK(functions->malloc && functions->calloc && functions->valloc && - functions->free && functions->realloc); - - if (zone->version >= 5) { - functions->memalign = zone->memalign; - CHECK(functions->memalign); - } -} - -void ReplaceZoneFunctions(ChromeMallocZone* zone, - const MallocZoneFunctions* functions) { - // Remove protection. - mach_vm_address_t reprotection_start = 0; - mach_vm_size_t reprotection_length = 0; - vm_prot_t reprotection_value = VM_PROT_NONE; - DeprotectMallocZone(zone, &reprotection_start, &reprotection_length, - &reprotection_value); - - zone->malloc = functions->malloc; - zone->calloc = functions->calloc; - zone->valloc = functions->valloc; - zone->free = functions->free; - zone->realloc = functions->realloc; - if (zone->version >= 5) { - zone->memalign = functions->memalign; - } - - // Restore protection if it was active. - if (reprotection_start) { - kern_return_t result = - mach_vm_protect(mach_task_self(), reprotection_start, - reprotection_length, false, reprotection_value); - MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect"; - } -} - -void InterceptAllocationsMac() { - if (g_oom_killer_enabled) - return; - - g_oom_killer_enabled = true; - -// === C malloc/calloc/valloc/realloc/posix_memalign === - -// This approach is not perfect, as requests for amounts of memory larger than -// MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will -// still fail with a NULL rather than dying (see -// http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details). -// Unfortunately, it's the best we can do. Also note that this does not affect -// allocations from non-default zones. - -#if !defined(ADDRESS_SANITIZER) - // Don't do anything special on OOM for the malloc zones replaced by - // AddressSanitizer, as modifying or protecting them may not work correctly. - ChromeMallocZone* default_zone = - reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); - StoreZoneFunctions(default_zone, &g_old_zone); - MallocZoneFunctions new_functions; - new_functions.malloc = oom_killer_malloc; - new_functions.calloc = oom_killer_calloc; - new_functions.valloc = oom_killer_valloc; - new_functions.free = oom_killer_free; - new_functions.realloc = oom_killer_realloc; - new_functions.memalign = oom_killer_memalign; - ReplaceZoneFunctions(default_zone, &new_functions); - - ChromeMallocZone* purgeable_zone = - reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone()); - if (purgeable_zone) { - StoreZoneFunctions(purgeable_zone, &g_old_purgeable_zone); - MallocZoneFunctions new_functions; - new_functions.malloc = oom_killer_malloc_purgeable; - new_functions.calloc = oom_killer_calloc_purgeable; - new_functions.valloc = oom_killer_valloc_purgeable; - new_functions.free = oom_killer_free_purgeable; - new_functions.realloc = oom_killer_realloc_purgeable; - new_functions.memalign = oom_killer_memalign_purgeable; - ReplaceZoneFunctions(purgeable_zone, &new_functions); - } -#endif - - // === C malloc_zone_batch_malloc === - - // batch_malloc is omitted because the default malloc zone's implementation - // only supports batch_malloc for "tiny" allocations from the free list. It - // will fail for allocations larger than "tiny", and will only allocate as - // many blocks as it's able to from the free list. These factors mean that it - // can return less than the requested memory even in a non-out-of-memory - // situation. There's no good way to detect whether a batch_malloc failure is - // due to these other factors, or due to genuine memory or address space - // exhaustion. The fact that it only allocates space from the "tiny" free list - // means that it's likely that a failure will not be due to memory exhaustion. - // Similarly, these constraints on batch_malloc mean that callers must always - // be expecting to receive less memory than was requested, even in situations - // where memory pressure is not a concern. Finally, the only public interface - // to batch_malloc is malloc_zone_batch_malloc, which is specific to the - // system's malloc implementation. It's unlikely that anyone's even heard of - // it. - - // === C++ operator new === - - // Yes, operator new does call through to malloc, but this will catch failures - // that our imperfect handling of malloc cannot. - - std::set_new_handler(oom_killer_new); - -#ifndef ADDRESS_SANITIZER - // === Core Foundation CFAllocators === - - // This will not catch allocation done by custom allocators, but will catch - // all allocation done by system-provided ones. - - CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc && - !g_old_cfallocator_malloc_zone) - << "Old allocators unexpectedly non-null"; - - bool cf_allocator_internals_known = CanGetContextForCFAllocator(); - - if (cf_allocator_internals_known) { - CFAllocatorContext* context = - ContextForCFAllocator(kCFAllocatorSystemDefault); - CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault."; - g_old_cfallocator_system_default = context->allocate; - CHECK(g_old_cfallocator_system_default) - << "Failed to get kCFAllocatorSystemDefault allocation function."; - context->allocate = oom_killer_cfallocator_system_default; - - context = ContextForCFAllocator(kCFAllocatorMalloc); - CHECK(context) << "Failed to get context for kCFAllocatorMalloc."; - g_old_cfallocator_malloc = context->allocate; - CHECK(g_old_cfallocator_malloc) - << "Failed to get kCFAllocatorMalloc allocation function."; - context->allocate = oom_killer_cfallocator_malloc; - - context = ContextForCFAllocator(kCFAllocatorMallocZone); - CHECK(context) << "Failed to get context for kCFAllocatorMallocZone."; - g_old_cfallocator_malloc_zone = context->allocate; - CHECK(g_old_cfallocator_malloc_zone) - << "Failed to get kCFAllocatorMallocZone allocation function."; - context->allocate = oom_killer_cfallocator_malloc_zone; - } else { - DLOG(WARNING) << "Internals of CFAllocator not known; out-of-memory " - "failures via CFAllocator will not result in termination. " - "http://crbug.com/45650"; - } -#endif - - // === Cocoa NSObject allocation === - - // Note that both +[NSObject new] and +[NSObject alloc] call through to - // +[NSObject allocWithZone:]. - - CHECK(!g_old_allocWithZone) << "Old allocator unexpectedly non-null"; - - Class nsobject_class = [NSObject class]; - Method orig_method = - class_getClassMethod(nsobject_class, @selector(allocWithZone:)); - g_old_allocWithZone = - reinterpret_cast<allocWithZone_t>(method_getImplementation(orig_method)); - CHECK(g_old_allocWithZone) - << "Failed to get allocWithZone allocation function."; - method_setImplementation(orig_method, - reinterpret_cast<IMP>(oom_killer_allocWithZone)); -} - -} // namespace allocator -} // namespace base
diff --git a/base/debug/activity_analyzer.cc b/base/debug/activity_analyzer.cc index 6a483f3..7c421e9 100644 --- a/base/debug/activity_analyzer.cc +++ b/base/debug/activity_analyzer.cc
@@ -31,7 +31,7 @@ : ThreadActivityAnalyzer(allocator->GetAsArray<char>( reference, GlobalActivityTracker::kTypeIdActivityTracker, - 1), + PersistentMemoryAllocator::kSizeAny), allocator->GetAllocSize(reference)) {} ThreadActivityAnalyzer::~ThreadActivityAnalyzer() {} @@ -159,6 +159,26 @@ return messages; } +std::vector<GlobalActivityTracker::ModuleInfo> +GlobalActivityAnalyzer::GetModules() { + std::vector<GlobalActivityTracker::ModuleInfo> modules; + + PersistentMemoryAllocator::Iterator iter(allocator_.get()); + const GlobalActivityTracker::ModuleInfoRecord* record; + while ( + (record = + iter.GetNextOfObject<GlobalActivityTracker::ModuleInfoRecord>()) != + nullptr) { + GlobalActivityTracker::ModuleInfo info; + if (record->DecodeTo(&info, allocator_->GetAllocSize( + allocator_->GetAsReference(record)))) { + modules.push_back(std::move(info)); + } + } + + return modules; +} + GlobalActivityAnalyzer::ProgramLocation GlobalActivityAnalyzer::GetProgramLocationFromAddress(uint64_t address) { // TODO(bcwhite): Implement this.
diff --git a/base/debug/activity_analyzer.h b/base/debug/activity_analyzer.h index 48efd85..95df69fd 100644 --- a/base/debug/activity_analyzer.h +++ b/base/debug/activity_analyzer.h
@@ -155,6 +155,9 @@ // Gets all log messages stored within. std::vector<std::string> GetLogMessages(); + // Gets all the known modules. + std::vector<GlobalActivityTracker::ModuleInfo> GetModules(); + // Gets the corresponding "program location" for a given "program counter". // This will return {0,0} if no mapping could be found. ProgramLocation GetProgramLocationFromAddress(uint64_t address);
diff --git a/base/debug/activity_analyzer_unittest.cc b/base/debug/activity_analyzer_unittest.cc index 08ed85c..7f1bce9 100644 --- a/base/debug/activity_analyzer_unittest.cc +++ b/base/debug/activity_analyzer_unittest.cc
@@ -321,6 +321,82 @@ EXPECT_EQ(strlen(string2), snapshot.at("sref").GetStringReference().size()); } +TEST_F(ActivityAnalyzerTest, GlobalModulesTest) { + GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); + + PersistentMemoryAllocator* allocator = + GlobalActivityTracker::Get()->allocator(); + GlobalActivityAnalyzer global_analyzer(MakeUnique<PersistentMemoryAllocator>( + const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); + + GlobalActivityTracker::ModuleInfo info1; + info1.is_loaded = true; + info1.address = 0x12345678; + info1.load_time = 1111; + info1.size = 0xABCDEF; + info1.timestamp = 111; + info1.age = 11; + info1.identifier[0] = 1; + info1.file = "anything"; + info1.debug_file = "elsewhere"; + + GlobalActivityTracker::Get()->RecordModuleInfo(info1); + std::vector<GlobalActivityTracker::ModuleInfo> modules1; + modules1 = global_analyzer.GetModules(); + ASSERT_EQ(1U, modules1.size()); + GlobalActivityTracker::ModuleInfo& stored1a = modules1[0]; + EXPECT_EQ(info1.is_loaded, stored1a.is_loaded); + EXPECT_EQ(info1.address, stored1a.address); + EXPECT_NE(info1.load_time, stored1a.load_time); + EXPECT_EQ(info1.size, stored1a.size); + EXPECT_EQ(info1.timestamp, stored1a.timestamp); + EXPECT_EQ(info1.age, stored1a.age); + EXPECT_EQ(info1.identifier[0], stored1a.identifier[0]); + EXPECT_EQ(info1.file, stored1a.file); + EXPECT_EQ(info1.debug_file, stored1a.debug_file); + + info1.is_loaded = false; + GlobalActivityTracker::Get()->RecordModuleInfo(info1); + modules1 = global_analyzer.GetModules(); + ASSERT_EQ(1U, modules1.size()); + GlobalActivityTracker::ModuleInfo& stored1b = modules1[0]; + EXPECT_EQ(info1.is_loaded, stored1b.is_loaded); + EXPECT_EQ(info1.address, stored1b.address); + EXPECT_NE(info1.load_time, stored1b.load_time); + EXPECT_EQ(info1.size, stored1b.size); + EXPECT_EQ(info1.timestamp, stored1b.timestamp); + EXPECT_EQ(info1.age, stored1b.age); + EXPECT_EQ(info1.identifier[0], stored1b.identifier[0]); + EXPECT_EQ(info1.file, stored1b.file); + EXPECT_EQ(info1.debug_file, stored1b.debug_file); + + GlobalActivityTracker::ModuleInfo info2; + info2.is_loaded = true; + info2.address = 0x87654321; + info2.load_time = 2222; + info2.size = 0xFEDCBA; + info2.timestamp = 222; + info2.age = 22; + info2.identifier[0] = 2; + info2.file = "nothing"; + info2.debug_file = "farewell"; + + GlobalActivityTracker::Get()->RecordModuleInfo(info2); + std::vector<GlobalActivityTracker::ModuleInfo> modules2; + modules2 = global_analyzer.GetModules(); + ASSERT_EQ(2U, modules2.size()); + GlobalActivityTracker::ModuleInfo& stored2 = modules2[1]; + EXPECT_EQ(info2.is_loaded, stored2.is_loaded); + EXPECT_EQ(info2.address, stored2.address); + EXPECT_NE(info2.load_time, stored2.load_time); + EXPECT_EQ(info2.size, stored2.size); + EXPECT_EQ(info2.timestamp, stored2.timestamp); + EXPECT_EQ(info2.age, stored2.age); + EXPECT_EQ(info2.identifier[0], stored2.identifier[0]); + EXPECT_EQ(info2.file, stored2.file); + EXPECT_EQ(info2.debug_file, stored2.debug_file); +} + TEST_F(ActivityAnalyzerTest, GlobalLogMessages) { GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3);
diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc index c728fa05..deb1717 100644 --- a/base/debug/activity_tracker.cc +++ b/base/debug/activity_tracker.cc
@@ -17,6 +17,7 @@ #include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" #include "base/pending_task.h" +#include "base/pickle.h" #include "base/process/process.h" #include "base/process/process_handle.h" #include "base/stl_util.h" @@ -44,6 +45,9 @@ const size_t kMaxUserDataNameLength = static_cast<size_t>(std::numeric_limits<uint8_t>::max()); +// A constant used to indicate that module information is changing. +const uint32_t kModuleInformationChanging = 0x80000000; + union ThreadRef { int64_t as_id; #if defined(OS_WIN) @@ -478,6 +482,10 @@ // the very first time the thread is seen. All fields must be of exact sizes // so there is no issue moving between 32 and 64-bit builds. struct ThreadActivityTracker::Header { + // Defined in .h for analyzer access. Increment this if structure changes! + static constexpr uint32_t kPersistentTypeId = + GlobalActivityTracker::kTypeIdActivityTracker; + // Expected size for 32/64-bit check. static constexpr size_t kExpectedInstanceSize = 80; @@ -894,6 +902,119 @@ GlobalActivityTracker* GlobalActivityTracker::g_tracker_ = nullptr; +GlobalActivityTracker::ModuleInfo::ModuleInfo() {} +GlobalActivityTracker::ModuleInfo::ModuleInfo(ModuleInfo&& rhs) = default; +GlobalActivityTracker::ModuleInfo::ModuleInfo(const ModuleInfo& rhs) = default; +GlobalActivityTracker::ModuleInfo::~ModuleInfo() {} + +GlobalActivityTracker::ModuleInfo& GlobalActivityTracker::ModuleInfo::operator=( + ModuleInfo&& rhs) = default; +GlobalActivityTracker::ModuleInfo& GlobalActivityTracker::ModuleInfo::operator=( + const ModuleInfo& rhs) = default; + +GlobalActivityTracker::ModuleInfoRecord::ModuleInfoRecord() {} +GlobalActivityTracker::ModuleInfoRecord::~ModuleInfoRecord() {} + +bool GlobalActivityTracker::ModuleInfoRecord::DecodeTo( + GlobalActivityTracker::ModuleInfo* info, + size_t record_size) const { + // Get the current "changes" indicator, acquiring all the other values. + uint32_t current_changes = changes.load(std::memory_order_acquire); + + // Copy out the dynamic information. + info->is_loaded = loaded != 0; + info->address = static_cast<uintptr_t>(address); + info->load_time = load_time; + + // Check to make sure no information changed while being read. A "seq-cst" + // operation is expensive but is only done during analysis and it's the only + // way to ensure this occurs after all the accesses above. If changes did + // occur then return a "not loaded" result so that |size| and |address| + // aren't expected to be accurate. + if ((current_changes & kModuleInformationChanging) != 0 || + changes.load(std::memory_order_seq_cst) != current_changes) { + info->is_loaded = false; + } + + // Copy out the static information. These never change so don't have to be + // protected by the atomic |current_changes| operations. + info->size = static_cast<size_t>(size); + info->timestamp = timestamp; + info->age = age; + memcpy(info->identifier, identifier, sizeof(info->identifier)); + + if (offsetof(ModuleInfoRecord, pickle) + pickle_size > record_size) + return false; + Pickle pickler(pickle, pickle_size); + PickleIterator iter(pickler); + return iter.ReadString(&info->file) && iter.ReadString(&info->debug_file); +} + +bool GlobalActivityTracker::ModuleInfoRecord::EncodeFrom( + const GlobalActivityTracker::ModuleInfo& info, + size_t record_size) { + Pickle pickler; + bool okay = + pickler.WriteString(info.file) && pickler.WriteString(info.debug_file); + if (!okay) { + NOTREACHED(); + return false; + } + if (offsetof(ModuleInfoRecord, pickle) + pickler.size() > record_size) { + NOTREACHED(); + return false; + } + + // These fields never changes and are done before the record is made + // iterable so no thread protection is necessary. + size = info.size; + timestamp = info.timestamp; + age = info.age; + memcpy(identifier, info.identifier, sizeof(identifier)); + memcpy(pickle, pickler.data(), pickler.size()); + pickle_size = pickler.size(); + changes.store(0, std::memory_order_relaxed); + + // Now set those fields that can change. + return UpdateFrom(info); +} + +bool GlobalActivityTracker::ModuleInfoRecord::UpdateFrom( + const GlobalActivityTracker::ModuleInfo& info) { + // Updates can occur after the record is made visible so make changes atomic. + // A "strong" exchange ensures no false failures. + uint32_t old_changes = changes.load(std::memory_order_relaxed); + uint32_t new_changes = old_changes | kModuleInformationChanging; + if ((old_changes & kModuleInformationChanging) != 0 || + !changes.compare_exchange_strong(old_changes, new_changes, + std::memory_order_acquire, + std::memory_order_acquire)) { + NOTREACHED() << "Multiple sources are updating module information."; + return false; + } + + loaded = info.is_loaded ? 1 : 0; + address = info.address; + load_time = Time::Now().ToInternalValue(); + + bool success = changes.compare_exchange_strong(new_changes, old_changes + 1, + std::memory_order_release, + std::memory_order_relaxed); + DCHECK(success); + return true; +} + +// static +size_t GlobalActivityTracker::ModuleInfoRecord::EncodedSize( + const GlobalActivityTracker::ModuleInfo& info) { + PickleSizer sizer; + sizer.AddString(info.file); + sizer.AddString(info.debug_file); + + return offsetof(ModuleInfoRecord, pickle) + sizeof(Pickle::Header) + + sizer.payload_size(); +} + GlobalActivityTracker::ScopedThreadActivity::ScopedThreadActivity( const void* program_counter, const void* origin, @@ -1022,13 +1143,8 @@ // TODO(bcwhite): Review this after major compiler releases. DCHECK(mem_reference); void* mem_base; -#if 0 // TODO(bcwhite): Update this for new GetAsObject functionality. - mem_base = allocator_->GetAsObject<ThreadActivityTracker::Header>( - mem_reference, kTypeIdActivityTracker); -#else - mem_base = allocator_->GetAsArray<char>(mem_reference, kTypeIdActivityTracker, - PersistentMemoryAllocator::kSizeAny); -#endif + mem_base = + allocator_->GetAsObject<ThreadActivityTracker::Header>(mem_reference); DCHECK(mem_base); DCHECK_LE(stack_memory_size_, allocator_->GetAllocSize(mem_reference)); @@ -1066,6 +1182,33 @@ } } +void GlobalActivityTracker::RecordModuleInfo(const ModuleInfo& info) { + AutoLock lock(modules_lock_); + auto found = modules_.find(info.file); + if (found != modules_.end()) { + ModuleInfoRecord* record = found->second; + DCHECK(record); + + // Update the basic state of module information that has been already + // recorded. It is assumed that the string information (identifier, + // version, etc.) remain unchanged which means that there's no need + // to create a new record to accommodate a possibly longer length. + record->UpdateFrom(info); + return; + } + + size_t required_size = ModuleInfoRecord::EncodedSize(info); + ModuleInfoRecord* record = + allocator_->AllocateObject<ModuleInfoRecord>(required_size); + if (!record) + return; + + bool success = record->EncodeFrom(info, required_size); + DCHECK(success); + allocator_->MakeIterable(record); + modules_.insert(std::make_pair(info.file, record)); +} + GlobalActivityTracker::GlobalActivityTracker( std::unique_ptr<PersistentMemoryAllocator> allocator, int stack_depth) @@ -1099,8 +1242,7 @@ DCHECK(!g_tracker_); g_tracker_ = this; - // The global user-data record must be iterable in order to be found by an - // analyzer. + // The global records must be iterable in order to be found by an analyzer. allocator_->MakeIterable(allocator_->GetAsReference( user_data_.GetBaseAddress(), kTypeIdGlobalDataRecord)); }
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h index 62f983b..2d3c2bc7 100644 --- a/base/debug/activity_tracker.h +++ b/base/debug/activity_tracker.h
@@ -646,6 +646,32 @@ kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, }; + // This structure contains information about a loaded module, as shown to + // users of the tracker. + struct BASE_EXPORT ModuleInfo { + ModuleInfo(); + ModuleInfo(ModuleInfo&& rhs); + ModuleInfo(const ModuleInfo& rhs); + ~ModuleInfo(); + + ModuleInfo& operator=(ModuleInfo&& rhs); + ModuleInfo& operator=(const ModuleInfo& rhs); + + // Information about where and when the module was loaded/unloaded. + bool is_loaded = false; // Was the last operation a load or unload? + uintptr_t address = 0; // Address of the last load operation. + int64_t load_time = 0; // Time of last change; set automatically. + + // Information about the module itself. These never change no matter how + // many times a module may be loaded and unloaded. + size_t size = 0; // The size of the loaded module. + uint32_t timestamp = 0; // Opaque "timestamp" for the module. + uint32_t age = 0; // Opaque "age" for the module. + uint8_t identifier[16]; // Opaque identifier (GUID, etc.) for the module. + std::string file; // The full path to the file. (UTF-8) + std::string debug_file; // The full path to the debug file. + }; + // This is a thin wrapper around the thread-tracker's ScopedActivity that // accesses the global tracker to provide some of the information, notably // which thread-tracker to use. It is safe to create even if activity @@ -749,10 +775,15 @@ // only store critical messages such as FATAL ones. void RecordLogMessage(StringPiece message); + // Records a module load/unload event. This is safe to call multiple times + // even with the same information. + void RecordModuleInfo(const ModuleInfo& info); + // Accesses the global data record for storing arbitrary key/value pairs. ActivityUserData& user_data() { return user_data_; } private: + friend class GlobalActivityAnalyzer; friend class ScopedThreadActivity; friend class ActivityTrackerTest; @@ -764,6 +795,51 @@ kCachedUserDataMemories = 10, }; + // State of a module as stored in persistent memory. This supports a single + // loading of a module only. If modules are loaded multiple times at + // different addresses, only the last will be recorded and an unload will + // not revert to the information of any other addresses. + struct BASE_EXPORT ModuleInfoRecord { + // SHA1(ModuleInfoRecord): Increment this if structure changes! + static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; + + // Expected size for 32/64-bit check by PersistentMemoryAllocator. + static constexpr size_t kExpectedInstanceSize = 56; + + // The atomic unfortunately makes this a "complex" class on some compilers + // and thus requires an out-of-line constructor & destructor even though + // they do nothing. + ModuleInfoRecord(); + ~ModuleInfoRecord(); + + uint64_t address; // The base address of the module. + uint64_t load_time; // Time of last load/unload. + uint64_t size; // The size of the module in bytes. + uint32_t timestamp; // Opaque timestamp of the module. + uint32_t age; // Opaque "age" associated with the module. + uint8_t identifier[16]; // Opaque identifier for the module. + std::atomic<uint32_t> changes; // Number load/unload actions. + uint16_t pickle_size; // The size of the following pickle. + uint8_t loaded; // Flag if module is loaded or not. + char pickle[1]; // Other strings; may allocate larger. + + // Decodes/encodes storage structure from more generic info structure. + bool DecodeTo(GlobalActivityTracker::ModuleInfo* info, + size_t record_size) const; + bool EncodeFrom(const GlobalActivityTracker::ModuleInfo& info, + size_t record_size); + + // Updates the core information without changing the encoded strings. This + // is useful when a known module changes state (i.e. new load or unload). + bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info); + + // Determines the required memory size for the encoded storage. + static size_t EncodedSize(const GlobalActivityTracker::ModuleInfo& info); + + private: + DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord); + }; + // A thin wrapper around the main thread-tracker that keeps additional // information that the global tracker needs to handle joined threads. class ManagedActivityTracker : public ThreadActivityTracker { @@ -825,6 +901,10 @@ // be written from the main UI thread. ActivityUserData user_data_; + // A map of global module information, keyed by module path. + std::map<const std::string, ModuleInfoRecord*> modules_; + base::Lock modules_lock_; + // The active global activity tracker. static GlobalActivityTracker* g_tracker_;
diff --git a/base/process/memory_mac.mm b/base/process/memory_mac.mm index 155004dc..4c1b120 100644 --- a/base/process/memory_mac.mm +++ b/base/process/memory_mac.mm
@@ -4,8 +4,25 @@ #include "base/process/memory.h" -#include "base/allocator/allocator_interception_mac.h" +#include <CoreFoundation/CoreFoundation.h> +#import <Foundation/Foundation.h> +#include <errno.h> +#include <mach/mach.h> +#include <mach/mach_vm.h> +#include <malloc/malloc.h> +#import <objc/runtime.h> +#include <stddef.h> + +#include <new> + +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/mac/mac_util.h" +#include "base/mac/mach_logging.h" +#include "base/scoped_clear_errno.h" #include "build/build_config.h" +#include "third_party/apple_apsl/CFBase.h" +#include "third_party/apple_apsl/malloc.h" namespace base { @@ -15,16 +32,521 @@ #endif } +// ------------------------------------------------------------------------ + +namespace { + +bool g_oom_killer_enabled; + +#if !defined(ADDRESS_SANITIZER) + +// Starting with Mac OS X 10.7, the zone allocators set up by the system are +// read-only, to prevent them from being overwritten in an attack. However, +// blindly unprotecting and reprotecting the zone allocators fails with +// GuardMalloc because GuardMalloc sets up its zone allocator using a block of +// memory in its bss. Explicit saving/restoring of the protection is required. +// +// This function takes a pointer to a malloc zone, de-protects it if necessary, +// and returns (in the out parameters) a region of memory (if any) to be +// re-protected when modifications are complete. This approach assumes that +// there is no contention for the protection of this memory. +void DeprotectMallocZone(ChromeMallocZone* default_zone, + mach_vm_address_t* reprotection_start, + mach_vm_size_t* reprotection_length, + vm_prot_t* reprotection_value) { + mach_port_t unused; + *reprotection_start = reinterpret_cast<mach_vm_address_t>(default_zone); + struct vm_region_basic_info_64 info; + mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; + kern_return_t result = + mach_vm_region(mach_task_self(), + reprotection_start, + reprotection_length, + VM_REGION_BASIC_INFO_64, + reinterpret_cast<vm_region_info_t>(&info), + &count, + &unused); + MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_region"; + + // The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but + // balance it with a deallocate in case this ever changes. See 10.9.2 + // xnu-2422.90.20/osfmk/vm/vm_map.c vm_map_region. + mach_port_deallocate(mach_task_self(), unused); + + // Does the region fully enclose the zone pointers? Possibly unwarranted + // simplification used: using the size of a full version 8 malloc zone rather + // than the actual smaller size if the passed-in zone is not version 8. + CHECK(*reprotection_start <= + reinterpret_cast<mach_vm_address_t>(default_zone)); + mach_vm_size_t zone_offset = reinterpret_cast<mach_vm_size_t>(default_zone) - + reinterpret_cast<mach_vm_size_t>(*reprotection_start); + CHECK(zone_offset + sizeof(ChromeMallocZone) <= *reprotection_length); + + if (info.protection & VM_PROT_WRITE) { + // No change needed; the zone is already writable. + *reprotection_start = 0; + *reprotection_length = 0; + *reprotection_value = VM_PROT_NONE; + } else { + *reprotection_value = info.protection; + result = mach_vm_protect(mach_task_self(), + *reprotection_start, + *reprotection_length, + false, + info.protection | VM_PROT_WRITE); + MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect"; + } +} + +// === C malloc/calloc/valloc/realloc/posix_memalign === + +typedef void* (*malloc_type)(struct _malloc_zone_t* zone, + size_t size); +typedef void* (*calloc_type)(struct _malloc_zone_t* zone, + size_t num_items, + size_t size); +typedef void* (*valloc_type)(struct _malloc_zone_t* zone, + size_t size); +typedef void (*free_type)(struct _malloc_zone_t* zone, + void* ptr); +typedef void* (*realloc_type)(struct _malloc_zone_t* zone, + void* ptr, + size_t size); +typedef void* (*memalign_type)(struct _malloc_zone_t* zone, + size_t alignment, + size_t size); + +malloc_type g_old_malloc; +calloc_type g_old_calloc; +valloc_type g_old_valloc; +free_type g_old_free; +realloc_type g_old_realloc; +memalign_type g_old_memalign; + +malloc_type g_old_malloc_purgeable; +calloc_type g_old_calloc_purgeable; +valloc_type g_old_valloc_purgeable; +free_type g_old_free_purgeable; +realloc_type g_old_realloc_purgeable; +memalign_type g_old_memalign_purgeable; + +void* oom_killer_malloc(struct _malloc_zone_t* zone, + size_t size) { + void* result = g_old_malloc(zone, size); + if (!result && size) + TerminateBecauseOutOfMemory(size); + return result; +} + +void* oom_killer_calloc(struct _malloc_zone_t* zone, + size_t num_items, + size_t size) { + void* result = g_old_calloc(zone, num_items, size); + if (!result && num_items && size) + TerminateBecauseOutOfMemory(num_items * size); + return result; +} + +void* oom_killer_valloc(struct _malloc_zone_t* zone, + size_t size) { + void* result = g_old_valloc(zone, size); + if (!result && size) + TerminateBecauseOutOfMemory(size); + return result; +} + +void oom_killer_free(struct _malloc_zone_t* zone, + void* ptr) { + g_old_free(zone, ptr); +} + +void* oom_killer_realloc(struct _malloc_zone_t* zone, + void* ptr, + size_t size) { + void* result = g_old_realloc(zone, ptr, size); + if (!result && size) + TerminateBecauseOutOfMemory(size); + return result; +} + +void* oom_killer_memalign(struct _malloc_zone_t* zone, + size_t alignment, + size_t size) { + void* result = g_old_memalign(zone, alignment, size); + // Only die if posix_memalign would have returned ENOMEM, since there are + // other reasons why NULL might be returned (see + // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ). + if (!result && size && alignment >= sizeof(void*) && + (alignment & (alignment - 1)) == 0) { + TerminateBecauseOutOfMemory(size); + } + return result; +} + +void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone, + size_t size) { + void* result = g_old_malloc_purgeable(zone, size); + if (!result && size) + TerminateBecauseOutOfMemory(size); + return result; +} + +void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone, + size_t num_items, + size_t size) { + void* result = g_old_calloc_purgeable(zone, num_items, size); + if (!result && num_items && size) + TerminateBecauseOutOfMemory(num_items * size); + return result; +} + +void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone, + size_t size) { + void* result = g_old_valloc_purgeable(zone, size); + if (!result && size) + TerminateBecauseOutOfMemory(size); + return result; +} + +void oom_killer_free_purgeable(struct _malloc_zone_t* zone, + void* ptr) { + g_old_free_purgeable(zone, ptr); +} + +void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone, + void* ptr, + size_t size) { + void* result = g_old_realloc_purgeable(zone, ptr, size); + if (!result && size) + TerminateBecauseOutOfMemory(size); + return result; +} + +void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone, + size_t alignment, + size_t size) { + void* result = g_old_memalign_purgeable(zone, alignment, size); + // Only die if posix_memalign would have returned ENOMEM, since there are + // other reasons why NULL might be returned (see + // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ). + if (!result && size && alignment >= sizeof(void*) + && (alignment & (alignment - 1)) == 0) { + TerminateBecauseOutOfMemory(size); + } + return result; +} + +#endif // !defined(ADDRESS_SANITIZER) + +// === C++ operator new === + +void oom_killer_new() { + TerminateBecauseOutOfMemory(0); +} + +#if !defined(ADDRESS_SANITIZER) + +// === Core Foundation CFAllocators === + +bool CanGetContextForCFAllocator() { + return !base::mac::IsOSLaterThan10_12_DontCallThis(); +} + +CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) { + ChromeCFAllocatorLions* our_allocator = + const_cast<ChromeCFAllocatorLions*>( + reinterpret_cast<const ChromeCFAllocatorLions*>(allocator)); + return &our_allocator->_context; +} + +CFAllocatorAllocateCallBack g_old_cfallocator_system_default; +CFAllocatorAllocateCallBack g_old_cfallocator_malloc; +CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone; + +void* oom_killer_cfallocator_system_default(CFIndex alloc_size, + CFOptionFlags hint, + void* info) { + void* result = g_old_cfallocator_system_default(alloc_size, hint, info); + if (!result) + TerminateBecauseOutOfMemory(alloc_size); + return result; +} + +void* oom_killer_cfallocator_malloc(CFIndex alloc_size, + CFOptionFlags hint, + void* info) { + void* result = g_old_cfallocator_malloc(alloc_size, hint, info); + if (!result) + TerminateBecauseOutOfMemory(alloc_size); + return result; +} + +void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size, + CFOptionFlags hint, + void* info) { + void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info); + if (!result) + TerminateBecauseOutOfMemory(alloc_size); + return result; +} + +#endif // !defined(ADDRESS_SANITIZER) + +// === Cocoa NSObject allocation === + +typedef id (*allocWithZone_t)(id, SEL, NSZone*); +allocWithZone_t g_old_allocWithZone; + +id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) +{ + id result = g_old_allocWithZone(self, _cmd, zone); + if (!result) + TerminateBecauseOutOfMemory(0); + return result; +} + +} // namespace + bool UncheckedMalloc(size_t size, void** result) { - return allocator::UncheckedMallocMac(size, result); +#if defined(ADDRESS_SANITIZER) + *result = malloc(size); +#else + if (g_old_malloc) { + *result = g_old_malloc(malloc_default_zone(), size); + } else { + *result = malloc(size); + } +#endif // defined(ADDRESS_SANITIZER) + + return *result != NULL; } bool UncheckedCalloc(size_t num_items, size_t size, void** result) { - return allocator::UncheckedCallocMac(num_items, size, result); +#if defined(ADDRESS_SANITIZER) + *result = calloc(num_items, size); +#else + if (g_old_calloc) { + *result = g_old_calloc(malloc_default_zone(), num_items, size); + } else { + *result = calloc(num_items, size); + } +#endif // defined(ADDRESS_SANITIZER) + + return *result != NULL; +} + +void* UncheckedMalloc(size_t size) { + void* address; + return UncheckedMalloc(size, &address) ? address : NULL; +} + +void* UncheckedCalloc(size_t num_items, size_t size) { + void* address; + return UncheckedCalloc(num_items, size, &address) ? address : NULL; } void EnableTerminationOnOutOfMemory() { - allocator::InterceptAllocationsMac(); + if (g_oom_killer_enabled) + return; + + g_oom_killer_enabled = true; + + // === C malloc/calloc/valloc/realloc/posix_memalign === + + // This approach is not perfect, as requests for amounts of memory larger than + // MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will + // still fail with a NULL rather than dying (see + // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details). + // Unfortunately, it's the best we can do. Also note that this does not affect + // allocations from non-default zones. + +#if !defined(ADDRESS_SANITIZER) + // Don't do anything special on OOM for the malloc zones replaced by + // AddressSanitizer, as modifying or protecting them may not work correctly. + + CHECK(!g_old_malloc && !g_old_calloc && !g_old_valloc && !g_old_realloc && + !g_old_memalign) << "Old allocators unexpectedly non-null"; + + CHECK(!g_old_malloc_purgeable && !g_old_calloc_purgeable && + !g_old_valloc_purgeable && !g_old_realloc_purgeable && + !g_old_memalign_purgeable) << "Old allocators unexpectedly non-null"; + + ChromeMallocZone* default_zone = + reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); + ChromeMallocZone* purgeable_zone = + reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone()); + + mach_vm_address_t default_reprotection_start = 0; + mach_vm_size_t default_reprotection_length = 0; + vm_prot_t default_reprotection_value = VM_PROT_NONE; + DeprotectMallocZone(default_zone, + &default_reprotection_start, + &default_reprotection_length, + &default_reprotection_value); + + mach_vm_address_t purgeable_reprotection_start = 0; + mach_vm_size_t purgeable_reprotection_length = 0; + vm_prot_t purgeable_reprotection_value = VM_PROT_NONE; + if (purgeable_zone) { + DeprotectMallocZone(purgeable_zone, + &purgeable_reprotection_start, + &purgeable_reprotection_length, + &purgeable_reprotection_value); + } + + // Default zone + + g_old_malloc = default_zone->malloc; + g_old_calloc = default_zone->calloc; + g_old_valloc = default_zone->valloc; + g_old_free = default_zone->free; + g_old_realloc = default_zone->realloc; + CHECK(g_old_malloc && g_old_calloc && g_old_valloc && g_old_free && + g_old_realloc) + << "Failed to get system allocation functions."; + + default_zone->malloc = oom_killer_malloc; + default_zone->calloc = oom_killer_calloc; + default_zone->valloc = oom_killer_valloc; + default_zone->free = oom_killer_free; + default_zone->realloc = oom_killer_realloc; + + if (default_zone->version >= 5) { + g_old_memalign = default_zone->memalign; + if (g_old_memalign) + default_zone->memalign = oom_killer_memalign; + } + + // Purgeable zone (if it exists) + + if (purgeable_zone) { + g_old_malloc_purgeable = purgeable_zone->malloc; + g_old_calloc_purgeable = purgeable_zone->calloc; + g_old_valloc_purgeable = purgeable_zone->valloc; + g_old_free_purgeable = purgeable_zone->free; + g_old_realloc_purgeable = purgeable_zone->realloc; + CHECK(g_old_malloc_purgeable && g_old_calloc_purgeable && + g_old_valloc_purgeable && g_old_free_purgeable && + g_old_realloc_purgeable) + << "Failed to get system allocation functions."; + + purgeable_zone->malloc = oom_killer_malloc_purgeable; + purgeable_zone->calloc = oom_killer_calloc_purgeable; + purgeable_zone->valloc = oom_killer_valloc_purgeable; + purgeable_zone->free = oom_killer_free_purgeable; + purgeable_zone->realloc = oom_killer_realloc_purgeable; + + if (purgeable_zone->version >= 5) { + g_old_memalign_purgeable = purgeable_zone->memalign; + if (g_old_memalign_purgeable) + purgeable_zone->memalign = oom_killer_memalign_purgeable; + } + } + + // Restore protection if it was active. + + if (default_reprotection_start) { + kern_return_t result = mach_vm_protect(mach_task_self(), + default_reprotection_start, + default_reprotection_length, + false, + default_reprotection_value); + MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect"; + } + + if (purgeable_reprotection_start) { + kern_return_t result = mach_vm_protect(mach_task_self(), + purgeable_reprotection_start, + purgeable_reprotection_length, + false, + purgeable_reprotection_value); + MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect"; + } +#endif + + // === C malloc_zone_batch_malloc === + + // batch_malloc is omitted because the default malloc zone's implementation + // only supports batch_malloc for "tiny" allocations from the free list. It + // will fail for allocations larger than "tiny", and will only allocate as + // many blocks as it's able to from the free list. These factors mean that it + // can return less than the requested memory even in a non-out-of-memory + // situation. There's no good way to detect whether a batch_malloc failure is + // due to these other factors, or due to genuine memory or address space + // exhaustion. The fact that it only allocates space from the "tiny" free list + // means that it's likely that a failure will not be due to memory exhaustion. + // Similarly, these constraints on batch_malloc mean that callers must always + // be expecting to receive less memory than was requested, even in situations + // where memory pressure is not a concern. Finally, the only public interface + // to batch_malloc is malloc_zone_batch_malloc, which is specific to the + // system's malloc implementation. It's unlikely that anyone's even heard of + // it. + + // === C++ operator new === + + // Yes, operator new does call through to malloc, but this will catch failures + // that our imperfect handling of malloc cannot. + + std::set_new_handler(oom_killer_new); + +#ifndef ADDRESS_SANITIZER + // === Core Foundation CFAllocators === + + // This will not catch allocation done by custom allocators, but will catch + // all allocation done by system-provided ones. + + CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc && + !g_old_cfallocator_malloc_zone) + << "Old allocators unexpectedly non-null"; + + bool cf_allocator_internals_known = CanGetContextForCFAllocator(); + + if (cf_allocator_internals_known) { + CFAllocatorContext* context = + ContextForCFAllocator(kCFAllocatorSystemDefault); + CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault."; + g_old_cfallocator_system_default = context->allocate; + CHECK(g_old_cfallocator_system_default) + << "Failed to get kCFAllocatorSystemDefault allocation function."; + context->allocate = oom_killer_cfallocator_system_default; + + context = ContextForCFAllocator(kCFAllocatorMalloc); + CHECK(context) << "Failed to get context for kCFAllocatorMalloc."; + g_old_cfallocator_malloc = context->allocate; + CHECK(g_old_cfallocator_malloc) + << "Failed to get kCFAllocatorMalloc allocation function."; + context->allocate = oom_killer_cfallocator_malloc; + + context = ContextForCFAllocator(kCFAllocatorMallocZone); + CHECK(context) << "Failed to get context for kCFAllocatorMallocZone."; + g_old_cfallocator_malloc_zone = context->allocate; + CHECK(g_old_cfallocator_malloc_zone) + << "Failed to get kCFAllocatorMallocZone allocation function."; + context->allocate = oom_killer_cfallocator_malloc_zone; + } else { + DLOG(WARNING) << "Internals of CFAllocator not known; out-of-memory " + "failures via CFAllocator will not result in termination. " + "http://crbug.com/45650"; + } +#endif + + // === Cocoa NSObject allocation === + + // Note that both +[NSObject new] and +[NSObject alloc] call through to + // +[NSObject allocWithZone:]. + + CHECK(!g_old_allocWithZone) + << "Old allocator unexpectedly non-null"; + + Class nsobject_class = [NSObject class]; + Method orig_method = class_getClassMethod(nsobject_class, + @selector(allocWithZone:)); + g_old_allocWithZone = reinterpret_cast<allocWithZone_t>( + method_getImplementation(orig_method)); + CHECK(g_old_allocWithZone) + << "Failed to get allocWithZone allocation function."; + method_setImplementation(orig_method, + reinterpret_cast<IMP>(oom_killer_allocWithZone)); } } // namespace base
diff --git a/base/time/time.cc b/base/time/time.cc index 93a6195c..f5cefd4 100644 --- a/base/time/time.cc +++ b/base/time/time.cc
@@ -191,6 +191,10 @@ } double Time::ToJsTime() const { + if (is_null()) { + // Preserve 0 so the invalid result doesn't depend on the platform. + return 0; + } if (is_max()) { // Preserve max without offset to prevent overflow. return std::numeric_limits<double>::infinity();
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc index f25315f..8906c3b 100644 --- a/base/time/time_unittest.cc +++ b/base/time/time_unittest.cc
@@ -159,15 +159,6 @@ EXPECT_EQ(700.0003, t.ToDoubleT()); t = Time::FromDoubleT(800.73); EXPECT_EQ(800730.0, t.ToJsTime()); - - // Correctly convert |- epoch offset| which is valid time in javascript. - Time minusEpoch = Time::FromJsTime(-11644473600000.0); - EXPECT_EQ(-11644473600000, minusEpoch.ToJsTime()); - - // Check conversion of boundary javascript time values. - // See http://www.ecma-international.org/ecma-262/6.0/#sec-timeclip - EXPECT_EQ(-8.46e15, Time::FromJsTime(-8.46e15).ToJsTime()); - EXPECT_EQ(8.46e15, Time::FromJsTime(8.46e15).ToJsTime()); } #if defined(OS_POSIX)
diff --git a/base/trace_event/memory_infra_background_whitelist.cc b/base/trace_event/memory_infra_background_whitelist.cc index ea37739..d6e9f5d16 100644 --- a/base/trace_event/memory_infra_background_whitelist.cc +++ b/base/trace_event/memory_infra_background_whitelist.cc
@@ -88,6 +88,42 @@ "winheap/allocated_objects", "sync/0x?/kernel", "sync/0x?/store", + "sync/0x?/model_type/APP", + "sync/0x?/model_type/APP_LIST", + "sync/0x?/model_type/APP_NOTIFICATION", + "sync/0x?/model_type/APP_SETTING", + "sync/0x?/model_type/ARC_PACKAGE", + "sync/0x?/model_type/ARTICLE", + "sync/0x?/model_type/AUTOFILL", + "sync/0x?/model_type/AUTOFILL_PROFILE", + "sync/0x?/model_type/AUTOFILL_WALLET", + "sync/0x?/model_type/BOOKMARK", + "sync/0x?/model_type/DEVICE_INFO", + "sync/0x?/model_type/DICTIONARY", + "sync/0x?/model_type/EXPERIMENTS", + "sync/0x?/model_type/EXTENSION", + "sync/0x?/model_type/EXTENSION_SETTING", + "sync/0x?/model_type/FAVICON_IMAGE", + "sync/0x?/model_type/FAVICON_TRACKING", + "sync/0x?/model_type/HISTORY_DELETE_DIRECTIVE", + "sync/0x?/model_type/MANAGED_USER", + "sync/0x?/model_type/MANAGED_USER_SETTING", + "sync/0x?/model_type/MANAGED_USER_SHARED_SETTING", + "sync/0x?/model_type/MANAGED_USER_WHITELIST", + "sync/0x?/model_type/NIGORI", + "sync/0x?/model_type/PASSWORD", + "sync/0x?/model_type/PREFERENCE", + "sync/0x?/model_type/PRINTER", + "sync/0x?/model_type/PRIORITY_PREFERENCE", + "sync/0x?/model_type/READING_LIST", + "sync/0x?/model_type/SEARCH_ENGINE", + "sync/0x?/model_type/SESSION", + "sync/0x?/model_type/SYNCED_NOTIFICATION", + "sync/0x?/model_type/SYNCED_NOTIFICATION_APP_INFO", + "sync/0x?/model_type/THEME", + "sync/0x?/model_type/TYPED_URL", + "sync/0x?/model_type/WALLET_METADATA", + "sync/0x?/model_type/WIFI_CREDENTIAL", nullptr // End of list marker. };
diff --git a/build/mac_toolchain.py b/build/mac_toolchain.py index c4de86f9..123e5e0d3 100755 --- a/build/mac_toolchain.py +++ b/build/mac_toolchain.py
@@ -28,8 +28,8 @@ MAC_TOOLCHAIN_SUB_REVISION = 3 MAC_TOOLCHAIN_VERSION = '%s-%s' % (MAC_TOOLCHAIN_VERSION, MAC_TOOLCHAIN_SUB_REVISION) -IOS_TOOLCHAIN_VERSION = '8A218a' -IOS_TOOLCHAIN_SUB_REVISION = 2 +IOS_TOOLCHAIN_VERSION = '8C1002' +IOS_TOOLCHAIN_SUB_REVISION = 1 IOS_TOOLCHAIN_VERSION = '%s-%s' % (IOS_TOOLCHAIN_VERSION, IOS_TOOLCHAIN_SUB_REVISION)
diff --git a/cc/test/ordered_simple_task_runner.cc b/cc/test/ordered_simple_task_runner.cc index 9dc4bbcd..161704f 100644 --- a/cc/test/ordered_simple_task_runner.cc +++ b/cc/test/ordered_simple_task_runner.cc
@@ -137,6 +137,8 @@ } base::TimeTicks OrderedSimpleTaskRunner::NextTaskTime() { + RemoveCancelledTasks(); + if (pending_tasks_.size() <= 0) { return AbsoluteMaxNow(); } @@ -146,6 +148,7 @@ base::TimeDelta OrderedSimpleTaskRunner::DelayToNextTaskTime() { DCHECK(thread_checker_.CalledOnValidThread()); + RemoveCancelledTasks(); if (pending_tasks_.size() <= 0) { return AbsoluteMaxNow() - base::TimeTicks(); @@ -198,6 +201,11 @@ } while (pending_tasks_.size() > 0) { + // Skip canceled tasks. + if (pending_tasks_.begin()->task.IsCancelled()) { + pending_tasks_.erase(pending_tasks_.begin()); + continue; + } // Check if we should continue to run pending tasks. bool condition_success = true; for (std::vector<base::Callback<bool(void)>>::iterator it = @@ -344,4 +352,15 @@ return true; } +void OrderedSimpleTaskRunner::RemoveCancelledTasks() { + std::set<TestOrderablePendingTask>::iterator it = pending_tasks_.begin(); + while (it != pending_tasks_.end()) { + if (it->task.IsCancelled()) { + it = pending_tasks_.erase(it); + } else { + it++; + } + } +} + } // namespace cc
diff --git a/cc/test/ordered_simple_task_runner.h b/cc/test/ordered_simple_task_runner.h index 9620a960..1ba8e95 100644 --- a/cc/test/ordered_simple_task_runner.h +++ b/cc/test/ordered_simple_task_runner.h
@@ -130,6 +130,9 @@ // Advance Now() to the next task to run. base::Callback<bool(void)> AdvanceNow(); + // Removes all tasks whose weak pointer has been revoked. + void RemoveCancelledTasks(); + protected: static bool TaskRunCountBelowCallback(size_t max_tasks, size_t* task_run); bool TaskExistedInitiallyCallback(
diff --git a/cc/trees/layer_tree.cc b/cc/trees/layer_tree.cc index 5f5e551..c545a12 100644 --- a/cc/trees/layer_tree.cc +++ b/cc/trees/layer_tree.cc
@@ -18,27 +18,8 @@ namespace cc { -LayerTree::Inputs::Inputs() - : top_controls_height(0.f), - top_controls_shown_ratio(0.f), - browser_controls_shrink_blink_size(false), - bottom_controls_height(0.f), - device_scale_factor(1.f), - painted_device_scale_factor(1.f), - page_scale_factor(1.f), - min_page_scale_factor(1.f), - max_page_scale_factor(1.f), - background_color(SK_ColorWHITE), - has_transparent_background(false), - have_scroll_event_handlers(false), - event_listener_properties() {} - -LayerTree::Inputs::~Inputs() = default; - LayerTree::LayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host) - : needs_full_tree_sync_(true), - needs_meta_info_recomputation_(true), - in_paint_layer_contents_(false), + : event_listener_properties_(), mutator_host_(mutator_host), layer_tree_host_(layer_tree_host) { DCHECK(mutator_host_); @@ -52,26 +33,26 @@ // We must clear any pointers into the layer tree prior to destroying it. RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr); - if (inputs_.root_layer) { - inputs_.root_layer->SetLayerTreeHost(nullptr); + if (root_layer_) { + root_layer_->SetLayerTreeHost(nullptr); // The root layer must be destroyed before the layer tree. We've made a // contract with our animation controllers that the animation_host will // outlive them, and we must make good. - inputs_.root_layer = nullptr; + root_layer_ = nullptr; } } void LayerTree::SetRootLayer(scoped_refptr<Layer> root_layer) { - if (inputs_.root_layer.get() == root_layer.get()) + if (root_layer_.get() == root_layer.get()) return; - if (inputs_.root_layer.get()) - inputs_.root_layer->SetLayerTreeHost(nullptr); - inputs_.root_layer = root_layer; - if (inputs_.root_layer.get()) { - DCHECK(!inputs_.root_layer->parent()); - inputs_.root_layer->SetLayerTreeHost(layer_tree_host_); + if (root_layer_.get()) + root_layer_->SetLayerTreeHost(nullptr); + root_layer_ = root_layer; + if (root_layer_.get()) { + DCHECK(!root_layer_->parent()); + root_layer_->SetLayerTreeHost(layer_tree_host_); } if (hud_layer_.get()) @@ -91,85 +72,85 @@ scoped_refptr<Layer> outer_viewport_scroll_layer) { DCHECK(!inner_viewport_scroll_layer || inner_viewport_scroll_layer != outer_viewport_scroll_layer); - inputs_.overscroll_elasticity_layer = overscroll_elasticity_layer; - inputs_.page_scale_layer = page_scale_layer; - inputs_.inner_viewport_scroll_layer = inner_viewport_scroll_layer; - inputs_.outer_viewport_scroll_layer = outer_viewport_scroll_layer; + overscroll_elasticity_layer_ = overscroll_elasticity_layer; + page_scale_layer_ = page_scale_layer; + inner_viewport_scroll_layer_ = inner_viewport_scroll_layer; + outer_viewport_scroll_layer_ = outer_viewport_scroll_layer; } void LayerTree::RegisterSelection(const LayerSelection& selection) { - if (inputs_.selection == selection) + if (selection_ == selection) return; - inputs_.selection = selection; + selection_ = selection; SetNeedsCommit(); } void LayerTree::SetHaveScrollEventHandlers(bool have_event_handlers) { - if (inputs_.have_scroll_event_handlers == have_event_handlers) + if (have_scroll_event_handlers_ == have_event_handlers) return; - inputs_.have_scroll_event_handlers = have_event_handlers; + have_scroll_event_handlers_ = have_event_handlers; SetNeedsCommit(); } void LayerTree::SetEventListenerProperties(EventListenerClass event_class, EventListenerProperties properties) { const size_t index = static_cast<size_t>(event_class); - if (inputs_.event_listener_properties[index] == properties) + if (event_listener_properties_[index] == properties) return; - inputs_.event_listener_properties[index] = properties; + event_listener_properties_[index] = properties; SetNeedsCommit(); } void LayerTree::SetViewportSize(const gfx::Size& device_viewport_size) { - if (inputs_.device_viewport_size == device_viewport_size) + if (device_viewport_size_ == device_viewport_size) return; - inputs_.device_viewport_size = device_viewport_size; + device_viewport_size_ = device_viewport_size; SetPropertyTreesNeedRebuild(); SetNeedsCommit(); } void LayerTree::SetBrowserControlsHeight(float height, bool shrink) { - if (inputs_.top_controls_height == height && - inputs_.browser_controls_shrink_blink_size == shrink) + if (top_controls_height_ == height && + browser_controls_shrink_blink_size_ == shrink) return; - inputs_.top_controls_height = height; - inputs_.browser_controls_shrink_blink_size = shrink; + top_controls_height_ = height; + browser_controls_shrink_blink_size_ = shrink; SetNeedsCommit(); } void LayerTree::SetBrowserControlsShownRatio(float ratio) { - if (inputs_.top_controls_shown_ratio == ratio) + if (top_controls_shown_ratio_ == ratio) return; - inputs_.top_controls_shown_ratio = ratio; + top_controls_shown_ratio_ = ratio; SetNeedsCommit(); } void LayerTree::SetBottomControlsHeight(float height) { - if (inputs_.bottom_controls_height == height) + if (bottom_controls_height_ == height) return; - inputs_.bottom_controls_height = height; + bottom_controls_height_ = height; SetNeedsCommit(); } void LayerTree::SetPageScaleFactorAndLimits(float page_scale_factor, float min_page_scale_factor, float max_page_scale_factor) { - if (inputs_.page_scale_factor == page_scale_factor && - inputs_.min_page_scale_factor == min_page_scale_factor && - inputs_.max_page_scale_factor == max_page_scale_factor) + if (page_scale_factor_ == page_scale_factor && + min_page_scale_factor_ == min_page_scale_factor && + max_page_scale_factor_ == max_page_scale_factor) return; - inputs_.page_scale_factor = page_scale_factor; - inputs_.min_page_scale_factor = min_page_scale_factor; - inputs_.max_page_scale_factor = max_page_scale_factor; + page_scale_factor_ = page_scale_factor; + min_page_scale_factor_ = min_page_scale_factor; + max_page_scale_factor_ = max_page_scale_factor; SetPropertyTreesNeedRebuild(); SetNeedsCommit(); } @@ -178,37 +159,37 @@ bool use_anchor, float scale, base::TimeDelta duration) { - inputs_.pending_page_scale_animation.reset(new PendingPageScaleAnimation( + pending_page_scale_animation_.reset(new PendingPageScaleAnimation( target_offset, use_anchor, scale, duration)); SetNeedsCommit(); } bool LayerTree::HasPendingPageScaleAnimation() const { - return !!inputs_.pending_page_scale_animation.get(); + return !!pending_page_scale_animation_.get(); } void LayerTree::SetDeviceScaleFactor(float device_scale_factor) { - if (inputs_.device_scale_factor == device_scale_factor) + if (device_scale_factor_ == device_scale_factor) return; - inputs_.device_scale_factor = device_scale_factor; + device_scale_factor_ = device_scale_factor; property_trees_.needs_rebuild = true; SetNeedsCommit(); } void LayerTree::SetPaintedDeviceScaleFactor(float painted_device_scale_factor) { - if (inputs_.painted_device_scale_factor == painted_device_scale_factor) + if (painted_device_scale_factor_ == painted_device_scale_factor) return; - inputs_.painted_device_scale_factor = painted_device_scale_factor; + painted_device_scale_factor_ = painted_device_scale_factor; SetNeedsCommit(); } void LayerTree::SetDeviceColorSpace(const gfx::ColorSpace& device_color_space) { - if (inputs_.device_color_space == device_color_space) + if (device_color_space_ == device_color_space) return; - inputs_.device_color_space = device_color_space; + device_color_space_ = device_color_space; LayerTreeHostCommon::CallFunctionForEveryLayer( this, [](Layer* layer) { layer->SetNeedsDisplay(); }); } @@ -277,7 +258,7 @@ void LayerTree::SetPageScaleFromImplSide(float page_scale) { DCHECK(layer_tree_host_->CommitRequested()); - inputs_.page_scale_factor = page_scale; + page_scale_factor_ = page_scale; SetPropertyTreesNeedRebuild(); } @@ -293,8 +274,8 @@ hud_layer_ = HeadsUpDisplayLayer::Create(); } - if (inputs_.root_layer.get() && !hud_layer_->parent()) - inputs_.root_layer->AddChild(hud_layer_); + if (root_layer_.get() && !hud_layer_->parent()) + root_layer_->AddChild(hud_layer_); } else if (hud_layer_.get()) { hud_layer_->RemoveFromParent(); hud_layer_ = nullptr; @@ -333,9 +314,9 @@ tree_impl->set_hud_layer(nullptr); } - tree_impl->set_background_color(inputs_.background_color); - tree_impl->set_has_transparent_background(inputs_.has_transparent_background); - tree_impl->set_have_scroll_event_handlers(inputs_.have_scroll_event_handlers); + tree_impl->set_background_color(background_color_); + tree_impl->set_has_transparent_background(has_transparent_background_); + tree_impl->set_have_scroll_event_handlers(have_scroll_event_handlers_); tree_impl->set_event_listener_properties( EventListenerClass::kTouchStartOrMove, event_listener_properties(EventListenerClass::kTouchStartOrMove)); @@ -346,30 +327,26 @@ EventListenerClass::kTouchEndOrCancel, event_listener_properties(EventListenerClass::kTouchEndOrCancel)); - if (inputs_.page_scale_layer && inputs_.inner_viewport_scroll_layer) { + if (page_scale_layer_ && inner_viewport_scroll_layer_) { tree_impl->SetViewportLayersFromIds( - inputs_.overscroll_elasticity_layer - ? inputs_.overscroll_elasticity_layer->id() - : Layer::INVALID_ID, - inputs_.page_scale_layer->id(), - inputs_.inner_viewport_scroll_layer->id(), - inputs_.outer_viewport_scroll_layer - ? inputs_.outer_viewport_scroll_layer->id() - : Layer::INVALID_ID); - DCHECK(inputs_.inner_viewport_scroll_layer - ->IsContainerForFixedPositionLayers()); + overscroll_elasticity_layer_ ? overscroll_elasticity_layer_->id() + : Layer::INVALID_ID, + page_scale_layer_->id(), inner_viewport_scroll_layer_->id(), + outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id() + : Layer::INVALID_ID); + DCHECK(inner_viewport_scroll_layer_->IsContainerForFixedPositionLayers()); } else { tree_impl->ClearViewportLayers(); } - tree_impl->RegisterSelection(inputs_.selection); + tree_impl->RegisterSelection(selection_); bool property_trees_changed_on_active_tree = tree_impl->IsActiveTree() && tree_impl->property_trees()->changed; // Property trees may store damage status. We preserve the sync tree damage // status by pushing the damage status from sync tree property trees to main // thread property trees or by moving it onto the layers. - if (inputs_.root_layer && property_trees_changed_on_active_tree) { + if (root_layer_ && property_trees_changed_on_active_tree) { if (property_trees_.sequence_number == tree_impl->property_trees()->sequence_number) tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_); @@ -379,28 +356,25 @@ // Setting property trees must happen before pushing the page scale. tree_impl->SetPropertyTrees(&property_trees_); - tree_impl->PushPageScaleFromMainThread(inputs_.page_scale_factor, - inputs_.min_page_scale_factor, - inputs_.max_page_scale_factor); + tree_impl->PushPageScaleFromMainThread( + page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_); tree_impl->set_browser_controls_shrink_blink_size( - inputs_.browser_controls_shrink_blink_size); - tree_impl->set_top_controls_height(inputs_.top_controls_height); - tree_impl->set_bottom_controls_height(inputs_.bottom_controls_height); - tree_impl->PushBrowserControlsFromMainThread( - inputs_.top_controls_shown_ratio); + browser_controls_shrink_blink_size_); + tree_impl->set_top_controls_height(top_controls_height_); + tree_impl->set_bottom_controls_height(bottom_controls_height_); + tree_impl->PushBrowserControlsFromMainThread(top_controls_shown_ratio_); tree_impl->elastic_overscroll()->PushFromMainThread(elastic_overscroll_); if (tree_impl->IsActiveTree()) tree_impl->elastic_overscroll()->PushPendingToActive(); - tree_impl->set_painted_device_scale_factor( - inputs_.painted_device_scale_factor); + tree_impl->set_painted_device_scale_factor(painted_device_scale_factor_); - tree_impl->SetDeviceColorSpace(inputs_.device_color_space); + tree_impl->SetDeviceColorSpace(device_color_space_); - if (inputs_.pending_page_scale_animation) { + if (pending_page_scale_animation_) { tree_impl->SetPendingPageScaleAnimation( - std::move(inputs_.pending_page_scale_animation)); + std::move(pending_page_scale_animation_)); } DCHECK(!tree_impl->ViewportSizeInvalid()); @@ -514,7 +488,7 @@ } LayerListIterator<Layer> LayerTree::begin() const { - return LayerListIterator<Layer>(inputs_.root_layer.get()); + return LayerListIterator<Layer>(root_layer_.get()); } LayerListIterator<Layer> LayerTree::end() const { @@ -522,7 +496,7 @@ } LayerListReverseIterator<Layer> LayerTree::rbegin() { - return LayerListReverseIterator<Layer>(inputs_.root_layer.get()); + return LayerListReverseIterator<Layer>(root_layer_.get()); } LayerListReverseIterator<Layer> LayerTree::rend() {
diff --git a/cc/trees/layer_tree.h b/cc/trees/layer_tree.h index 5ac3f69..7f874120 100644 --- a/cc/trees/layer_tree.h +++ b/cc/trees/layer_tree.h
@@ -44,8 +44,8 @@ virtual ~LayerTree(); void SetRootLayer(scoped_refptr<Layer> root_layer); - Layer* root_layer() { return inputs_.root_layer.get(); } - const Layer* root_layer() const { return inputs_.root_layer.get(); } + Layer* root_layer() { return root_layer_.get(); } + const Layer* root_layer() const { return root_layer_.get(); } void RegisterViewportLayers(scoped_refptr<Layer> overscroll_elasticity_layer, scoped_refptr<Layer> page_scale_layer, @@ -53,35 +53,33 @@ scoped_refptr<Layer> outer_viewport_scroll_layer); Layer* overscroll_elasticity_layer() const { - return inputs_.overscroll_elasticity_layer.get(); + return overscroll_elasticity_layer_.get(); } - Layer* page_scale_layer() const { return inputs_.page_scale_layer.get(); } + Layer* page_scale_layer() const { return page_scale_layer_.get(); } Layer* inner_viewport_scroll_layer() const { - return inputs_.inner_viewport_scroll_layer.get(); + return inner_viewport_scroll_layer_.get(); } Layer* outer_viewport_scroll_layer() const { - return inputs_.outer_viewport_scroll_layer.get(); + return outer_viewport_scroll_layer_.get(); } void RegisterSelection(const LayerSelection& selection); - const LayerSelection& selection() const { return inputs_.selection; } + const LayerSelection& selection() const { return selection_; } void SetHaveScrollEventHandlers(bool have_event_handlers); bool have_scroll_event_handlers() const { - return inputs_.have_scroll_event_handlers; + return have_scroll_event_handlers_; } void SetEventListenerProperties(EventListenerClass event_class, EventListenerProperties event_properties); EventListenerProperties event_listener_properties( EventListenerClass event_class) const { - return inputs_.event_listener_properties[static_cast<size_t>(event_class)]; + return event_listener_properties_[static_cast<size_t>(event_class)]; } void SetViewportSize(const gfx::Size& device_viewport_size); - gfx::Size device_viewport_size() const { - return inputs_.device_viewport_size; - } + gfx::Size device_viewport_size() const { return device_viewport_size_; } void SetBrowserControlsHeight(float height, bool shrink); void SetBrowserControlsShownRatio(float ratio); @@ -90,18 +88,18 @@ void SetPageScaleFactorAndLimits(float page_scale_factor, float min_page_scale_factor, float max_page_scale_factor); - float page_scale_factor() const { return inputs_.page_scale_factor; } - float min_page_scale_factor() const { return inputs_.min_page_scale_factor; } - float max_page_scale_factor() const { return inputs_.max_page_scale_factor; } + float page_scale_factor() const { return page_scale_factor_; } + float min_page_scale_factor() const { return min_page_scale_factor_; } + float max_page_scale_factor() const { return max_page_scale_factor_; } - void set_background_color(SkColor color) { inputs_.background_color = color; } - SkColor background_color() const { return inputs_.background_color; } + void set_background_color(SkColor color) { background_color_ = color; } + SkColor background_color() const { return background_color_; } void set_has_transparent_background(bool transparent) { - inputs_.has_transparent_background = transparent; + has_transparent_background_ = transparent; } bool has_transparent_background() const { - return inputs_.has_transparent_background; + return has_transparent_background_; } void StartPageScaleAnimation(const gfx::Vector2d& target_offset, @@ -111,16 +109,16 @@ bool HasPendingPageScaleAnimation() const; void SetDeviceScaleFactor(float device_scale_factor); - float device_scale_factor() const { return inputs_.device_scale_factor; } + float device_scale_factor() const { return device_scale_factor_; } void SetPaintedDeviceScaleFactor(float painted_device_scale_factor); float painted_device_scale_factor() const { - return inputs_.painted_device_scale_factor; + return painted_device_scale_factor_; } void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space); const gfx::ColorSpace& device_color_space() const { - return inputs_.device_color_space; + return device_color_space_; } // Used externally by blink for setting the PropertyTrees when @@ -218,51 +216,43 @@ gfx::ScrollOffset GetScrollOffsetForAnimation( ElementId element_id) const override; - // Encapsulates the data, callbacks, interfaces received from the embedder. - struct Inputs { - Inputs(); - ~Inputs(); + scoped_refptr<Layer> root_layer_; - scoped_refptr<Layer> root_layer; + scoped_refptr<Layer> overscroll_elasticity_layer_; + scoped_refptr<Layer> page_scale_layer_; + scoped_refptr<Layer> inner_viewport_scroll_layer_; + scoped_refptr<Layer> outer_viewport_scroll_layer_; - scoped_refptr<Layer> overscroll_elasticity_layer; - scoped_refptr<Layer> page_scale_layer; - scoped_refptr<Layer> inner_viewport_scroll_layer; - scoped_refptr<Layer> outer_viewport_scroll_layer; + float top_controls_height_ = 0.f; + float top_controls_shown_ratio_ = 0.f; + bool browser_controls_shrink_blink_size_ = false; - float top_controls_height; - float top_controls_shown_ratio; - bool browser_controls_shrink_blink_size; + float bottom_controls_height_ = 0.f; - float bottom_controls_height; + float device_scale_factor_ = 1.f; + float painted_device_scale_factor_ = 1.f; + float page_scale_factor_ = 1.f; + float min_page_scale_factor_ = 1.f; + float max_page_scale_factor_ = 1.f; + gfx::ColorSpace device_color_space_; - float device_scale_factor; - float painted_device_scale_factor; - float page_scale_factor; - float min_page_scale_factor; - float max_page_scale_factor; - gfx::ColorSpace device_color_space; + SkColor background_color_ = SK_ColorWHITE; + bool has_transparent_background_ = false; - SkColor background_color; - bool has_transparent_background; + LayerSelection selection_; - LayerSelection selection; + gfx::Size device_viewport_size_; - gfx::Size device_viewport_size; + bool have_scroll_event_handlers_ = false; + EventListenerProperties event_listener_properties_[static_cast<size_t>( + EventListenerClass::kNumClasses)]; - bool have_scroll_event_handlers; - EventListenerProperties event_listener_properties[static_cast<size_t>( - EventListenerClass::kNumClasses)]; - - std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation; - }; - - Inputs inputs_; + std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_; PropertyTrees property_trees_; - bool needs_full_tree_sync_; - bool needs_meta_info_recomputation_; + bool needs_full_tree_sync_ = true; + bool needs_meta_info_recomputation_ = true; gfx::Vector2dF elastic_overscroll_; @@ -277,7 +267,7 @@ using ElementLayersMap = std::unordered_map<ElementId, Layer*, ElementIdHash>; ElementLayersMap element_layers_map_; - bool in_paint_layer_contents_; + bool in_paint_layer_contents_ = false; MutatorHost* mutator_host_; LayerTreeHost* layer_tree_host_;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java index 4d8dee5..850fec8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
@@ -6,7 +6,6 @@ import org.chromium.base.Callback; import org.chromium.base.Log; -import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ntp.NewTabPage.DestructionObserver; import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.ntp.snippets.CategoryInt; @@ -152,7 +151,7 @@ int itemCount = mSuggestions.size(); if (itemCount > n) { mSuggestions.subList(n, itemCount).clear(); - notifyItemRangeRemoved(n, itemCount - 1); + notifyItemRangeRemoved(n, itemCount - n); } } @@ -474,21 +473,11 @@ return mHeader.getHeaderText(); } - /** - * @return The progress indicator. - */ - @VisibleForTesting ProgressItem getProgressItemForTesting() { return mProgressIndicator; } - @VisibleForTesting - ActionItem getActionItem() { + ActionItem getActionItemForTesting() { return mMoreButton; } - - @VisibleForTesting - StatusItem getStatusItem() { - return mStatus; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java index ae07fda..8d1de1f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
@@ -19,6 +19,11 @@ void initializeNative(Tab currentTab, VrShellDelegate delegate, boolean forWebVR); /** + * Swaps to the designated tab. + */ + void swapTab(Tab currentTab); + + /** * Pauses VrShell. */ void pause();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 70f379b..835a3c63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -30,6 +30,8 @@ import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; +import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -74,6 +76,7 @@ private final ChromeTabbedActivity mActivity; private TabObserver mTabObserver; + private TabModelSelectorObserver mTabModelSelectorObserver; private Intent mEnterVRIntent; @VrSupportLevel @@ -111,6 +114,7 @@ mVrSupportLevel = VR_NOT_AVAILABLE; mEnterVRIntent = null; mTabObserver = null; + mTabModelSelectorObserver = null; return; } @@ -147,6 +151,14 @@ } }; } + if (mTabModelSelectorObserver == null) { + mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() { + @Override + public void onChange() { + swapToForegroundTab(); + } + }; + } mVrSupportLevel = mVrDaydreamApi.isDaydreamReadyDevice() ? VR_DAYDREAM : VR_CARDBOARD; } @@ -250,6 +262,7 @@ mVrShell.resume(); mTab.updateFullscreenEnabledState(); setEnterVRResult(true, requestedWebVR); + mActivity.getTabModelSelector().addObserver(mTabModelSelectorObserver); } private void setEnterVRResult(boolean success, boolean requestedWebVR) { @@ -260,6 +273,22 @@ mRequestedWebVR = false; } + private void swapToForegroundTab() { + Tab tab = mActivity.getActivityTab(); + if (tab == mTab) return; + if (!canEnterVR(tab)) { + forceExitVr(); + return; + } + mTab.removeObserver(mTabObserver); + mTab.updateFullscreenEnabledState(); + + mVrShell.swapTab(tab); + mTab = tab; + mTab.addObserver(mTabObserver); + mTab.updateFullscreenEnabledState(); + } + private boolean canEnterVR(Tab tab) { if (!LibraryLoader.isInitialized()) { return false; @@ -511,6 +540,7 @@ mVrClassesWrapper.setVrModeEnabled(false); mLastVRExit = SystemClock.uptimeMillis(); } + mActivity.getTabModelSelector().removeObserver(mTabModelSelectorObserver); mActivity.setRequestedOrientation(mRestoreOrientation); mVrShell.pause(); removeVrViews();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index fd53a659..4c73c02f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -65,6 +65,7 @@ private final CompositorViewHolder mCompositorViewHolder; private final VirtualDisplayAndroid mContentVirtualDisplay; private final VirtualDisplayAndroid mUiVirtualDisplay; + private final TabRedirectHandler mTabRedirectHandler; private long mNativeVrShell; @@ -87,6 +88,9 @@ private TabRedirectHandler mNonVrTabRedirectHandler; private TabModelSelector mTabModelSelector; + private float mLastContentWidth; + private float mLastContentHeight; + private float mLastContentDpr; public VrShellImpl(Activity activity, CompositorViewHolder compositorViewHolder) { super(activity); @@ -123,6 +127,13 @@ mContentVirtualDisplay.setTo(primaryDisplay); mUiVirtualDisplay = VirtualDisplayAndroid.createVirtualDisplay(); mUiVirtualDisplay.setTo(primaryDisplay); + + mTabRedirectHandler = new TabRedirectHandler(mActivity) { + @Override + public boolean shouldStayInChrome(boolean hasExternalProtocol) { + return true; + } + }; } @Override @@ -132,15 +143,6 @@ mContentCVC = mTab.getContentViewCore(); mContentVrWindowAndroid = new VrWindowAndroid(mActivity, mContentVirtualDisplay); - // Make sure we are not redirecting to another app, i.e. out of VR mode. - mNonVrTabRedirectHandler = mTab.getTabRedirectHandler(); - mTab.setTabRedirectHandler(new TabRedirectHandler(mActivity) { - @Override - public boolean shouldStayInChrome(boolean hasExternalProtocol) { - return true; - } - }); - mUiVrWindowAndroid = new VrWindowAndroid(mActivity, mUiVirtualDisplay); mUiContents = WebContentsFactory.createWebContents(true, false); mUiCVC = new ContentViewCore(mActivity, ChromeVersionInfo.getProductVersion()); @@ -187,9 +189,35 @@ mUiCVC.setTopControlsHeight(0, false); mUiVrWindowAndroid.onVisibilityChanged(true); + initializeTabForVR(); + } + + private void initializeTabForVR() { mOriginalWindowAndroid = mContentCVC.getWindowAndroid(); mTab.updateWindowAndroid(mContentVrWindowAndroid); mContentCVC.onAttachedToWindow(); + + // Make sure we are not redirecting to another app, i.e. out of VR mode. + mNonVrTabRedirectHandler = mTab.getTabRedirectHandler(); + mTab.setTabRedirectHandler(mTabRedirectHandler); + } + + private void restoreTabFromVR() { + mTab.setTabRedirectHandler(mNonVrTabRedirectHandler); + mTab.updateWindowAndroid(mOriginalWindowAndroid); + mOriginalWindowAndroid = null; + mNonVrTabRedirectHandler = null; + } + + @Override + public void swapTab(final Tab newTab) { + restoreTabFromVR(); + mTab = newTab; + mContentCVC = mTab.getContentViewCore(); + initializeTabForVR(); + + nativeSwapContents(mNativeVrShell, mContentCVC.getWebContents()); + setContentCssSize(mLastContentWidth, mLastContentHeight, mLastContentDpr); } @CalledByNative @@ -212,6 +240,9 @@ @CalledByNative public void setContentCssSize(float width, float height, float dpr) { ThreadUtils.assertOnUiThread(); + mLastContentWidth = width; + mLastContentHeight = height; + mLastContentDpr = dpr; int surfaceWidth = (int) Math.ceil(width * dpr); int surfaceHeight = (int) Math.ceil(height * dpr); @@ -270,15 +301,12 @@ nativeDestroy(mNativeVrShell); mNativeVrShell = 0; } - mCompositorViewHolder.onExitVR(mTabModelSelector); - mTab.setTabRedirectHandler(mNonVrTabRedirectHandler); - mTab.updateWindowAndroid(mOriginalWindowAndroid); - mContentCVC.onSizeChanged(mContentCVC.getContainerView().getWidth(), - mContentCVC.getContainerView().getHeight(), 0, 0); + restoreTabFromVR(); mUiContents.destroy(); mContentVirtualDisplay.destroy(); mUiVirtualDisplay.destroy(); super.shutdown(); + mCompositorViewHolder.onExitVR(mTabModelSelector); } @Override @@ -333,6 +361,7 @@ long nativeContentWindowAndroid, WebContents uiWebContents, long nativeUiWindowAndroid, boolean forWebVR, VrShellDelegate delegate, long gvrApi, boolean reprojectedRendering); private native void nativeSetSurface(long nativeVrShell, Surface surface); + private native void nativeSwapContents(long nativeVrShell, WebContents webContents); private native void nativeLoadUIContent(long nativeVrShell); private native void nativeDestroy(long nativeVrShell); private native void nativeOnTriggerEvent(long nativeVrShell);
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 38f2ca1..6d2105e 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1396,6 +1396,7 @@ "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppCanMakePaymentQueryTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppTest.java", + "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java", "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRemoveBillingAddressTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java new file mode 100644 index 0000000..a158a26 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java
@@ -0,0 +1,80 @@ +// 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. + +package org.chromium.chrome.browser.payments; + +import android.support.test.filters.MediumTest; + +import org.chromium.base.test.util.Feature; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +/** + * A payment integration test for a merchant that requests payment via Bob Pay when performing the + * single payment app UI skip optimization. + */ +public class PaymentRequestPaymentAppUiSkipTest extends PaymentRequestTestBase { + public PaymentRequestPaymentAppUiSkipTest() { + super("payment_request_bobpay_ui_skip_test.html"); + } + + @Override + public void onMainActivityStarted() + throws InterruptedException, ExecutionException, TimeoutException {} + + /** + * If Bob Pay is supported and installed, user should be able to pay with it. Here Bob Pay + * responds to Chrome immediately. + */ + @MediumTest + @Feature({"Payments"}) + public void testPayViaFastBobPay() + throws InterruptedException, ExecutionException, TimeoutException { + installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); + openPageAndClickBuyAndWait(mDismissed); + expectResultContains(new String[] {"https://bobpay.com", "\"transaction\"", "1337"}); + } + + /** + * If Bob Pay is supported and installed, user should be able to pay with it. Here Bob Pay + * responds to Chrome after a slight delay. + */ + @MediumTest + @Feature({"Payments"}) + public void testPayViaSlowBobPay() + throws InterruptedException, ExecutionException, TimeoutException { + installPaymentApp(HAVE_INSTRUMENTS, DELAYED_RESPONSE); + openPageAndClickBuyAndWait(mDismissed); + expectResultContains(new String[] {"https://bobpay.com", "\"transaction\"", "1337"}); + } + + /** + * Test payment with a Bob Pay that is created with a delay, but responds immediately + * to getInstruments. + */ + @MediumTest + @Feature({"Payments"}) + public void testPayViaDelayedFastBobPay() + throws InterruptedException, ExecutionException, TimeoutException { + installPaymentApp( + "https://bobpay.com", HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE, DELAYED_CREATION); + openPageAndClickBuyAndWait(mDismissed); + expectResultContains(new String[] {"https://bobpay.com", "\"transaction\"", "1337"}); + } + + /** + * Test payment with a Bob Pay that is created with a delay, and responds slowly to + * getInstruments. + */ + @MediumTest + @Feature({"Payments"}) + public void testPayViaDelayedSlowBobPay() + throws InterruptedException, ExecutionException, TimeoutException { + installPaymentApp( + "https://bobpay.com", HAVE_INSTRUMENTS, DELAYED_RESPONSE, DELAYED_CREATION); + openPageAndClickBuyAndWait(mDismissed); + expectResultContains(new String[] {"https://bobpay.com", "\"transaction\"", "1337"}); + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java index 4d27499..e8d0cad 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java
@@ -225,11 +225,11 @@ bindViewHolders(sectionList); assertThat(sectionList.getSectionForTesting(KnownCategories.ARTICLES) - .getActionItem() + .getActionItemForTesting() .getPerSectionRank(), equalTo(0)); assertThat(sectionList.getSectionForTesting(KnownCategories.DOWNLOADS) - .getActionItem() + .getActionItemForTesting() .getPerSectionRank(), equalTo(3)); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java index 678dd08..4450d7f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
@@ -94,7 +94,7 @@ SuggestionsSection section = createSectionWithReloadAction(true); section.setStatus(CategoryStatus.AVAILABLE); - assertNotNull(section.getActionItem()); + assertNotNull(section.getActionItemForTesting()); // Without snippets. assertEquals(ItemViewType.HEADER, section.getItemViewType(0)); @@ -120,7 +120,7 @@ SuggestionsSection section = createSectionWithReloadAction(true); section.setStatus(CategoryStatus.AVAILABLE); - assertNotNull(section.getActionItem()); + assertNotNull(section.getActionItemForTesting()); // Without snippets. assertEquals(ItemViewType.HEADER, section.getItemViewType(0)); @@ -315,13 +315,13 @@ .build()); SuggestionsSection section = createSection(info); - assertTrue(section.getActionItem().isVisible()); + assertTrue(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_VIEW_ALL); section.setSuggestions( createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); - assertTrue(section.getActionItem().isVisible()); + assertTrue(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_VIEW_ALL); } @@ -340,13 +340,13 @@ .build()); SuggestionsSection section = createSection(info); - assertTrue(section.getActionItem().isVisible()); + assertTrue(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_RELOAD); section.setSuggestions( createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); - assertTrue(section.getActionItem().isVisible()); + assertTrue(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_FETCH_MORE); } @@ -360,13 +360,13 @@ new CategoryInfoBuilder(TEST_CATEGORY_ID).withReloadAction().showIfEmpty().build()); SuggestionsSection section = createSection(info); - assertTrue(section.getActionItem().isVisible()); + assertTrue(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_RELOAD); section.setSuggestions( createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); - assertFalse(section.getActionItem().isVisible()); + assertFalse(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_NONE); } @@ -380,13 +380,13 @@ new CategoryInfoBuilder(TEST_CATEGORY_ID).withMoreAction().showIfEmpty().build()); SuggestionsSection section = createSection(info); - assertFalse(section.getActionItem().isVisible()); + assertFalse(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_NONE); section.setSuggestions( createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); - assertTrue(section.getActionItem().isVisible()); + assertTrue(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_FETCH_MORE); } @@ -400,13 +400,13 @@ spy(new CategoryInfoBuilder(TEST_CATEGORY_ID).showIfEmpty().build()); SuggestionsSection section = createSection(info); - assertFalse(section.getActionItem().isVisible()); + assertFalse(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_NONE); section.setSuggestions( createDummySuggestions(3), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); - assertFalse(section.getActionItem().isVisible()); + assertFalse(section.getActionItemForTesting().isVisible()); verifyAction(section, ActionItem.ACTION_NONE); } @@ -443,6 +443,8 @@ section.setSuggestions(createDummySuggestions(3, TEST_CATEGORY_ID), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); + verify(mParent).onItemRangeRemoved(section, 1, 4); + verify(mParent).onItemRangeInserted(section, 1, 3); assertEquals(3, section.getSuggestionsCount()); } @@ -463,6 +465,8 @@ section.setSuggestions(createDummySuggestions(3, TEST_CATEGORY_ID), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); + verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(), anyInt()); + verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt(), anyInt()); assertEquals(4, section.getSuggestionsCount()); } @@ -487,10 +491,14 @@ // Copy the list when passing to the section - it may alter it but we later need it. section.setSuggestions(new ArrayList<>(newSnippets), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); + verify(mParent).onItemRangeRemoved(section, 2, 3); + verify(mParent).onItemRangeInserted(section, 2, 2); assertEquals(3, section.getSuggestionsCount()); assertEquals(snippets.get(0), section.getSuggestionAt(1)); assertNotEquals(snippets.get(1), section.getSuggestionAt(2)); assertEquals(newSnippets.get(0), section.getSuggestionAt(2)); + assertNotEquals(snippets.get(2), section.getSuggestionAt(3)); + assertEquals(newSnippets.get(1), section.getSuggestionAt(3)); } /** @@ -515,6 +523,8 @@ // Copy the list when passing to the section - it may alter it but we later need it. section.setSuggestions(new ArrayList<>(newSnippets), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); + verify(mParent).onItemRangeRemoved(section, 3, 2); + verify(mParent).onItemRangeInserted(section, 3, 1); assertEquals(3, section.getSuggestionsCount()); assertEquals(snippets.get(0), section.getSuggestionAt(1)); assertEquals(snippets.get(1), section.getSuggestionAt(2)); @@ -543,6 +553,8 @@ CategoryStatus.AVAILABLE, /* replaceExisting = */ true); // Even though the new list has just one suggestion, we need to keep the two seen ones // around. + verify(mParent).onItemRangeRemoved(section, 3, 2); + verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt(), anyInt()); assertEquals(2, section.getSuggestionsCount()); assertEquals(snippets.get(0), section.getSuggestionAt(1)); assertEquals(snippets.get(1), section.getSuggestionAt(2)); @@ -568,12 +580,15 @@ // Remove last two items. section.removeSuggestionById(section.getSuggestionAt(3).mIdWithinCategory); section.removeSuggestionById(section.getSuggestionAt(2).mIdWithinCategory); + reset(mParent); assertEquals(1, section.getSuggestionsCount()); section.setSuggestions(createDummySuggestions(4, TEST_CATEGORY_ID), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); // We do not touch the current list if all has been seen. + verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(), anyInt()); + verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt(), anyInt()); assertEquals(1, section.getSuggestionsCount()); assertEquals(snippets.get(0), section.getSuggestionAt(1)); } @@ -593,6 +608,8 @@ section.setSuggestions(createDummySuggestions(3, TEST_CATEGORY_ID), CategoryStatus.AVAILABLE, /* replaceExisting = */ true); + verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(), anyInt()); + verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt(), anyInt()); // All old snippets should be in place. verifySnippets(section, snippets); @@ -631,6 +648,10 @@ SuggestionsSection section = createSectionWithReloadAction(true); section.setStatus(CategoryStatus.AVAILABLE); section.setSuggestions(snippets, CategoryStatus.AVAILABLE, /* replaceExisting = */ true); + + // Reset any notification invocations on the parent from setting the initial list + // of suggestions. + reset(mParent); return section; } @@ -667,7 +688,7 @@ when(manager.getMetricsReporter()).thenReturn(mock(SuggestionsMetricsReporter.class)); if (action != ActionItem.ACTION_NONE) { - section.getActionItem().performAction(manager); + section.getActionItemForTesting().performAction(manager); } verify(section.getCategoryInfo(),
diff --git a/chrome/app/resources/locale_settings_mac.grd b/chrome/app/resources/locale_settings_mac.grd index 812c18b..3b49d1d4 100644 --- a/chrome/app/resources/locale_settings_mac.grd +++ b/chrome/app/resources/locale_settings_mac.grd
@@ -215,7 +215,7 @@ <!-- The default value for |WebPreference::serif_font_family_map| for Simplified Chinese script. --> <message name="IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true"> - STSong + Songti SC </message> <!-- The default value for |WebPreference::sans_serif_font_family_map| for @@ -239,7 +239,7 @@ <!-- The default value for |WebPreference::serif_font_family_map| for Traditional Chinese script. --> <message name="IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true"> - LiSong Pro + Songti TC </message> <!-- The default value for |WebPreference::sans_serif_font_family_map| for
diff --git a/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-CN.xtb b/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-CN.xtb index eaac82c..caa09d2 100644 --- a/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-CN.xtb +++ b/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-CN.xtb
@@ -2,7 +2,7 @@ <!DOCTYPE translationbundle> <translationbundle lang="zh-CN"> <translation id="IDS_STANDARD_FONT_FAMILY">,PingFang SC,STHeiti</translation> -<translation id="IDS_SERIF_FONT_FAMILY">STSong</translation> +<translation id="IDS_SERIF_FONT_FAMILY">Songti SC</translation> <translation id="IDS_SANS_SERIF_FONT_FAMILY">,PingFang SC,STHeiti</translation> <translation id="IDS_CURSIVE_FONT_FAMILY">Kaiti SC</translation> <translation id="IDS_MINIMUM_FONT_SIZE">12</translation>
diff --git a/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-TW.xtb b/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-TW.xtb index 0ea5a9d..664a81b 100644 --- a/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-TW.xtb +++ b/chrome/app/resources/platform_locale_settings/locale_settings_mac_zh-TW.xtb
@@ -2,7 +2,7 @@ <!DOCTYPE translationbundle> <translationbundle lang="zh-TW"> <translation id="IDS_STANDARD_FONT_FAMILY">,PingFang TC,Heiti TC</translation> -<translation id="IDS_SERIF_FONT_FAMILY">LiSong Pro</translation> +<translation id="IDS_SERIF_FONT_FAMILY">Songti TC</translation> <translation id="IDS_SANS_SERIF_FONT_FAMILY">,PingFang TC,Heiti TC</translation> <translation id="IDS_CURSIVE_FONT_FAMILY">Kaiti TC</translation> <translation id="IDS_MINIMUM_FONT_SIZE">12</translation>
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 8cbc9319..fb40a0d 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -147,7 +147,7 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kWebPaymentsSingleAppUiSkip{ - "WebPaymentsSingleAppUiSkip", base::FEATURE_DISABLED_BY_DEFAULT}; + "WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT}; static jboolean IsEnabled(JNIEnv* env, const JavaParamRef<jclass>& clazz,
diff --git a/chrome/browser/android/omnibox/omnibox_prerender.cc b/chrome/browser/android/omnibox/omnibox_prerender.cc index 2d4bd40..5342880 100644 --- a/chrome/browser/android/omnibox/omnibox_prerender.cc +++ b/chrome/browser/android/omnibox/omnibox_prerender.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" -#include "chrome/browser/ui/search/instant_search_prerenderer.h" #include "components/omnibox/browser/autocomplete_match.h" #include "components/omnibox/browser/autocomplete_result.h" #include "content/public/browser/web_contents.h" @@ -91,26 +90,15 @@ if (default_match == autocomplete_result->end()) return; - AutocompleteActionPredictor::Action recommended_action = - AutocompleteActionPredictor::ACTION_NONE; - InstantSearchPrerenderer* prerenderer = - InstantSearchPrerenderer::GetForProfile(profile); - if (prerenderer && - prerenderer->IsAllowed(*default_match, web_contents)) { - recommended_action = AutocompleteActionPredictor::ACTION_PRERENDER; - } else { - AutocompleteActionPredictor* action_predictor = - AutocompleteActionPredictorFactory::GetForProfile(profile); - if (!action_predictor) - return; + AutocompleteActionPredictor* action_predictor = + AutocompleteActionPredictorFactory::GetForProfile(profile); + if (!action_predictor) + return; - if (action_predictor) { - action_predictor-> - RegisterTransitionalMatches(url_string, *autocomplete_result); - recommended_action = - action_predictor->RecommendAction(url_string, *default_match); - } - } + action_predictor-> + RegisterTransitionalMatches(url_string, *autocomplete_result); + AutocompleteActionPredictor::Action recommended_action = + action_predictor->RecommendAction(url_string, *default_match); GURL current_url = GURL(current_url_string); switch (recommended_action) { @@ -145,14 +133,6 @@ if (!web_contents) return; gfx::Rect container_bounds = web_contents->GetContainerBounds(); - InstantSearchPrerenderer* prerenderer = - InstantSearchPrerenderer::GetForProfile(profile); - if (prerenderer && prerenderer->IsAllowed(match, web_contents)) { - prerenderer->Init( - web_contents->GetController().GetDefaultSessionStorageNamespace(), - container_bounds.size()); - return; - } predictors::AutocompleteActionPredictorFactory::GetForProfile(profile)-> StartPrerendering( match.destination_url,
diff --git a/chrome/browser/android/vr_shell/vr_compositor.cc b/chrome/browser/android/vr_shell/vr_compositor.cc index 882236f..e386d90 100644 --- a/chrome/browser/android/vr_shell/vr_compositor.cc +++ b/chrome/browser/android/vr_shell/vr_compositor.cc
@@ -20,12 +20,8 @@ } VrCompositor::~VrCompositor() { - if (layer_) { - layer_->SetBackgroundColor(background_color_); - if (layer_parent_) { - layer_parent_->AddChild(layer_); - } - } + if (layer_) + RestoreLayer(); } void VrCompositor::UpdateLayerTreeHost() {} @@ -33,7 +29,8 @@ void VrCompositor::OnSwapBuffersCompleted(int pending_swap_buffers) {} void VrCompositor::SetLayer(content::WebContents* web_contents) { - assert(layer_ == nullptr); + if (layer_) + RestoreLayer(); ui::ViewAndroid* view_android = web_contents->GetNativeView(); // When we pass the layer for the ContentViewCore to the compositor it may be @@ -50,6 +47,13 @@ compositor_->SetRootLayer(layer_); } +void VrCompositor::RestoreLayer() { + layer_->SetBackgroundColor(background_color_); + if (layer_parent_) { + layer_parent_->AddChild(layer_); + } +} + void VrCompositor::SurfaceDestroyed() { compositor_->SetSurface(nullptr); }
diff --git a/chrome/browser/android/vr_shell/vr_compositor.h b/chrome/browser/android/vr_shell/vr_compositor.h index a0e87202..7238ad8 100644 --- a/chrome/browser/android/vr_shell/vr_compositor.h +++ b/chrome/browser/android/vr_shell/vr_compositor.h
@@ -45,6 +45,8 @@ void OnSwapBuffersCompleted(int pending_swap_buffers) override; private: + void RestoreLayer(); + std::unique_ptr<content::Compositor> compositor_; gfx::Size bounds_;
diff --git a/chrome/browser/android/vr_shell/vr_input_manager.cc b/chrome/browser/android/vr_shell/vr_input_manager.cc index e8ceb40c..efb98cb 100644 --- a/chrome/browser/android/vr_shell/vr_input_manager.cc +++ b/chrome/browser/android/vr_shell/vr_input_manager.cc
@@ -30,16 +30,11 @@ } // namespace VrInputManager::VrInputManager(content::WebContents* web_contents) - : web_contents_(web_contents), - weak_ptr_factory_(this) { + : web_contents_(web_contents) { } VrInputManager::~VrInputManager() = default; -base::WeakPtr<VrInputManager> VrInputManager::GetWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); -} - void VrInputManager::ProcessUpdatedGesture( std::unique_ptr<blink::WebInputEvent> event) { if (WebInputEvent::isMouseEventType(event->type())) {
diff --git a/chrome/browser/android/vr_shell/vr_input_manager.h b/chrome/browser/android/vr_shell/vr_input_manager.h index f80b331..8e4e70d8 100644 --- a/chrome/browser/android/vr_shell/vr_input_manager.h +++ b/chrome/browser/android/vr_shell/vr_input_manager.h
@@ -23,7 +23,6 @@ explicit VrInputManager(content::WebContents* web_contents); ~VrInputManager(); - base::WeakPtr<VrInputManager> GetWeakPtr(); void ProcessUpdatedGesture(std::unique_ptr<blink::WebInputEvent> event); private: @@ -33,8 +32,6 @@ content::WebContents* web_contents_; - base::WeakPtrFactory<VrInputManager> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(VrInputManager); };
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc index 2704107f..4cba25a 100644 --- a/chrome/browser/android/vr_shell/vr_shell.cc +++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -27,6 +27,7 @@ #include "content/public/common/referrer.h" #include "device/vr/android/gvr/gvr_device_provider.h" #include "jni/VrShellImpl_jni.h" +#include "third_party/WebKit/public/platform/WebInputEvent.h" #include "ui/android/view_android.h" #include "ui/android/window_android.h" #include "ui/base/page_transition_types.h" @@ -46,16 +47,12 @@ class GLThread : public base::Thread { public: GLThread(const base::WeakPtr<VrShell>& weak_vr_shell, - const base::WeakPtr<VrInputManager>& content_input_manager, - const base::WeakPtr<VrInputManager>& ui_input_manager, scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, gvr_context* gvr_api, bool initially_web_vr, bool reprojected_rendering) : base::Thread("VrShellGL"), weak_vr_shell_(weak_vr_shell), - content_input_manager_(content_input_manager), - ui_input_manager_(ui_input_manager), main_thread_task_runner_(std::move(main_thread_task_runner)), gvr_api_(gvr_api), initially_web_vr_(initially_web_vr), @@ -70,8 +67,6 @@ protected: void Init() override { vr_shell_gl_.reset(new VrShellGl(std::move(weak_vr_shell_), - std::move(content_input_manager_), - std::move(ui_input_manager_), std::move(main_thread_task_runner_), gvr_api_, initially_web_vr_, @@ -89,14 +84,17 @@ base::WeakPtr<VrShellGl> weak_vr_shell_gl_; base::WeakPtr<VrShell> weak_vr_shell_; - base::WeakPtr<VrInputManager> content_input_manager_; - base::WeakPtr<VrInputManager> ui_input_manager_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; gvr_context* gvr_api_; bool initially_web_vr_; bool reprojected_rendering_; }; +void SetIsInVR(content::WebContents* contents, bool is_in_vr) { + if (contents->GetRenderWidgetHostView()) + contents->GetRenderWidgetHostView()->SetIsInVR(is_in_vr); +} + } // namespace VrShell::VrShell(JNIEnv* env, @@ -111,11 +109,12 @@ bool reprojected_rendering) : WebContentsObserver(ui_contents), main_contents_(main_contents), - content_compositor_(new VrCompositor(content_window, false)), + content_compositor_( + base::MakeUnique<VrCompositor>(content_window, false)), ui_contents_(ui_contents), - ui_compositor_(new VrCompositor(ui_window, true)), + ui_compositor_(base::MakeUnique<VrCompositor>(ui_window, true)), delegate_(delegate), - metrics_helper_(new VrMetricsHelper(main_contents_)), + metrics_helper_(base::MakeUnique<VrMetricsHelper>(main_contents_)), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), reprojected_rendering_(reprojected_rendering), weak_ptr_factory_(this) { @@ -123,19 +122,15 @@ g_instance = this; j_vr_shell_.Reset(env, obj); - content_input_manager_.reset(new VrInputManager(main_contents_)); - ui_input_manager_.reset(new VrInputManager(ui_contents_)); + content_input_manager_ = base::MakeUnique<VrInputManager>(main_contents_); + ui_input_manager_ = base::MakeUnique<VrInputManager>(ui_contents_); content_compositor_->SetLayer(main_contents_); ui_compositor_->SetLayer(ui_contents_); - gl_thread_.reset(new GLThread(weak_ptr_factory_.GetWeakPtr(), - content_input_manager_->GetWeakPtr(), - ui_input_manager_->GetWeakPtr(), - main_thread_task_runner_, - gvr_api, - for_web_vr, - reprojected_rendering_)); + gl_thread_ = base::MakeUnique<GLThread>(weak_ptr_factory_.GetWeakPtr(), + main_thread_task_runner_, gvr_api, + for_web_vr, reprojected_rendering_); base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT, 0); options.priority = base::ThreadPriority::DISPLAY; @@ -143,19 +138,39 @@ if (for_web_vr) metrics_helper_->SetWebVREnabled(true); - html_interface_.reset(new UiInterface( + html_interface_ = base::MakeUnique<UiInterface>( for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD, - main_contents_->IsFullscreen())); - vr_web_contents_observer_.reset(new VrWebContentsObserver( - main_contents, html_interface_.get(), this)); + main_contents_->IsFullscreen()); + vr_web_contents_observer_ = base::MakeUnique<VrWebContentsObserver>( + main_contents_, html_interface_.get(), this); - SetIsInVR(true); + SetIsInVR(main_contents_, true); } void VrShell::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { delete this; } +void VrShell::SwapContents(JNIEnv* env, const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& web_contents) { + SetIsInVR(main_contents_, false); + content::WebContents* contents = + content::WebContents::FromJavaWebContents(web_contents); + main_contents_ = contents; + content_input_manager_ = base::MakeUnique<VrInputManager>(main_contents_); + content_compositor_->SetLayer(main_contents_); + vr_web_contents_observer_ = base::MakeUnique<VrWebContentsObserver>( + main_contents_, html_interface_.get(), this); + SetIsInVR(main_contents_, true); + + // TODO(billorr): Make VrMetricsHelper tab-aware and able to track multiple + // tabs. crbug.com/684661 + metrics_helper_ = base::MakeUnique<VrMetricsHelper>(main_contents_); + metrics_helper_->SetVRActive(true); + metrics_helper_->SetWebVREnabled( + html_interface_->GetMode() == UiInterface::Mode::WEB_VR); +} + void VrShell::LoadUIContent(JNIEnv* env, const JavaParamRef<jobject>& obj) { GURL url(kVrShellUIURL); ui_contents_->GetController().LoadURL( @@ -209,7 +224,7 @@ // exit vr session metrics_helper_->SetVRActive(false); - SetIsInVR(false); + SetIsInVR(main_contents_, false); } void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { @@ -218,7 +233,7 @@ FROM_HERE, base::Bind(&VrShellGl::OnResume, thread->GetVrShellGl())); metrics_helper_->SetVRActive(true); - SetIsInVR(true); + SetIsInVR(main_contents_, true); } void VrShell::SetSurface(JNIEnv* env, @@ -233,10 +248,6 @@ base::Unretained(window))); } -void VrShell::SetIsInVR(bool is_in_vr) { - main_contents_->GetRenderWidgetHostView()->SetIsInVR(is_in_vr); -} - base::WeakPtr<VrShell> VrShell::GetWeakPtr( const content::WebContents* web_contents) { // Ensure that the WebContents requesting the VrShell instance is the one @@ -448,9 +459,11 @@ void VrShell::ContentWasHidden() { // Ensure we don't continue sending input to it. - content_input_manager_.reset(); - // TODO(mthiesse): Handle web contents being hidden. - ForceExitVr(); + content_input_manager_ = nullptr; +} + +void VrShell::ContentWasShown() { + content_input_manager_ = base::MakeUnique<VrInputManager>(main_contents_); } void VrShell::ForceExitVr() { @@ -468,6 +481,21 @@ Java_VrShellImpl_setUiCssSize(env, j_vr_shell_.obj(), width, height, dpr); } +void VrShell::ProcessUIGesture(std::unique_ptr<blink::WebInputEvent> event) { + if (ui_input_manager_) { + ui_input_manager_->ProcessUpdatedGesture(std::move(event)); + } + +} + +void VrShell::ProcessContentGesture( + std::unique_ptr<blink::WebInputEvent> event) { + if (content_input_manager_) { + content_input_manager_->ProcessUpdatedGesture(std::move(event)); + } +} + + // ---------------------------------------------------------------------------- // Native JNI methods // ----------------------------------------------------------------------------
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h index 8b71dc0..f0e83ec 100644 --- a/chrome/browser/android/vr_shell/vr_shell.h +++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -24,6 +24,10 @@ class Thread; } +namespace blink { +class WebInputEvent; +} + namespace content { class WebContents; } @@ -65,7 +69,9 @@ VrShellDelegate* delegate, gvr_context* gvr_api, bool reprojected_rendering); - + void SwapContents(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& web_contents); void LoadUIContent(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); @@ -89,6 +95,7 @@ // Called when our WebContents have been hidden. Usually a sign that something // like another tab placed in front of it. void ContentWasHidden(); + void ContentWasShown(); // html/js UI hooks. static base::WeakPtr<VrShell> GetWeakPtr( @@ -136,9 +143,11 @@ void ForceExitVr(); + void ProcessUIGesture(std::unique_ptr<blink::WebInputEvent> event); + void ProcessContentGesture(std::unique_ptr<blink::WebInputEvent> event); + private: ~VrShell() override; - void SetIsInVR(bool is_in_vr); void PostToGlThreadWhenReady(const base::Closure& task); // content::WebContentsObserver implementation. All called on UI thread.
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc index 93ffa9ab..f9a0af1 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.cc +++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -12,11 +12,11 @@ #include "chrome/browser/android/vr_shell/ui_scene.h" #include "chrome/browser/android/vr_shell/vr_controller.h" #include "chrome/browser/android/vr_shell/vr_gl_util.h" -#include "chrome/browser/android/vr_shell/vr_input_manager.h" #include "chrome/browser/android/vr_shell/vr_math.h" #include "chrome/browser/android/vr_shell/vr_shell.h" #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" +#include "third_party/WebKit/public/platform/WebMouseEvent.h" #include "ui/gfx/vsync_provider.h" #include "ui/gl/android/scoped_java_surface.h" #include "ui/gl/android/surface_texture.h" @@ -180,8 +180,6 @@ VrShellGl::VrShellGl( const base::WeakPtr<VrShell>& weak_vr_shell, - const base::WeakPtr<VrInputManager>& content_input_manager, - const base::WeakPtr<VrInputManager>& ui_input_manager, scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, gvr_context* gvr_api, bool initially_web_vr, @@ -190,8 +188,6 @@ surfaceless_rendering_(reprojected_rendering), task_runner_(base::ThreadTaskRunnerHandle::Get()), weak_vr_shell_(weak_vr_shell), - content_input_manager_(content_input_manager), - ui_input_manager_(ui_input_manager), main_thread_task_runner_(std::move(main_thread_task_runner)), weak_ptr_factory_(this) { GvrInit(gvr_api); @@ -580,13 +576,12 @@ void VrShellGl::SendGesture(InputTarget input_target, std::unique_ptr<blink::WebInputEvent> event) { DCHECK(input_target != InputTarget::NONE); - const base::WeakPtr<VrInputManager>& weak_ptr = - input_target == InputTarget::CONTENT ? content_input_manager_ - : ui_input_manager_; + auto&& target = input_target == InputTarget::CONTENT + ? &VrShell::ProcessContentGesture + : &VrShell::ProcessUIGesture; main_thread_task_runner_->PostTask( FROM_HERE, - base::Bind(&VrInputManager::ProcessUpdatedGesture, weak_ptr, - base::Passed(std::move(event)))); + base::Bind(target, weak_vr_shell_, base::Passed(std::move(event)))); } void VrShellGl::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) {
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h index c5dce100..f38164b 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.h +++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -36,7 +36,6 @@ class UiScene; class VrController; -class VrInputManager; class VrShell; class VrShellRenderer; struct ContentRectangle; @@ -53,8 +52,6 @@ VrShellGl( const base::WeakPtr<VrShell>& weak_vr_shell, - const base::WeakPtr<VrInputManager>& content_input_manager, - const base::WeakPtr<VrInputManager>& ui_input_manager, scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, gvr_context* gvr_api, bool initially_web_vr, @@ -176,8 +173,6 @@ base::TimeDelta vsync_interval_; base::WeakPtr<VrShell> weak_vr_shell_; - base::WeakPtr<VrInputManager> content_input_manager_; - base::WeakPtr<VrInputManager> ui_input_manager_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; base::WeakPtrFactory<VrShellGl> weak_ptr_factory_;
diff --git a/chrome/browser/android/vr_shell/vr_web_contents_observer.cc b/chrome/browser/android/vr_shell/vr_web_contents_observer.cc index 77979416..7d819ee 100644 --- a/chrome/browser/android/vr_shell/vr_web_contents_observer.cc +++ b/chrome/browser/android/vr_shell/vr_web_contents_observer.cc
@@ -81,6 +81,11 @@ vr_shell_->ContentWasHidden(); } +void VrWebContentsObserver::WasShown() { + vr_shell_->ContentWasShown(); +} + + void VrWebContentsObserver::MainFrameWasResized(bool width_changed) { vr_shell_->ContentFrameWasResized(width_changed); }
diff --git a/chrome/browser/android/vr_shell/vr_web_contents_observer.h b/chrome/browser/android/vr_shell/vr_web_contents_observer.h index a3102e13..de2652a 100644 --- a/chrome/browser/android/vr_shell/vr_web_contents_observer.h +++ b/chrome/browser/android/vr_shell/vr_web_contents_observer.h
@@ -42,6 +42,7 @@ void DidChangeVisibleSecurityState() override; void WebContentsDestroyed() override; void WasHidden() override; + void WasShown() override; void MainFrameWasResized(bool width_changed) override; void RenderViewHostChanged(content::RenderViewHost* old_host, content::RenderViewHost* new_host) override;
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index 4e89ac2c..950fbba 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -38,6 +38,7 @@ #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" +#include "chrome/browser/translate/language_model_factory.h" #include "chrome/browser/web_data_service_factory.h" #include "chrome/common/features.h" #include "chrome/common/pref_names.h" @@ -63,6 +64,7 @@ #include "components/previews/core/previews_ui_service.h" #include "components/search_engines/template_url_service.h" #include "components/sessions/core/tab_restore_service.h" +#include "components/translate/core/browser/language_model.h" #include "content/public/browser/plugin_data_remover.h" #include "content/public/browser/ssl_host_state_delegate.h" #include "content/public/browser/storage_partition.h" @@ -375,6 +377,12 @@ filter, bookmark_model); } + translate::LanguageModel* language_model = + LanguageModelFactory::GetInstance()->GetForBrowserContext(profile_); + if (language_model) { + language_model->ClearHistory(delete_begin_, delete_end_); + } + #if BUILDFLAG(ENABLE_EXTENSIONS) // The extension activity log contains details of which websites extensions // were active on. It therefore indirectly stores details of websites a
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 009376f..86871d8 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/permissions/permission_decision_auto_blocker.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/storage/durable_storage_permission_context.h" +#include "chrome/browser/translate/language_model_factory.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" @@ -54,6 +55,7 @@ #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_store_consumer.h" #include "components/prefs/testing_pref_service.h" +#include "components/translate/core/browser/language_model.h" #include "content/public/test/mock_download_manager.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" @@ -91,6 +93,7 @@ using testing::_; using testing::ByRef; using testing::Eq; +using testing::FloatEq; using testing::Invoke; using testing::IsEmpty; using testing::Matcher; @@ -1739,3 +1742,35 @@ EXPECT_THAT(remaining_nodes, SizeIs(1)); EXPECT_THAT(remaining_nodes[0]->url().spec(), Eq("http://foo-2.org/")); } + +// Test that the remover clears language model data (normally added by the +// ChromeTranslateClient). +TEST_F(ChromeBrowsingDataRemoverDelegateTest, + LanguageModelClearedOnClearingCompleteHistory) { + translate::LanguageModel* language_model = + LanguageModelFactory::GetInstance()->GetForBrowserContext(GetProfile()); + + // Simulate browsing. + for (int i = 0; i < 100; i++) { + language_model->OnPageVisited("en"); + language_model->OnPageVisited("en"); + language_model->OnPageVisited("en"); + language_model->OnPageVisited("es"); + } + + // Clearing a part of the history has no effect. + BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), + BrowsingDataRemover::REMOVE_HISTORY, false); + + EXPECT_THAT(language_model->GetTopLanguages(), SizeIs(2)); + EXPECT_THAT(language_model->GetLanguageFrequency("en"), FloatEq(0.75)); + EXPECT_THAT(language_model->GetLanguageFrequency("es"), FloatEq(0.25)); + + // Clearing the full history does the trick. + BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), + BrowsingDataRemover::REMOVE_HISTORY, false); + + EXPECT_THAT(language_model->GetTopLanguages(), SizeIs(0)); + EXPECT_THAT(language_model->GetLanguageFrequency("en"), FloatEq(0.0)); + EXPECT_THAT(language_model->GetLanguageFrequency("es"), FloatEq(0.0)); +}
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 4b830e7a..5de302c 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -3110,6 +3110,31 @@ FINAL_STATUS_NEW_NAVIGATION_ENTRY, 1); } +// Checks that the prerendering of a page for ORIGIN_OFFLINE is not canceled +// when the prerendered page tries to make a second navigation entry. +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, + PrerenderNewNavigationEntryForOffline) { + // Navigate to about:blank to get the session storage namespace. + ui_test_utils::NavigateToURL(current_browser(), GURL(url::kAboutBlankURL)); + content::SessionStorageNamespace* storage_namespace = + GetActiveWebContents() + ->GetController() + .GetDefaultSessionStorageNamespace(); + + std::unique_ptr<TestPrerender> test_prerender = + prerender_contents_factory()->ExpectPrerenderContents( + FINAL_STATUS_APP_TERMINATING); + + const GURL url = + src_server()->GetURL(MakeAbsolute("/prerender/prerender_new_entry.html")); + std::unique_ptr<PrerenderHandle> prerender_handle( + GetPrerenderManager()->AddPrerenderForOffline(url, storage_namespace, + gfx::Size(640, 480))); + ASSERT_EQ(prerender_handle->contents(), test_prerender->contents()); + test_prerender->WaitForLoads(2); + ASSERT_EQ(1, GetActiveWebContents()->GetController().GetEntryCount()); +} + // Attempt a swap-in in a new tab. The session storage doesn't match, so it // should not swap. IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) {
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc index aea147d..cbff038 100644 --- a/chrome/browser/prerender/prerender_contents.cc +++ b/chrome/browser/prerender/prerender_contents.cc
@@ -577,6 +577,13 @@ void PrerenderContents::DidNavigateMainFrame( const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) { + // Prevent ORIGIN_OFFLINE prerenders from being destroyed on location.href + // change, since the history is never merged for offline prerenders. Also + // avoid adding aliases as they may potentially mark other valid requests to + // offline as duplicate. + if (origin() == ORIGIN_OFFLINE) + return; + // If the prerender made a second navigation entry, abort the prerender. This // avoids having to correctly implement a complex history merging case (this // interacts with location.replace) and correctly synchronize with the
diff --git a/chrome/browser/prerender/prerender_tab_helper.cc b/chrome/browser/prerender/prerender_tab_helper.cc index bb34ce2..e9e6018 100644 --- a/chrome/browser/prerender/prerender_tab_helper.cc +++ b/chrome/browser/prerender/prerender_tab_helper.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/prerender/prerender_manager_factory.h" #include "chrome/browser/profiles/profile.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/resource_request_details.h" #include "content/public/browser/web_contents.h" @@ -37,19 +38,21 @@ MainFrameUrlDidChange(details.new_url); } -void PrerenderTabHelper::DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - ui::PageTransition transition_type) { - if (render_frame_host->GetParent()) +void PrerenderTabHelper::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame() || + !navigation_handle->HasCommitted() || + navigation_handle->IsErrorPage()) { return; - url_ = validated_url; + } + + url_ = navigation_handle->GetURL(); PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); if (!prerender_manager) return; if (prerender_manager->IsWebContentsPrerendering(web_contents(), NULL)) return; - prerender_manager->RecordNavigation(validated_url); + prerender_manager->RecordNavigation(url_); } void PrerenderTabHelper::DidStopLoading() { @@ -90,10 +93,11 @@ actual_load_start_ = base::TimeTicks(); } -void PrerenderTabHelper::DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page) { +void PrerenderTabHelper::DidStartNavigation( + content::NavigationHandle* navigation_handle) { + if (navigation_handle->IsSamePage()) + return; + // Determine the navigation type. PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); if (prerender_manager && @@ -103,14 +107,14 @@ navigation_type_ = NAVIGATION_TYPE_NORMAL; } - if (render_frame_host->GetParent()) + if (!navigation_handle->IsInMainFrame()) return; // Record PPLT state for the beginning of a new navigation. pplt_load_start_ = GetTimeTicksFromPrerenderManager(); actual_load_start_ = base::TimeTicks(); - MainFrameUrlDidChange(validated_url); + MainFrameUrlDidChange(navigation_handle->GetURL()); } void PrerenderTabHelper::MainFrameUrlDidChange(const GURL& url) {
diff --git a/chrome/browser/prerender/prerender_tab_helper.h b/chrome/browser/prerender/prerender_tab_helper.h index 5f96be28..f944aa1 100644 --- a/chrome/browser/prerender/prerender_tab_helper.h +++ b/chrome/browser/prerender/prerender_tab_helper.h
@@ -32,14 +32,10 @@ void DidGetRedirectForResourceRequest( const content::ResourceRedirectDetails& details) override; void DidStopLoading() override; - void DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page) override; - void DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - ui::PageTransition transition_type) override; + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; // Called when the URL of the main frame changed, either when the load // commits, or a redirect happens.
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc index f9c8481..10671f8 100644 --- a/chrome/browser/sync/profile_sync_service_factory.cc +++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -152,7 +152,12 @@ init_params.url_request_context = profile->GetRequestContext(); init_params.debug_identifier = profile->GetDebugName(); init_params.channel = chrome::GetChannel(); - init_params.blocking_pool = content::BrowserThread::GetBlockingPool(); + base::SequencedWorkerPool* blocking_pool = + content::BrowserThread::GetBlockingPool(); + init_params.blocking_task_runner = + blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior( + blocking_pool->GetSequenceToken(), + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); bool local_sync_backend_enabled = false;
diff --git a/chrome/browser/sync/profile_sync_test_util.cc b/chrome/browser/sync/profile_sync_test_util.cc index c06b04f..c59b3c0 100644 --- a/chrome/browser/sync/profile_sync_test_util.cc +++ b/chrome/browser/sync/profile_sync_test_util.cc
@@ -55,7 +55,12 @@ init_params.url_request_context = profile->GetRequestContext(); init_params.debug_identifier = profile->GetDebugName(); init_params.channel = chrome::GetChannel(); - init_params.blocking_pool = content::BrowserThread::GetBlockingPool(); + base::SequencedWorkerPool* blocking_pool = + content::BrowserThread::GetBlockingPool(); + init_params.blocking_task_runner = + blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior( + blocking_pool->GetSequenceToken(), + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); return init_params; }
diff --git a/chrome/browser/tracing/navigation_tracing.cc b/chrome/browser/tracing/navigation_tracing.cc index e5c7332..510b6e9 100644 --- a/chrome/browser/tracing/navigation_tracing.cc +++ b/chrome/browser/tracing/navigation_tracing.cc
@@ -15,6 +15,7 @@ #include "content/public/browser/background_tracing_config.h" #include "content/public/browser/background_tracing_manager.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" DEFINE_WEB_CONTENTS_USER_DATA_KEY(tracing::NavigationTracingObserver); @@ -101,8 +102,8 @@ NavigationTracingObserver::NavigationTracingObserver( content::WebContents* web_contents) : content::WebContentsObserver(web_contents) { - if (navigation_handle == -1) { - navigation_handle = + if (navigation_trigger_handle_ == -1) { + navigation_trigger_handle_ = content::BackgroundTracingManager::GetInstance()->RegisterTriggerType( kNavigationTracingConfig); } @@ -111,18 +112,16 @@ NavigationTracingObserver::~NavigationTracingObserver() { } -void NavigationTracingObserver::DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page) { - if (!render_frame_host->GetParent() && !is_error_page) { +void NavigationTracingObserver::DidStartNavigation( + content::NavigationHandle* navigation_handle) { + if (navigation_handle->IsInMainFrame()) { content::BackgroundTracingManager::GetInstance()->TriggerNamedEvent( - navigation_handle, + navigation_trigger_handle_, content::BackgroundTracingManager::StartedFinalizingCallback()); } } content::BackgroundTracingManager::TriggerHandle - NavigationTracingObserver::navigation_handle = -1; + NavigationTracingObserver::navigation_trigger_handle_ = -1; } // namespace tracing
diff --git a/chrome/browser/tracing/navigation_tracing.h b/chrome/browser/tracing/navigation_tracing.h index f26287e..709379d 100644 --- a/chrome/browser/tracing/navigation_tracing.h +++ b/chrome/browser/tracing/navigation_tracing.h
@@ -28,12 +28,11 @@ ~NavigationTracingObserver() override; // content::WebContentsObserver implementation. - void DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page) override; + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override; - static content::BackgroundTracingManager::TriggerHandle navigation_handle; + static content::BackgroundTracingManager::TriggerHandle + navigation_trigger_handle_; DISALLOW_COPY_AND_ASSIGN(NavigationTracingObserver); };
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 4e8f3cbd..9cba78d 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1804,6 +1804,8 @@ "views/payments/payment_request_views_util.h", "views/payments/payment_sheet_view_controller.cc", "views/payments/payment_sheet_view_controller.h", + "views/payments/shipping_list_view_controller.cc", + "views/payments/shipping_list_view_controller.h", "views/payments/view_stack.cc", "views/payments/view_stack.h", "views/process_singleton_dialog_linux.cc",
diff --git a/chrome/browser/ui/android/toolbar/toolbar_model_android.cc b/chrome/browser/ui/android/toolbar/toolbar_model_android.cc index 8676af2..9368db5 100644 --- a/chrome/browser/ui/android/toolbar/toolbar_model_android.cc +++ b/chrome/browser/ui/android/toolbar/toolbar_model_android.cc
@@ -5,17 +5,12 @@ #include "chrome/browser/ui/android/toolbar/toolbar_model_android.h" #include "base/android/jni_string.h" -#include "base/metrics/field_trial.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search/search.h" -#include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "components/toolbar/toolbar_model_impl.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/ssl_status.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_constants.h" #include "jni/ToolbarModel_jni.h" -#include "net/cert/x509_certificate.h" using base::android::JavaParamRef; using base::android::ScopedJavaLocalRef;
diff --git a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm index 7e4c133a..5dfac1d 100644 --- a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm
@@ -144,7 +144,7 @@ if (bubble_) CloseBubble(); else - ShowBubble(NO); + ShowBubble(YES); return true; }
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc index 355a8a9..8abd360 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc +++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
@@ -11,10 +11,10 @@ #include "chrome/browser/ui/views/payments/order_summary_view_controller.h" #include "chrome/browser/ui/views/payments/payment_method_view_controller.h" #include "chrome/browser/ui/views/payments/payment_sheet_view_controller.h" +#include "chrome/browser/ui/views/payments/shipping_list_view_controller.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "components/payments/payment_request.h" -#include "components/payments/payment_request_dialog.h" #include "content/public/browser/browser_thread.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/layout/fill_layout.h" @@ -101,13 +101,19 @@ void PaymentRequestDialogView::ShowOrderSummary() { view_stack_.Push(CreateViewAndInstallController<OrderSummaryViewController>( &controller_map_, request_, this), - true); + /* animate = */ true); } void PaymentRequestDialogView::ShowPaymentMethodSheet() { view_stack_.Push(CreateViewAndInstallController<PaymentMethodViewController>( &controller_map_, request_, this), - true); + /* animate = */ true); +} + +void PaymentRequestDialogView::ShowShippingListSheet() { + view_stack_.Push(CreateViewAndInstallController<ShippingListViewController>( + &controller_map_, request_, this), + /* animate = */ true); } void PaymentRequestDialogView::ShowDialog() { @@ -122,7 +128,7 @@ void PaymentRequestDialogView::ShowInitialPaymentSheet() { view_stack_.Push(CreateViewAndInstallController<PaymentSheetViewController>( &controller_map_, request_, this), - false); + /* animate = */ false); if (observer_for_testing_) observer_for_testing_->OnDialogOpened(); }
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.h b/chrome/browser/ui/views/payments/payment_request_dialog_view.h index 4dc07950..1d35d2f 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog_view.h +++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
@@ -56,6 +56,7 @@ void GoBack(); void ShowOrderSummary(); + void ShowShippingListSheet(); void ShowPaymentMethodSheet(); private:
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index 87d3f2d..061d75fd 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -213,7 +213,7 @@ break; case static_cast<int>(PaymentSheetViewControllerTags::SHOW_SHIPPING_BUTTON): - // TODO(tmartino): Transition to shipping page once it exists. + dialog()->ShowShippingListSheet(); break; case static_cast<int>( @@ -266,7 +266,7 @@ std::unique_ptr<views::View> PaymentSheetViewController::CreateShippingSectionContent() { - auto profile = request()->GetCurrentlySelectedProfile(); + auto profile = request()->selected_shipping_profile(); // TODO(tmartino): Empty string param is app locale; this should be passed // at construct-time and stored as a member in a future CL. @@ -351,7 +351,7 @@ std::unique_ptr<views::View> PaymentSheetViewController::CreateContactInfoSectionContent() { - auto profile = request()->GetCurrentlySelectedProfile(); + auto profile = request()->selected_contact_profile(); // TODO(tmartino): Replace empty string with app locale. return profile ? payments::GetContactInfoLabel(AddressStyleType::SUMMARY, std::string(), *profile, true,
diff --git a/chrome/browser/ui/views/payments/shipping_list_view_controller.cc b/chrome/browser/ui/views/payments/shipping_list_view_controller.cc new file mode 100644 index 0000000..25b391f --- /dev/null +++ b/chrome/browser/ui/views/payments/shipping_list_view_controller.cc
@@ -0,0 +1,66 @@ +// 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 "chrome/browser/ui/views/payments/shipping_list_view_controller.h" + +#include <memory> +#include <utility> + +#include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" +#include "chrome/browser/ui/views/payments/payment_request_views_util.h" +#include "components/payments/payment_request.h" +#include "components/strings/grit/components_strings.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/views/layout/box_layout.h" + +namespace payments { + +ShippingListViewController::ShippingListViewController( + PaymentRequest* request, + PaymentRequestDialogView* dialog) + : PaymentRequestSheetController(request, dialog) {} + +ShippingListViewController::~ShippingListViewController() {} + +std::unique_ptr<views::View> ShippingListViewController::CreateView() { + std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>(); + + views::BoxLayout* layout = + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); + layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); + layout->set_cross_axis_alignment( + views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH); + content_view->SetLayoutManager(layout); + + for (auto& profile : request()->shipping_profiles()) { + // TODO(tmartino): Pass an actual locale in place of empty string. + content_view->AddChildView( + GetShippingAddressLabel(AddressStyleType::DETAILED, std::string(), + *profile) + .release()); + } + + return CreatePaymentView( + CreateSheetHeaderView( + /* show_back_arrow = */ true, + l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_SHIPPING_SECTION_NAME), + this), + std::move(content_view)); +} + +void ShippingListViewController::ButtonPressed(views::Button* sender, + const ui::Event& event) { + switch (sender->tag()) { + case static_cast<int>(PaymentRequestCommonTags::CLOSE_BUTTON_TAG): + dialog()->CloseDialog(); + break; + case static_cast<int>(PaymentRequestCommonTags::BACK_BUTTON_TAG): + dialog()->GoBack(); + break; + default: + NOTREACHED(); + } +} + +} // namespace payments
diff --git a/chrome/browser/ui/views/payments/shipping_list_view_controller.h b/chrome/browser/ui/views/payments/shipping_list_view_controller.h new file mode 100644 index 0000000..9b3d441 --- /dev/null +++ b/chrome/browser/ui/views/payments/shipping_list_view_controller.h
@@ -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. + +#ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_SHIPPING_LIST_VIEW_CONTROLLER_H_ +#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_SHIPPING_LIST_VIEW_CONTROLLER_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/views/payments/payment_request_sheet_controller.h" +#include "ui/views/controls/button/vector_icon_button_delegate.h" + +namespace payments { + +class PaymentRequest; +class PaymentRequestDialogView; + +// The PaymentRequestSheetController subtype for the Shipping address list +// screen of the Payment Request flow. +class ShippingListViewController : public PaymentRequestSheetController, + public views::VectorIconButtonDelegate { + public: + // Does not take ownership of the arguments, which should outlive this object. + ShippingListViewController(PaymentRequest* request, + PaymentRequestDialogView* dialog); + ~ShippingListViewController() override; + + // PaymentRequestSheetController: + std::unique_ptr<views::View> CreateView() override; + + private: + // views::VectorIconButtonDelegate: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + DISALLOW_COPY_AND_ASSIGN(ShippingListViewController); +}; + +} // namespace payments + +#endif // CHROME_BROWSER_UI_VIEWS_PAYMENTS_SHIPPING_LIST_VIEW_CONTROLLER_H_
diff --git a/chrome/renderer/autofill/DEPS b/chrome/renderer/autofill/DEPS deleted file mode 100644 index d7867aa1..0000000 --- a/chrome/renderer/autofill/DEPS +++ /dev/null
@@ -1,7 +0,0 @@ -specific_include_rules = { - # TODO(estark): remove this when the Form-Not-Secure feature is fully - # launched. https://crbug.com/677295 - "password_autofill_agent_browsertest\.cc" : [ - "+components/security_state/core", - ], -} \ No newline at end of file
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index 55aa61a..ae056a5c 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -23,7 +23,6 @@ #include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form_field_prediction_map.h" #include "components/password_manager/core/common/password_manager_features.h" -#include "components/security_state/core/security_state.h" #include "content/public/common/associated_interface_provider.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" @@ -352,11 +351,6 @@ password_manager::features::kFillOnAccountSelect); } - void SetHttpFormWarning() { - scoped_feature_list_.InitAndEnableFeature( - security_state::kHttpFormWarningFeature); - } - void UpdateOriginForHTML(const std::string& html) { std::string origin = "data:text/html;charset=utf-8," + html; fill_data_.origin = GURL(origin); @@ -489,11 +483,6 @@ return fake_driver_.called_show_pw_suggestions(); } - bool GetCalledShowNotSecureWarning() { - base::RunLoop().RunUntilIdle(); - return fake_driver_.called_show_not_secure_warning(); - } - void ExpectFormSubmittedWithUsernameAndPasswords( const std::string& username_value, const std::string& password_value, @@ -1367,30 +1356,6 @@ ClearUsernameAndPasswordFields(); } -// Tests that the Form Not Secure warning appears when a password form -// is autofilled when the Form Not Secure feature is enabled. -TEST_F(PasswordAutofillAgentTest, FormNotSecureWarningOnAutofill) { - SetHttpFormWarning(); - - fill_data_.show_form_not_secure_warning_on_autofill = true; - - // Simulate the browser autofilling a password form. - SimulateOnFillPasswordForm(fill_data_); - EXPECT_TRUE(GetCalledShowNotSecureWarning()); -} - -// Tests that the Form Not Secure warning does not appear when the -// PasswordFormFillData does not indicate that it should show. -TEST_F(PasswordAutofillAgentTest, FormNotSecureWarningNotShownOnAutofill) { - SetHttpFormWarning(); - - fill_data_.show_form_not_secure_warning_on_autofill = false; - - // Simulate the browser autofilling a password form. - SimulateOnFillPasswordForm(fill_data_); - EXPECT_FALSE(GetCalledShowNotSecureWarning()); -} - // Tests that there is an autosuggestion from the password manager when the // user clicks on the password field when FillOnAccountSelect is enabled. TEST_F(PasswordAutofillAgentTest,
diff --git a/chrome/test/data/payments/bobpay.js b/chrome/test/data/payments/bobpay.js index 0d24e9fc..9e4848c6 100644 --- a/chrome/test/data/payments/bobpay.js +++ b/chrome/test/data/payments/bobpay.js
@@ -7,12 +7,13 @@ /* global PaymentRequest:false */ /** - * Launches the PaymentRequest UI with Bob Pay as the only payment method. + * Launches the PaymentRequest UI with Bob Pay as one of multiple payment + * methods. */ function buy() { // eslint-disable-line no-unused-vars try { new PaymentRequest( - [{supportedMethods: ['https://bobpay.com']}], + [{supportedMethods: ['https://bobpay.com', 'https://alicepay.com']}], {total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}}) .show() .then(function(resp) {
diff --git a/chrome/test/data/payments/bobpay_ui_skip.js b/chrome/test/data/payments/bobpay_ui_skip.js new file mode 100644 index 0000000..62b4680 --- /dev/null +++ b/chrome/test/data/payments/bobpay_ui_skip.js
@@ -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. + */ + +/* global PaymentRequest:false */ + +/** + * Launches the PaymentRequest UI with Bob Pay as the only payment method. + * + * <p>When the developer chooses a single payment method and requests no other + * data (no shipping, no email, no phone, ...), Payment Request will apply + * the UI skip optimization, skipping its own UI enterily and going directly to + * Bob Pay. + */ +function buy() { // eslint-disable-line no-unused-vars + try { + new PaymentRequest( + [{supportedMethods: ['https://bobpay.com']}], + {total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}}) + .show() + .then(function(resp) { + resp.complete('success') + .then(function() { + print(resp.methodName + '<br>' + + JSON.stringify(resp.details, undefined, 2)); + }) + .catch(function(error) { + print('complete() rejected<br>' + error); + }); + }) + .catch(function(error) { + print('show() rejected<br>' + error); + }); + } catch (error) { + print('exception thrown<br>' + error); + } +}
diff --git a/chrome/test/data/payments/payment_request_bobpay_ui_skip_test.html b/chrome/test/data/payments/payment_request_bobpay_ui_skip_test.html new file mode 100644 index 0000000..5d179cf7 --- /dev/null +++ b/chrome/test/data/payments/payment_request_bobpay_ui_skip_test.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<!-- +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. +--> +<html> +<head> +<title>Bob Pay UI skip Test</title> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> +<link rel="stylesheet" type="text/css" href="style.css"> +</head> +<body> +<button onclick="buy()" id="buy">Bob Pay Test</button><br> +<pre id="result"></pre> +<script src="util.js"></script> +<script src="bobpay_ui_skip.js"></script> +</body> +</html>
diff --git a/chromeos/dbus/debug_daemon_client.cc b/chromeos/dbus/debug_daemon_client.cc index 868a60f2..c007e2f 100644 --- a/chromeos/dbus/debug_daemon_client.cc +++ b/chromeos/dbus/debug_daemon_client.cc
@@ -466,12 +466,13 @@ weak_ptr_factory_.GetWeakPtr(), callback)); } - void CupsAddPrinter(const std::string& name, - const std::string& uri, - const std::string& ppd_path, - bool ipp_everywhere, - const DebugDaemonClient::CupsAddPrinterCallback& callback, - const base::Closure& error_callback) override { + void CupsAddPrinter( + const std::string& name, + const std::string& uri, + const std::string& ppd_path, + bool ipp_everywhere, + const DebugDaemonClient::LegacyCupsAddPrinterCallback& callback, + const base::Closure& error_callback) override { dbus::MethodCall method_call(debugd::kDebugdInterface, debugd::kCupsAddPrinter); dbus::MessageWriter writer(&method_call); @@ -482,6 +483,42 @@ debugdaemon_proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&DebugDaemonClientImpl::LegacyOnPrinterAdded, + weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); + } + + void CupsAddManuallyConfiguredPrinter( + const std::string& name, + const std::string& uri, + const std::string& ppd_contents, + const DebugDaemonClient::CupsAddPrinterCallback& callback, + const base::Closure& error_callback) override { + dbus::MethodCall method_call(debugd::kDebugdInterface, + debugd::kCupsAddManuallyConfiguredPrinter); + dbus::MessageWriter writer(&method_call); + writer.AppendString(name); + writer.AppendString(uri); + writer.AppendString(ppd_contents); + + debugdaemon_proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&DebugDaemonClientImpl::OnPrinterAdded, + weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); + } + + void CupsAddAutoConfiguredPrinter( + const std::string& name, + const std::string& uri, + const DebugDaemonClient::CupsAddPrinterCallback& callback, + const base::Closure& error_callback) override { + dbus::MethodCall method_call(debugd::kDebugdInterface, + debugd::kCupsAddAutoConfiguredPrinter); + dbus::MessageWriter writer(&method_call); + writer.AppendString(name); + writer.AppendString(uri); + + debugdaemon_proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::Bind(&DebugDaemonClientImpl::OnPrinterAdded, weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); } @@ -713,9 +750,9 @@ callback.Run(false, ""); } - void OnPrinterAdded(const CupsAddPrinterCallback& callback, - const base::Closure& error_callback, - dbus::Response* response) { + void LegacyOnPrinterAdded(const LegacyCupsAddPrinterCallback& callback, + const base::Closure& error_callback, + dbus::Response* response) { bool result = false; dbus::MessageReader reader(response); if (response && reader.PopBool(&result)) { @@ -725,6 +762,18 @@ } } + void OnPrinterAdded(const CupsAddPrinterCallback& callback, + const base::Closure& error_callback, + dbus::Response* response) { + int32_t result; + dbus::MessageReader reader(response); + if (response && reader.PopInt32(&result)) { + callback.Run(result); + } else { + error_callback.Run(); + } + } + void OnPrinterRemoved(const CupsRemovePrinterCallback& callback, const base::Closure& error_callback, dbus::Response* response) {
diff --git a/chromeos/dbus/debug_daemon_client.h b/chromeos/dbus/debug_daemon_client.h index 2a7a3185..4d8541ae 100644 --- a/chromeos/dbus/debug_daemon_client.h +++ b/chromeos/dbus/debug_daemon_client.h
@@ -210,7 +210,12 @@ const SetOomScoreAdjCallback& callback) = 0; // A callback to handle the result of CupsAddPrinter. - using CupsAddPrinterCallback = base::Callback<void(bool success)>; + using LegacyCupsAddPrinterCallback = base::Callback<void(bool status)>; + + // A callback to handle the result of CupsAdd[Auto|Manually]ConfiguredPrinter. + // A zero status means success, non-zero statuses are used to convey different + // errors. + using CupsAddPrinterCallback = base::Callback<void(int32_t status)>; // Calls CupsAddPrinter. |name| is the printer name. |uri| is the device // uri. |ppd_path| is the absolute path to the PPD file. |ipp_everywhere| @@ -218,13 +223,40 @@ // true if adding the printer to CUPS was successful and false if there was an // error. |error_callback| will be called if there was an error in // communicating with debugd. + // + // Obsoleted by CupsAddAutoConfiguredPrinter and + // CupsAddManuallyConfiguredPrinter. virtual void CupsAddPrinter(const std::string& name, const std::string& uri, const std::string& ppd_path, bool ipp_everywhere, - const CupsAddPrinterCallback& callback, + const LegacyCupsAddPrinterCallback& callback, const base::Closure& error_callback) = 0; + // Calls CupsAddManuallyConfiguredPrinter. |name| is the printer + // name. |uri| is the device. |ppd_contents| is the contents of the + // PPD file used to drive the device. |callback| is called with + // true if adding the printer to CUPS was successful and false if + // there was an error. |error_callback| will be called if there was + // an error in communicating with debugd. + virtual void CupsAddManuallyConfiguredPrinter( + const std::string& name, + const std::string& uri, + const std::string& ppd_contents, + const CupsAddPrinterCallback& callback, + const base::Closure& error_callback) = 0; + + // Calls CupsAddAutoConfiguredPrinter. |name| is the printer + // name. |uri| is the device. |callback| is called with true if + // adding the printer to CUPS was successful and false if there was + // an error. |error_callback| will be called if there was an error + // in communicating with debugd. + virtual void CupsAddAutoConfiguredPrinter( + const std::string& name, + const std::string& uri, + const CupsAddPrinterCallback& callback, + const base::Closure& error_callback) = 0; + // A callback to handle the result of CupsRemovePrinter. using CupsRemovePrinterCallback = base::Callback<void(bool success)>;
diff --git a/chromeos/dbus/fake_debug_daemon_client.cc b/chromeos/dbus/fake_debug_daemon_client.cc index a07b18e..20d7498 100644 --- a/chromeos/dbus/fake_debug_daemon_client.cc +++ b/chromeos/dbus/fake_debug_daemon_client.cc
@@ -223,13 +223,34 @@ const std::string& uri, const std::string& ppd_path, bool ipp_everywhere, - const DebugDaemonClient::CupsAddPrinterCallback& callback, + const DebugDaemonClient::LegacyCupsAddPrinterCallback& callback, const base::Closure& error_callback) { printers_.insert(name); base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(callback, true)); } +void FakeDebugDaemonClient::CupsAddManuallyConfiguredPrinter( + const std::string& name, + const std::string& uri, + const std::string& ppd_contents, + const DebugDaemonClient::CupsAddPrinterCallback& callback, + const base::Closure& error_callback) { + printers_.insert(name); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind(callback, 0)); +} + +void FakeDebugDaemonClient::CupsAddAutoConfiguredPrinter( + const std::string& name, + const std::string& uri, + const DebugDaemonClient::CupsAddPrinterCallback& callback, + const base::Closure& error_callback) { + printers_.insert(name); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind(callback, 0)); +} + void FakeDebugDaemonClient::CupsRemovePrinter( const std::string& name, const DebugDaemonClient::CupsRemovePrinterCallback& callback,
diff --git a/chromeos/dbus/fake_debug_daemon_client.h b/chromeos/dbus/fake_debug_daemon_client.h index d008880..00e8dce 100644 --- a/chromeos/dbus/fake_debug_daemon_client.h +++ b/chromeos/dbus/fake_debug_daemon_client.h
@@ -76,8 +76,19 @@ const std::string& uri, const std::string& ppd_path, bool ipp_everywhere, - const CupsAddPrinterCallback& callback, + const LegacyCupsAddPrinterCallback& callback, const base::Closure& error_callback) override; + void CupsAddManuallyConfiguredPrinter( + const std::string& name, + const std::string& uri, + const std::string& ppd_contents, + const CupsAddPrinterCallback& callback, + const base::Closure& error_callback) override; + void CupsAddAutoConfiguredPrinter( + const std::string& name, + const std::string& uri, + const CupsAddPrinterCallback& callback, + const base::Closure& error_callback) override; void CupsRemovePrinter(const std::string& name, const CupsRemovePrinterCallback& callback, const base::Closure& error_callback) override;
diff --git a/components/autofill/content/common/autofill_types.mojom b/components/autofill/content/common/autofill_types.mojom index db88276..9142c617 100644 --- a/components/autofill/content/common/autofill_types.mojom +++ b/components/autofill/content/common/autofill_types.mojom
@@ -140,7 +140,6 @@ array<array<string>> other_possible_usernames_values; bool wait_for_username; bool is_possible_change_password_form; - bool show_form_not_secure_warning_on_autofill; }; // autofill::PasswordFormGenerationData
diff --git a/components/autofill/content/common/autofill_types_struct_traits.cc b/components/autofill/content/common/autofill_types_struct_traits.cc index d3214a1..dce12aa 100644 --- a/components/autofill/content/common/autofill_types_struct_traits.cc +++ b/components/autofill/content/common/autofill_types_struct_traits.cc
@@ -463,8 +463,6 @@ out->wait_for_username = data.wait_for_username(); out->is_possible_change_password_form = data.is_possible_change_password_form(); - out->show_form_not_secure_warning_on_autofill = - data.show_form_not_secure_warning_on_autofill(); return true; }
diff --git a/components/autofill/content/common/autofill_types_struct_traits.h b/components/autofill/content/common/autofill_types_struct_traits.h index a9785e3..ba126b37 100644 --- a/components/autofill/content/common/autofill_types_struct_traits.h +++ b/components/autofill/content/common/autofill_types_struct_traits.h
@@ -355,11 +355,6 @@ return r.is_possible_change_password_form; } - static bool show_form_not_secure_warning_on_autofill( - const autofill::PasswordFormFillData& r) { - return r.show_form_not_secure_warning_on_autofill; - } - static bool Read(autofill::mojom::PasswordFormFillDataDataView data, autofill::PasswordFormFillData* out); };
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 1026178..2d8f6c91 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1278,15 +1278,12 @@ element.isPasswordField() ? element : web_input_to_password_info_[element].password_field; - if (FillFormOnPasswordReceived( - form_data, username_element, password_element, - &field_value_and_properties_map_, - base::Bind(&PasswordValueGatekeeper::RegisterElement, - base::Unretained(&gatekeeper_)), - logger.get())) { - if (form_data.show_form_not_secure_warning_on_autofill) - autofill_agent_->ShowNotSecureWarning(element); - } + FillFormOnPasswordReceived( + form_data, username_element, password_element, + &field_value_and_properties_map_, + base::Bind(&PasswordValueGatekeeper::RegisterElement, + base::Unretained(&gatekeeper_)), + logger.get()); } }
diff --git a/components/autofill/core/common/password_form_fill_data.cc b/components/autofill/core/common/password_form_fill_data.cc index 014a24e..9b138304 100644 --- a/components/autofill/core/common/password_form_fill_data.cc +++ b/components/autofill/core/common/password_form_fill_data.cc
@@ -22,9 +22,7 @@ } PasswordFormFillData::PasswordFormFillData() - : wait_for_username(false), - is_possible_change_password_form(false), - show_form_not_secure_warning_on_autofill(false) {} + : wait_for_username(false), is_possible_change_password_form(false) {} PasswordFormFillData::PasswordFormFillData(const PasswordFormFillData& other) = default;
diff --git a/components/autofill/core/common/password_form_fill_data.h b/components/autofill/core/common/password_form_fill_data.h index 91798eda..fd0f64fe 100644 --- a/components/autofill/core/common/password_form_fill_data.h +++ b/components/autofill/core/common/password_form_fill_data.h
@@ -75,10 +75,6 @@ // True if this form is a change password form. bool is_possible_change_password_form; - // True if a "form not secure" warning should be shown when the form is - // autofilled. - bool show_form_not_secure_warning_on_autofill; - PasswordFormFillData(); PasswordFormFillData(const PasswordFormFillData& other); ~PasswordFormFillData();
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index b17acf44..6c7488b 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -69,7 +69,6 @@ #include "components/sync/js/js_event_details.h" #include "components/sync/model/change_processor.h" #include "components/sync/model/model_type_change_processor.h" -#include "components/sync/model/model_type_store.h" #include "components/sync/model/sync_error.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/syncable/directory.h" @@ -193,7 +192,7 @@ network_time_update_callback_( std::move(init_params.network_time_update_callback)), url_request_context_(init_params.url_request_context), - blocking_pool_(init_params.blocking_pool), + blocking_task_runner_(std::move(init_params.blocking_task_runner)), is_first_time_sync_configure_(false), engine_initialized_(false), sync_disabled_by_admin_(false), @@ -274,19 +273,11 @@ syncer::ModelTypeSet(syncer::SESSIONS))); if (base::FeatureList::IsEnabled(switches::kSyncUSSDeviceInfo)) { - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner( - blocking_pool_->GetSequencedTaskRunnerWithShutdownBehavior( - blocking_pool_->GetSequenceToken(), - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); // TODO(skym): Stop creating leveldb files when signed out. // TODO(skym): Verify using AsUTF8Unsafe is okay here. Should work as long // as the Local State file is guaranteed to be UTF-8. device_info_sync_bridge_ = base::MakeUnique<DeviceInfoSyncBridge>( - local_device_.get(), - base::Bind(&ModelTypeStore::CreateStore, syncer::DEVICE_INFO, - sync_data_folder_.Append(base::FilePath(kLevelDBFolderName)) - .AsUTF8Unsafe(), - blocking_task_runner), + local_device_.get(), GetModelTypeStoreFactory(syncer::DEVICE_INFO), base::BindRepeating( &ModelTypeChangeProcessor::Create, base::BindRepeating(&syncer::ReportUnrecoverableError, channel_))); @@ -974,7 +965,7 @@ // Initialize local device info. local_device_->Initialize(cache_guid, signin_scoped_device_id, - blocking_pool_); + blocking_task_runner_); if (protocol_event_observers_.might_have_observers()) { engine_->RequestBufferedProtocolEventsAndEnableForwarding(); @@ -1823,6 +1814,14 @@ platform_sync_allowed_provider_ = platform_sync_allowed_provider; } +syncer::ModelTypeStoreFactory ProfileSyncService::GetModelTypeStoreFactory( + ModelType type) { + return base::Bind(&ModelTypeStore::CreateStore, type, + sync_data_folder_.Append(base::FilePath(kLevelDBFolderName)) + .AsUTF8Unsafe(), + blocking_task_runner_); +} + void ProfileSyncService::ConfigureDataTypeManager() { // Don't configure datatypes if the setup UI is still on the screen - this // is to help multi-screen setting UIs (like iOS) where they don't want to
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h index 43c8f8b..9d7c709 100644 --- a/components/browser_sync/profile_sync_service.h +++ b/components/browser_sync/profile_sync_service.h
@@ -49,6 +49,7 @@ #include "components/sync/engine/sync_engine_host.h" #include "components/sync/engine/sync_manager_factory.h" #include "components/sync/js/sync_js_controller.h" +#include "components/sync/model/model_type_store.h" #include "components/sync/syncable/user_share.h" #include "components/version_info/version_info.h" #include "google_apis/gaia/google_service_auth_error.h" @@ -244,7 +245,7 @@ scoped_refptr<net::URLRequestContextGetter> url_request_context; std::string debug_identifier; version_info::Channel channel = version_info::Channel::UNKNOWN; - base::SequencedWorkerPool* blocking_pool = nullptr; + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner; base::FilePath local_sync_backend_folder; private: @@ -580,6 +581,11 @@ void SetPlatformSyncAllowedProvider( const PlatformSyncAllowedProvider& platform_sync_allowed_provider); + // Returns a function for |type| that will create a ModelTypeStore that shares + // the sync LevelDB backend. + syncer::ModelTypeStoreFactory GetModelTypeStoreFactory( + syncer::ModelType type); + // Needed to test whether the directory is deleted properly. base::FilePath GetDirectoryPathForTest() const; @@ -793,8 +799,8 @@ // The request context in which sync should operate. scoped_refptr<net::URLRequestContextGetter> url_request_context_; - // Threading context. - base::SequencedWorkerPool* blocking_pool_; + // The task runner to use for blocking IO operations. + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; // Indicates if this is the first time sync is being configured. This value // is equal to !IsFirstSetupComplete() at the time of OnEngineInitialized().
diff --git a/components/browser_sync/profile_sync_test_util.cc b/components/browser_sync/profile_sync_test_util.cc index f9f8355d..c6d34511 100644 --- a/components/browser_sync/profile_sync_test_util.cc +++ b/components/browser_sync/profile_sync_test_util.cc
@@ -261,7 +261,10 @@ init_params.url_request_context = url_request_context(); init_params.debug_identifier = "dummyDebugName"; init_params.channel = version_info::Channel::UNKNOWN; - init_params.blocking_pool = worker_pool_owner_.pool().get(); + init_params.blocking_task_runner = + worker_pool_owner_.pool()->GetSequencedTaskRunnerWithShutdownBehavior( + worker_pool_owner_.pool()->GetSequenceToken(), + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); return init_params; }
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index a91c1822..be93b49 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -39,7 +39,6 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_service.h" -#include "components/security_state/core/security_state.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -2866,41 +2865,4 @@ } } -class PasswordFormManagerFormNotSecureTest : public PasswordFormManagerTest { - public: - PasswordFormManagerFormNotSecureTest() { - scoped_feature_list_.InitAndEnableFeature( - security_state::kHttpFormWarningFeature); - } - - base::test::ScopedFeatureList scoped_feature_list_; -}; - -// Tests that PasswordFormFillData's -// |show_form_not_secure_warning_on_autofill| field is set correctly -// when processing a frame. -TEST_F(PasswordFormManagerFormNotSecureTest, - ProcessFrameSetsFormNotSecureFlag) { - autofill::PasswordFormFillData fill_data; - EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_)) - .WillOnce(SaveArg<0>(&fill_data)); - fake_form_fetcher()->SetNonFederated({saved_match()}, 0u); - EXPECT_TRUE(fill_data.show_form_not_secure_warning_on_autofill); -} - -// Tests that PasswordFormFillData's -// |show_form_not_secure_warning_on_autofill| field is *not* set when -// the feature is not enabled. -// -// TODO(estark): remove this test when the feature is fully -// launched. https://crbug.com/677295 -TEST_F(PasswordFormManagerTest, - ProcessFrameSetsFormNotSecureFlagWithoutFeature) { - autofill::PasswordFormFillData fill_data; - EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_)) - .WillOnce(SaveArg<0>(&fill_data)); - fake_form_fetcher()->SetNonFederated({saved_match()}, 0u); - EXPECT_FALSE(fill_data.show_form_not_secure_warning_on_autofill); -} - } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index a2bbaf12..acb0e8dc 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -16,7 +16,6 @@ #include "base/threading/platform_thread.h" #include "build/build_config.h" #include "components/autofill/core/browser/autofill_field.h" -#include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/common/form_data_predictions.h" #include "components/autofill/core/common/password_form_field_prediction_map.h" @@ -35,7 +34,6 @@ #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" -#include "components/security_state/core/security_state.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #if defined(OS_WIN) @@ -782,16 +780,6 @@ InitPasswordFormFillData(form_for_autofill, best_matches, &preferred_match, wait_for_username, OtherPossibleUsernamesEnabled(), &fill_data); - // Show a "Login not secure" warning if the experiment is enabled and the - // top-level page is not secure. - // TODO(estark): Verify that |origin| is the right URL to check here. - // https://crbug.com/676706 - autofill::AutofillManager* autofill_manager = - client_->GetAutofillManagerForMainFrame(); - fill_data.show_form_not_secure_warning_on_autofill = - security_state::IsHttpWarningInFormEnabled() && autofill_manager && - !autofill_manager->client()->IsContextSecure(fill_data.origin); - if (logger) logger->LogBoolean(Logger::STRING_WAIT_FOR_USERNAME, wait_for_username); UMA_HISTOGRAM_BOOLEAN(
diff --git a/components/payments/payment_request.cc b/components/payments/payment_request.cc index 2fa4910..d7302df 100644 --- a/components/payments/payment_request.cc +++ b/components/payments/payment_request.cc
@@ -22,7 +22,9 @@ : web_contents_(web_contents), delegate_(std::move(delegate)), manager_(manager), - binding_(this, std::move(request)) { + binding_(this, std::move(request)), + selected_shipping_profile_(nullptr), + selected_contact_profile_(nullptr) { // OnConnectionTerminated will be called when the Mojo pipe is closed. This // will happen as a result of many renderer-side events (both successful and // erroneous in nature). @@ -30,6 +32,7 @@ // set_connection_error_with_reason_handler with Binding::CloseWithReason. binding_.set_connection_error_handler(base::Bind( &PaymentRequest::OnConnectionTerminated, base::Unretained(this))); + } PaymentRequest::~PaymentRequest() {} @@ -48,6 +51,8 @@ } client_ = std::move(client); details_ = std::move(details); + PopulateProfileCache(); + SetDefaultProfileSelections(); } void PaymentRequest::Show() { @@ -105,17 +110,14 @@ return currency_formatter_.get(); } -autofill::AutofillProfile* PaymentRequest::GetCurrentlySelectedProfile() { - // TODO(tmartino): Implement more sophisticated algorithm for populating - // this when it starts empty. - if (!profile_) { - autofill::PersonalDataManager* data_manager = - delegate_->GetPersonalDataManager(); - auto profiles = data_manager->GetProfiles(); - if (!profiles.empty()) - profile_ = base::MakeUnique<autofill::AutofillProfile>(*profiles[0]); - } - return profile_ ? profile_.get() : nullptr; +const std::vector<autofill::AutofillProfile*>& + PaymentRequest::shipping_profiles() { + return shipping_profiles_; +} + +const std::vector<autofill::AutofillProfile*>& + PaymentRequest::contact_profiles() { + return contact_profiles_; } autofill::CreditCard* PaymentRequest::GetCurrentlySelectedCreditCard() { @@ -137,4 +139,32 @@ return first_complete_card == cards.end() ? nullptr : *first_complete_card; } +void PaymentRequest::PopulateProfileCache() { + autofill::PersonalDataManager* data_manager = + delegate_->GetPersonalDataManager(); + std::vector<autofill::AutofillProfile*> profiles = + data_manager->GetProfilesToSuggest(); + + // PaymentRequest may outlive the Profiles returned by the Data Manager. + // Thus, we store copies, and return a vector of pointers to these copies + // whenever Profiles are requested. + for (size_t i = 0; i < profiles.size(); i++) { + profile_cache_.push_back( + base::MakeUnique<autofill::AutofillProfile>(*profiles[i])); + + // TODO(tmartino): Implement deduplication rules specific to shipping and + // contact profiles. + shipping_profiles_.push_back(profile_cache_[i].get()); + contact_profiles_.push_back(profile_cache_[i].get()); + } +} + +void PaymentRequest::SetDefaultProfileSelections() { + if (!shipping_profiles().empty()) + set_selected_shipping_profile(shipping_profiles()[0]); + + if (!contact_profiles().empty()) + set_selected_contact_profile(contact_profiles()[0]); +} + } // namespace payments
diff --git a/components/payments/payment_request.h b/components/payments/payment_request.h index cbc9905..a2caab9 100644 --- a/components/payments/payment_request.h +++ b/components/payments/payment_request.h
@@ -67,12 +67,28 @@ const std::string& currency_system, const std::string& locale_name); - // Returns the Autofill Profile, representing the shipping address and contact - // information, currently selected for this PaymentRequest flow. If - // unpopulated, populates with and returns the 0th profile on record for this - // user, if it exists; or nullptr otherwise. Profile is owned by the request - // object, not the caller. - autofill::AutofillProfile* GetCurrentlySelectedProfile(); + // Returns the appropriate Autofill Profiles for this user. On the first + // invocation of either getter, the profiles are fetched from the + // PersonalDataManager; on subsequent invocations, a cached version is + // returned. The profiles returned are owned by the request object. + const std::vector<autofill::AutofillProfile*>& shipping_profiles(); + const std::vector<autofill::AutofillProfile*>& contact_profiles(); + + // Gets/sets the Autofill Profile representing the shipping address or contact + // information currently selected for this PaymentRequest flow. Can return + // null. + autofill::AutofillProfile* selected_shipping_profile() const { + return selected_shipping_profile_; + } + void set_selected_shipping_profile(autofill::AutofillProfile* profile) { + selected_shipping_profile_ = profile; + } + autofill::AutofillProfile* selected_contact_profile() const { + return selected_contact_profile_; + } + void set_selected_contact_profile(autofill::AutofillProfile* profile) { + selected_contact_profile_ = profile; + } // Returns the currently selected credit card for this PaymentRequest flow. // It's not guaranteed to be complete. Returns nullptr if there is no selected @@ -83,6 +99,13 @@ content::WebContents* web_contents() { return web_contents_; } private: + // Fetches the Autofill Profiles for this user from the PersonalDataManager, + // and stores copies of them, owned by this Request, in profile_cache_. + void PopulateProfileCache(); + + // Sets the default values for the selected Shipping and Contact profiles. + void SetDefaultProfileSelections(); + content::WebContents* web_contents_; std::unique_ptr<PaymentRequestDelegate> delegate_; // |manager_| owns this PaymentRequest. @@ -91,7 +114,15 @@ payments::mojom::PaymentRequestClientPtr client_; payments::mojom::PaymentDetailsPtr details_; std::unique_ptr<CurrencyFormatter> currency_formatter_; - std::unique_ptr<autofill::AutofillProfile> profile_; + + // Profiles may change due to (e.g.) sync events, so profiles are cached after + // loading and owned here. They are populated once only, and ordered by + // frecency. + std::vector<std::unique_ptr<autofill::AutofillProfile>> profile_cache_; + std::vector<autofill::AutofillProfile*> shipping_profiles_; + std::vector<autofill::AutofillProfile*> contact_profiles_; + autofill::AutofillProfile* selected_shipping_profile_; + autofill::AutofillProfile* selected_contact_profile_; DISALLOW_COPY_AND_ASSIGN(PaymentRequest); };
diff --git a/components/sync/device_info/device_info_sync_bridge.cc b/components/sync/device_info/device_info_sync_bridge.cc index 0ba09e3..9490815 100644 --- a/components/sync/device_info/device_info_sync_bridge.cc +++ b/components/sync/device_info/device_info_sync_bridge.cc
@@ -86,7 +86,7 @@ DeviceInfoSyncBridge::DeviceInfoSyncBridge( LocalDeviceInfoProvider* local_device_info_provider, - const StoreFactoryFunction& callback, + const ModelTypeStoreFactory& store_factory, const ChangeProcessorFactory& change_processor_factory) : ModelTypeSyncBridge(change_processor_factory, DEVICE_INFO), local_device_info_provider_(local_device_info_provider) { @@ -102,7 +102,7 @@ base::Unretained(this))); } - callback.Run( + store_factory.Run( base::Bind(&DeviceInfoSyncBridge::OnStoreCreated, base::AsWeakPtr(this))); }
diff --git a/components/sync/device_info/device_info_sync_bridge.h b/components/sync/device_info/device_info_sync_bridge.h index 2634df0..1ddbb2b 100644 --- a/components/sync/device_info/device_info_sync_bridge.h +++ b/components/sync/device_info/device_info_sync_bridge.h
@@ -34,11 +34,8 @@ class DeviceInfoSyncBridge : public ModelTypeSyncBridge, public DeviceInfoTracker { public: - typedef base::Callback<void(const ModelTypeStore::InitCallback& callback)> - StoreFactoryFunction; - DeviceInfoSyncBridge(LocalDeviceInfoProvider* local_device_info_provider, - const StoreFactoryFunction& callback, + const ModelTypeStoreFactory& store_factory, const ChangeProcessorFactory& change_processor_factory); ~DeviceInfoSyncBridge() override;
diff --git a/components/sync/model/model_type_store.h b/components/sync/model/model_type_store.h index d640c9e..dfe9e3fa 100644 --- a/components/sync/model/model_type_store.h +++ b/components/sync/model/model_type_store.h
@@ -195,6 +195,10 @@ // It will delete all metadata records and global metadata record. }; +// Typedef for a store factory that has all params bound except InitCallback. +using ModelTypeStoreFactory = + base::Callback<void(const ModelTypeStore::InitCallback&)>; + } // namespace syncer #endif // COMPONENTS_SYNC_MODEL_MODEL_TYPE_STORE_H_
diff --git a/components/translate/core/browser/language_model.cc b/components/translate/core/browser/language_model.cc index 6c575499..6899b38 100644 --- a/components/translate/core/browser/language_model.cc +++ b/components/translate/core/browser/language_model.cc
@@ -132,4 +132,14 @@ DiscountAndCleanCounters(dict); } +void LanguageModel::ClearHistory(base::Time begin, base::Time end) { + // Ignore all partial removals and react only to "entire" history removal. + bool is_entire_history = (begin == base::Time() && end == base::Time::Max()); + if (!is_entire_history) { + return; + } + + pref_service_->ClearPref(kLanguageModelCounters); +} + } // namespace translate
diff --git a/components/translate/core/browser/language_model.h b/components/translate/core/browser/language_model.h index 1dc7436..b6547f0 100644 --- a/components/translate/core/browser/language_model.h +++ b/components/translate/core/browser/language_model.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/macros.h" +#include "base/time/time.h" #include "components/keyed_service/core/keyed_service.h" class PrefRegistrySimple; @@ -56,6 +57,9 @@ // Informs the model that a page with the given language has been visited. void OnPageVisited(const std::string& language_code); + // Reflect in the model that history from |begin| to |end| gets cleared. + void ClearHistory(base::Time begin, base::Time end); + private: PrefService* pref_service_;
diff --git a/components/translate/core/browser/language_model_unittest.cc b/components/translate/core/browser/language_model_unittest.cc index df8b6ba..f59a31b 100644 --- a/components/translate/core/browser/language_model_unittest.cc +++ b/components/translate/core/browser/language_model_unittest.cc
@@ -11,6 +11,7 @@ using testing::ElementsAre; using testing::FloatEq; using testing::Gt; +using testing::SizeIs; namespace { @@ -105,4 +106,42 @@ ElementsAre(LanguageModel::LanguageInfo{kLang1, 1})); } +TEST(LanguageModelTest, ShouldClearHistoryIfAllTimes) { + TestingPrefServiceSimple prefs; + LanguageModel::RegisterProfilePrefs(prefs.registry()); + LanguageModel model(&prefs); + + for (int i = 0; i < 100; i++) { + model.OnPageVisited(kLang1); + } + + EXPECT_THAT(model.GetTopLanguages(), SizeIs(1)); + EXPECT_THAT(model.GetLanguageFrequency(kLang1), FloatEq(1.0)); + + model.ClearHistory(base::Time(), base::Time::Max()); + + EXPECT_THAT(model.GetTopLanguages(), SizeIs(0)); + EXPECT_THAT(model.GetLanguageFrequency(kLang1), FloatEq(0.0)); +} + +TEST(LanguageModelTest, ShouldNotClearHistoryIfNotAllTimes) { + TestingPrefServiceSimple prefs; + LanguageModel::RegisterProfilePrefs(prefs.registry()); + LanguageModel model(&prefs); + + for (int i = 0; i < 100; i++) { + model.OnPageVisited(kLang1); + } + + EXPECT_THAT(model.GetTopLanguages(), SizeIs(1)); + EXPECT_THAT(model.GetLanguageFrequency(kLang1), FloatEq(1.0)); + + // Clearing only the last hour of the history has no effect. + model.ClearHistory(base::Time::Now() - base::TimeDelta::FromHours(2), + base::Time::Max()); + + EXPECT_THAT(model.GetTopLanguages(), SizeIs(1)); + EXPECT_THAT(model.GetLanguageFrequency(kLang1), FloatEq(1.0)); +} + } // namespace translate
diff --git a/content/browser/frame_host/frame_navigation_entry.cc b/content/browser/frame_host/frame_navigation_entry.cc index 5ebb6c2..3a46ef6f 100644 --- a/content/browser/frame_host/frame_navigation_entry.cc +++ b/content/browser/frame_host/frame_navigation_entry.cc
@@ -99,7 +99,6 @@ scoped_refptr<ResourceRequestBodyImpl> FrameNavigationEntry::GetPostData() const { - DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries()); if (method_ != "POST") return nullptr;
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 8b528d0..23de865 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -721,16 +721,14 @@ // Update the FTN ID to use below in case we found a named frame. frame_tree_node_id = node->frame_tree_node_id(); - // In --site-per-process, create an identical NavigationEntry with a - // new FrameNavigationEntry for the target subframe. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - entry = GetLastCommittedEntry()->Clone(); - entry->AddOrUpdateFrameEntry( - node, -1, -1, nullptr, - static_cast<SiteInstanceImpl*>(params.source_site_instance.get()), - params.url, params.referrer, params.redirect_chain, PageState(), - "GET", -1); - } + // Create an identical NavigationEntry with a new FrameNavigationEntry for + // the target subframe. + entry = GetLastCommittedEntry()->Clone(); + entry->AddOrUpdateFrameEntry( + node, -1, -1, nullptr, + static_cast<SiteInstanceImpl*>(params.source_site_instance.get()), + params.url, params.referrer, params.redirect_chain, PageState(), + "GET", -1); } } @@ -867,11 +865,10 @@ break; case NAVIGATION_TYPE_AUTO_SUBFRAME: if (!RendererDidNavigateAutoSubframe(rfh, params)) { - // In UseSubframeNavigationEntries mode, we won't send a notification - // about auto-subframe PageState during UpdateStateForFrame, since it - // looks like nothing has changed. Send it here at commit time instead. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) - NotifyEntryChanged(GetLastCommittedEntry()); + // We don't send a notification about auto-subframe PageState during + // UpdateStateForFrame, since it looks like nothing has changed. Send + // it here at commit time instead. + NotifyEntryChanged(GetLastCommittedEntry()); return false; } break; @@ -916,17 +913,12 @@ FrameNavigationEntry* frame_entry = active_entry->GetFrameEntry(rfh->frame_tree_node()); - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - // Update the frame-specific PageState and RedirectChain - // We may not find a frame_entry in some cases; ignore the PageState if so. - // TODO(creis): Remove the "if" once https://crbug.com/522193 is fixed. - if (frame_entry) { - frame_entry->SetPageState(params.page_state); - frame_entry->set_redirect_chain(params.redirects); - } - } else { - active_entry->SetPageState(params.page_state); - active_entry->SetRedirectChain(params.redirects); + // Update the frame-specific PageState and RedirectChain + // We may not find a frame_entry in some cases; ignore the PageState if so. + // TODO(creis): Remove the "if" once https://crbug.com/522193 is fixed. + if (frame_entry) { + frame_entry->SetPageState(params.page_state); + frame_entry->set_redirect_chain(params.redirects); } // Use histogram to track memory impact of redirect chain because it's now @@ -1343,24 +1335,20 @@ DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " << "that a last committed entry exists."; - std::unique_ptr<NavigationEntryImpl> new_entry; - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - // Make sure we don't leak frame_entry if new_entry doesn't take ownership. - scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry( - params.frame_unique_name, params.item_sequence_number, - params.document_sequence_number, rfh->GetSiteInstance(), nullptr, - params.url, params.referrer, params.method, params.post_id)); - new_entry = GetLastCommittedEntry()->CloneAndReplace( - frame_entry.get(), is_in_page, rfh->frame_tree_node(), - delegate_->GetFrameTree()->root()); + // Make sure we don't leak frame_entry if new_entry doesn't take ownership. + scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry( + params.frame_unique_name, params.item_sequence_number, + params.document_sequence_number, rfh->GetSiteInstance(), nullptr, + params.url, params.referrer, params.method, params.post_id)); + std::unique_ptr<NavigationEntryImpl> new_entry = + GetLastCommittedEntry()->CloneAndReplace( + frame_entry.get(), is_in_page, rfh->frame_tree_node(), + delegate_->GetFrameTree()->root()); - // TODO(creis): Update this to add the frame_entry if we can't find the one - // to replace, which can happen due to a unique name change. See - // https://crbug.com/607205. For now, frame_entry will be deleted when it - // goes out of scope if it doesn't get used. - } else { - new_entry = GetLastCommittedEntry()->Clone(); - } + // TODO(creis): Update this to add the frame_entry if we can't find the one + // to replace, which can happen due to a unique name change. See + // https://crbug.com/607205. For now, frame_entry will be deleted when it + // goes out of scope if it doesn't get used. InsertOrReplaceEntry(std::move(new_entry), replace_entry); } @@ -1413,16 +1401,14 @@ } } - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - // This may be a "new auto" case where we add a new FrameNavigationEntry, or - // it may be a "history auto" case where we update an existing one. - NavigationEntryImpl* last_committed = GetLastCommittedEntry(); - last_committed->AddOrUpdateFrameEntry( - rfh->frame_tree_node(), params.item_sequence_number, - params.document_sequence_number, rfh->GetSiteInstance(), nullptr, - params.url, params.referrer, params.redirects, params.page_state, - params.method, params.post_id); - } + // This may be a "new auto" case where we add a new FrameNavigationEntry, or + // it may be a "history auto" case where we update an existing one. + NavigationEntryImpl* last_committed = GetLastCommittedEntry(); + last_committed->AddOrUpdateFrameEntry( + rfh->frame_tree_node(), params.item_sequence_number, + params.document_sequence_number, rfh->GetSiteInstance(), nullptr, + params.url, params.referrer, params.redirects, params.page_state, + params.method, params.post_id); return send_commit_notification; } @@ -1896,23 +1882,8 @@ DCHECK(pending_entry_); FrameTreeNode* root = delegate_->GetFrameTree()->root(); - // In default Chrome, there are no subframe FrameNavigationEntries. Either - // navigate the main frame or use the main frame's FrameNavigationEntry to - // tell the indicated frame where to go. - if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) { - FrameNavigationEntry* frame_entry = GetPendingEntry()->GetFrameEntry(root); - FrameTreeNode* frame = root; - int ftn_id = GetPendingEntry()->frame_tree_node_id(); - if (ftn_id != -1) { - frame = delegate_->GetFrameTree()->FindByID(ftn_id); - DCHECK(frame); - } - return frame->navigator()->NavigateToPendingEntry(frame, *frame_entry, - reload_type, false); - } - - // In --site-per-process, we compare FrameNavigationEntries to see which - // frames in the tree need to be navigated. + // Compare FrameNavigationEntries to see which frames in the tree need to be + // navigated. FrameLoadVector same_document_loads; FrameLoadVector different_document_loads; if (GetLastCommittedEntry()) {
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 86a2aec..b528804 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -355,11 +355,6 @@ } void NavigationEntryImpl::SetPageState(const PageState& state) { - if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) { - frame_tree_->frame_entry->SetPageState(state); - return; - } - // SetPageState should only be called before the NavigationEntry has been // loaded, such as for restore (when there are no subframe // FrameNavigationEntries yet). However, some callers expect to call this @@ -387,10 +382,9 @@ } PageState NavigationEntryImpl::GetPageState() const { - // Just return the main frame's PageState in default Chrome, or if there are - // no subframe FrameNavigationEntries. - if (!SiteIsolationPolicy::UseSubframeNavigationEntries() || - frame_tree_->children.size() == 0U) + // Just return the main frame's state if there are no subframe + // FrameNavigationEntries. + if (frame_tree_->children.size() == 0U) return frame_tree_->frame_entry->page_state(); // When we're using subframe entries, each FrameNavigationEntry has a
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 4483572..1927b1c 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -751,8 +751,7 @@ // Send the navigation to the current FrameTreeNode if it's destined for a // subframe in the current tab. We'll assume it's for the main frame // (possibly of a new or different WebContents) otherwise. - if (SiteIsolationPolicy::UseSubframeNavigationEntries() && - disposition == WindowOpenDisposition::CURRENT_TAB && + if (disposition == WindowOpenDisposition::CURRENT_TAB && render_frame_host->GetParent()) { frame_tree_node_id = render_frame_host->frame_tree_node()->frame_tree_node_id(); @@ -867,7 +866,6 @@ std::unique_ptr<NavigationEntryImpl> entry; if (!node->IsMainFrame()) { // Subframe case: create FrameNavigationEntry. - CHECK(SiteIsolationPolicy::UseSubframeNavigationEntries()); if (controller_->GetLastCommittedEntry()) { entry = controller_->GetLastCommittedEntry()->Clone(); entry->set_extra_headers(extra_headers);
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index a564e6b..7424a5b 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1067,8 +1067,6 @@ GetProcess()->FilterURL(false, &validated_url); if (params.is_history_navigation_in_new_child) { - DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries()); - // Try to find a FrameNavigationEntry that matches this frame instead, based // on the frame's unique name. If this can't be found, fall back to the // default params using RequestOpenURL below.
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h index 2e1dda41..7dc40c3 100644 --- a/content/browser/renderer_host/render_view_host_delegate.h +++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -32,7 +32,6 @@ class BrowserContext; class FrameTree; -class PageState; class RenderViewHost; class RenderViewHostImpl; class RenderViewHostDelegateView; @@ -85,10 +84,6 @@ // RenderView is going to be destroyed virtual void RenderViewDeleted(RenderViewHost* render_view_host) {} - // The state for the page changed and should be updated. - virtual void UpdateState(RenderViewHost* render_view_host, - const PageState& state) {} - // The destination URL has changed should be updated. virtual void UpdateTargetURL(RenderViewHost* render_view_host, const GURL& url) {}
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 6cca925..0ada79d 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -769,7 +769,6 @@ IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget, OnShowFullscreenWidget) - IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateState, OnUpdateState) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL) IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose) IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove) @@ -833,20 +832,6 @@ // decoupled. } -void RenderViewHostImpl::OnUpdateState(const PageState& state) { - // Without this check, the renderer can trick the browser into using - // filenames it can't access in a future session restore. - auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - int child_id = GetProcess()->GetID(); - if (!policy->CanReadAllFiles(child_id, state.GetReferencedFiles())) { - bad_message::ReceivedBadMessage( - GetProcess(), bad_message::RVH_CAN_ACCESS_FILES_OF_PAGE_STATE); - return; - } - - delegate_->UpdateState(this, state); -} - void RenderViewHostImpl::OnUpdateTargetURL(const GURL& url) { if (is_active_) delegate_->UpdateTargetURL(this, url);
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index 88b7ea9a..cb30e86 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -35,7 +35,6 @@ namespace content { -class PageState; struct FrameReplicationState; // This implements the RenderViewHost interface that is exposed to @@ -233,7 +232,6 @@ void OnShowWidget(int route_id, const gfx::Rect& initial_rect); void OnShowFullscreenWidget(int route_id); void OnRenderProcessGone(int status, int error_code); - void OnUpdateState(const PageState& state); void OnUpdateTargetURL(const GURL& url); void OnClose(); void OnRequestMove(const gfx::Rect& pos);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 2f2051fc..592bad2 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -2275,13 +2275,12 @@ GURL url_a = child->current_url(); // Disable host resolution in the test server and try to navigate the subframe - // cross-site, which will lead to a committed net error (which looks like - // success to the TestNavigationObserver). + // cross-site, which will lead to a committed net error. GURL url_b = embedded_test_server()->GetURL("b.com", "/title3.html"); host_resolver()->ClearRules(); TestNavigationObserver observer(shell()->web_contents()); NavigateIframeToURL(shell()->web_contents(), "child-0", url_b); - EXPECT_TRUE(observer.last_navigation_succeeded()); + EXPECT_FALSE(observer.last_navigation_succeeded()); EXPECT_EQ(url_b, observer.last_navigation_url()); EXPECT_EQ(2, shell()->web_contents()->GetController().GetEntryCount());
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 95a4592..5de41501 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4392,33 +4392,6 @@ observer.RenderViewDeleted(rvh); } -void WebContentsImpl::UpdateState(RenderViewHost* rvh, - const PageState& page_state) { - DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries()); - - // Ensure that this state update comes from a RenderViewHost that belongs to - // this WebContents. - // TODO(nasko): This should go through RenderFrameHost. - if (rvh->GetDelegate()->GetAsWebContents() != this) - return; - - if (!rvh->GetMainFrame()) { - // When UseSubframeNavigationEntries is turned off, state updates only come - // in on main frames. When UseSubframeNavigationEntries is turned on, - // UpdateStateForFrame() should have been called rather than this function. - NOTREACHED(); - return; - } - - NavigationEntryImpl* entry = controller_.GetEntryWithUniqueID( - static_cast<RenderFrameHostImpl*>(rvh->GetMainFrame())->nav_entry_id()); - - if (page_state == entry->GetPageState()) - return; // Nothing to update. - entry->SetPageState(page_state); - controller_.NotifyEntryChanged(entry); -} - void WebContentsImpl::UpdateTargetURL(RenderViewHost* render_view_host, const GURL& url) { if (fullscreen_widget_routing_id_ != MSG_ROUTING_NONE) { @@ -4584,8 +4557,6 @@ void WebContentsImpl::UpdateStateForFrame(RenderFrameHost* render_frame_host, const PageState& page_state) { - DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries()); - // The state update affects the last NavigationEntry associated with the given // |render_frame_host|. This may not be the last committed NavigationEntry (as // in the case of an UpdateState from a frame being swapped out). We track
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index fcd0937..ab1c9e7 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -515,8 +515,6 @@ base::TerminationStatus status, int error_code) override; void RenderViewDeleted(RenderViewHost* render_view_host) override; - void UpdateState(RenderViewHost* render_view_host, - const PageState& page_state) override; void UpdateTargetURL(RenderViewHost* render_view_host, const GURL& url) override; void Close(RenderViewHost* render_view_host) override;
diff --git a/content/common/site_isolation_policy.cc b/content/common/site_isolation_policy.cc index 015940a..5a47487 100644 --- a/content/common/site_isolation_policy.cc +++ b/content/common/site_isolation_policy.cc
@@ -38,9 +38,4 @@ switches::kTopDocumentIsolation); } -// static -bool SiteIsolationPolicy::UseSubframeNavigationEntries() { - return true; -} - } // namespace content
diff --git a/content/common/site_isolation_policy.h b/content/common/site_isolation_policy.h index c6d6e61..3e70f64 100644 --- a/content/common/site_isolation_policy.h +++ b/content/common/site_isolation_policy.h
@@ -41,12 +41,6 @@ // different process from the main frame. static bool IsTopDocumentIsolationEnabled(); - // Returns true if navigation and history code should maintain per-frame - // navigation entries. This is an in-progress feature related to site - // isolation, so the return value is currently tied to --site-per-process. - // TODO(creis, avi): Make this the default, and eliminate this. - static bool UseSubframeNavigationEntries(); - private: SiteIsolationPolicy(); // Not instantiable.
diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc index 0b19611..233d07d 100644 --- a/content/common/swapped_out_messages.cc +++ b/content/common/swapped_out_messages.cc
@@ -58,8 +58,6 @@ // Note that synchronous messages that are not handled will receive an // error reply instead, to avoid leaving the renderer in a stuck state. switch (msg.type()) { - // Updates the previous navigation entry. - case ViewHostMsg_UpdateState::ID: // Sends an ACK. case ViewHostMsg_UpdateTargetURL::ID: // We allow closing even if we are in the process of swapping out.
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 8df18e9..e10872a 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -657,10 +657,6 @@ // message. IPC_MESSAGE_ROUTED0(ViewHostMsg_ClosePage_ACK) -// Notifies the browser that we have session history information. -IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateState, - content::PageState /* state */) - // Notifies the browser that we want to show a destination url for a potential // action (e.g. when the user is hovering over a link). IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateTargetURL,
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index 22f354d..f04b7f90f 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -9,7 +9,7 @@ import("//media/media_options.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//ppapi/features/features.gni") -import("//third_party/webrtc/build/webrtc.gni") +import("//third_party/webrtc/webrtc.gni") # See //content/BUILD.gn for how this works. group("common") {
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index d36497a8..bc99abf7 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -20,7 +20,6 @@ #include "content/common/input_messages.h" #include "content/common/renderer.mojom.h" #include "content/common/resize_params.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/native_web_keyboard_event.h" @@ -30,7 +29,6 @@ #include "content/public/common/renderer_preferences.h" #include "content/public/renderer/content_renderer_client.h" #include "content/public/test/frame_load_waiter.h" -#include "content/renderer/history_controller.h" #include "content/renderer/history_serialization.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" @@ -212,17 +210,12 @@ PageState RenderViewTest::GetCurrentPageState() { RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_); - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - // This returns a PageState object for the main frame, excluding subframes. - // This could be extended to all local frames if needed by tests, but it - // cannot include out-of-process frames. - TestRenderFrame* frame = - static_cast<TestRenderFrame*>(view_impl->GetMainRenderFrame()); - return SingleHistoryItemToPageState(frame->current_history_item()); - } else { - return HistoryEntryToPageState( - view_impl->history_controller()->GetCurrentEntry()); - } + // This returns a PageState object for the main frame, excluding subframes. + // This could be extended to all local frames if needed by tests, but it + // cannot include out-of-process frames. + TestRenderFrame* frame = + static_cast<TestRenderFrame*>(view_impl->GetMainRenderFrame()); + return SingleHistoryItemToPageState(frame->current_history_item()); } void RenderViewTest::GoBack(const GURL& url, const PageState& state) {
diff --git a/content/public/test/test_navigation_observer.cc b/content/public/test/test_navigation_observer.cc index dcaf956..2abb8e2 100644 --- a/content/public/test/test_navigation_observer.cc +++ b/content/public/test/test_navigation_observer.cc
@@ -5,13 +5,10 @@ #include "content/public/test/test_navigation_observer.h" #include "base/bind.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" -#include "base/run_loop.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents_observer.h" -#include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -47,29 +44,19 @@ parent_->OnDidStopLoading(web_contents()); } - void DidStartProvisionalLoadForFrame(RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page) override { - parent_->OnDidStartProvisionalLoad(render_frame_host, validated_url, - is_error_page); + void DidStartNavigation(NavigationHandle* navigation_handle) override { + if (navigation_handle->IsSamePage()) + return; + + parent_->OnDidStartNavigation(); } - void DidFailProvisionalLoad( - RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - bool was_ignored_by_handler) override { - parent_->OnDidFailProvisionalLoad(render_frame_host, validated_url, - error_code, error_description); - } + void DidFinishNavigation(NavigationHandle* navigation_handle) override { + if (!navigation_handle->HasCommitted()) + return; - void DidCommitProvisionalLoadForFrame( - RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type) override { - parent_->OnDidCommitProvisionalLoadForFrame( - render_frame_host, url, transition_type); + parent_->OnDidFinishNavigation(navigation_handle->IsErrorPage(), + navigation_handle->GetURL()); } TestNavigationObserver* parent_; @@ -163,28 +150,14 @@ } } -void TestNavigationObserver::OnDidStartProvisionalLoad( - RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page) { +void TestNavigationObserver::OnDidStartNavigation() { last_navigation_succeeded_ = false; } -void TestNavigationObserver::OnDidFailProvisionalLoad( - RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description) { - last_navigation_url_ = validated_url; - last_navigation_succeeded_ = false; -} - -void TestNavigationObserver::OnDidCommitProvisionalLoadForFrame( - RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type) { +void TestNavigationObserver::OnDidFinishNavigation(bool is_error_page, + const GURL& url) { last_navigation_url_ = url; - last_navigation_succeeded_ = true; + last_navigation_succeeded_ = !is_error_page; } } // namespace content
diff --git a/content/public/test/test_navigation_observer.h b/content/public/test/test_navigation_observer.h index 6409486..a2333f3 100644 --- a/content/public/test/test_navigation_observer.h +++ b/content/public/test/test_navigation_observer.h
@@ -9,16 +9,12 @@ #include <set> #include "base/callback.h" -#include "base/compiler_specific.h" #include "base/macros.h" #include "content/public/test/test_utils.h" -#include "ui/base/page_transition_types.h" #include "url/gurl.h" namespace content { -class RenderFrameHost; class WebContents; -struct LoadCommittedDetails; // For browser_tests, which run on the UI thread, run a second // MessageLoop and quit when the navigation completes loading. @@ -67,16 +63,8 @@ void OnDidAttachInterstitialPage(WebContents* web_contents); void OnDidStartLoading(WebContents* web_contents); void OnDidStopLoading(WebContents* web_contents); - void OnDidStartProvisionalLoad(RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page); - void OnDidFailProvisionalLoad(RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description); - void OnDidCommitProvisionalLoadForFrame(RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type); + void OnDidStartNavigation(); + void OnDidFinishNavigation(bool is_error_page, const GURL& url); // If true the navigation has started. bool navigation_started_;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index ddf805f..06535765 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -9,7 +9,7 @@ import("//media/media_options.gni") import("//ppapi/features/features.gni") import("//printing/features/features.gni") -import("//third_party/webrtc/build/webrtc.gni") +import("//third_party/webrtc/webrtc.gni") import("//tools/ipc_fuzzer/ipc_fuzzer.gni") if (is_component_build) { @@ -147,8 +147,6 @@ "gpu/renderer_compositor_frame_sink.h", "gpu/stream_texture_host_android.cc", "gpu/stream_texture_host_android.h", - "history_controller.cc", - "history_controller.h", "history_entry.cc", "history_entry.h", "history_serialization.cc",
diff --git a/content/renderer/history_controller.cc b/content/renderer/history_controller.cc deleted file mode 100644 index 6369f09..0000000 --- a/content/renderer/history_controller.cc +++ /dev/null
@@ -1,335 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/* - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. - * (http://www.torchmobile.com/) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "content/renderer/history_controller.h" - -#include <utility> - -#include "base/memory/ptr_util.h" -#include "content/common/navigation_params.h" -#include "content/common/site_isolation_policy.h" -#include "content/renderer/render_frame_impl.h" -#include "content/renderer/render_view_impl.h" -#include "third_party/WebKit/public/web/WebFrameLoadType.h" -#include "third_party/WebKit/public/web/WebLocalFrame.h" - -using blink::WebCachePolicy; -using blink::WebFrame; -using blink::WebHistoryCommitType; -using blink::WebHistoryItem; -using blink::WebURLRequest; - -namespace content { - -HistoryController::HistoryController(RenderViewImpl* render_view) - : render_view_(render_view) { - // We don't use HistoryController in OOPIF enabled modes. - DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries()); -} - -HistoryController::~HistoryController() { -} - -bool HistoryController::GoToEntry( - blink::WebLocalFrame* main_frame, - std::unique_ptr<HistoryEntry> target_entry, - std::unique_ptr<NavigationParams> navigation_params, - WebCachePolicy cache_policy) { - DCHECK(!main_frame->parent()); - HistoryFrameLoadVector same_document_loads; - HistoryFrameLoadVector different_document_loads; - - set_provisional_entry(std::move(target_entry)); - navigation_params_ = std::move(navigation_params); - - if (current_entry_) { - RecursiveGoToEntry( - main_frame, same_document_loads, different_document_loads); - } - - if (same_document_loads.empty() && different_document_loads.empty()) { - // If we don't have any frames to navigate at this point, either - // (1) there is no previous history entry to compare against, or - // (2) we were unable to match any frames by name. In the first case, - // doing a different document navigation to the root item is the only valid - // thing to do. In the second case, we should have been able to find a - // frame to navigate based on names if this were a same document - // navigation, so we can safely assume this is the different document case. - different_document_loads.push_back( - std::make_pair(main_frame, provisional_entry_->root())); - } - - bool has_main_frame_request = false; - for (const auto& item : same_document_loads) { - WebFrame* frame = item.first; - RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame); - if (!render_frame) - continue; - render_frame->SetPendingNavigationParams( - base::MakeUnique<NavigationParams>(*navigation_params_.get())); - WebURLRequest request = frame->toWebLocalFrame()->requestFromHistoryItem( - item.second, cache_policy); - frame->toWebLocalFrame()->load( - request, blink::WebFrameLoadType::BackForward, item.second, - blink::WebHistorySameDocumentLoad); - if (frame == main_frame) - has_main_frame_request = true; - } - for (const auto& item : different_document_loads) { - WebFrame* frame = item.first; - RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame); - if (!render_frame) - continue; - render_frame->SetPendingNavigationParams( - base::MakeUnique<NavigationParams>(*navigation_params_.get())); - WebURLRequest request = frame->toWebLocalFrame()->requestFromHistoryItem( - item.second, cache_policy); - frame->toWebLocalFrame()->load( - request, blink::WebFrameLoadType::BackForward, item.second, - blink::WebHistoryDifferentDocumentLoad); - if (frame == main_frame) - has_main_frame_request = true; - } - - return has_main_frame_request; -} - -void HistoryController::RecursiveGoToEntry( - WebFrame* frame, - HistoryFrameLoadVector& same_document_loads, - HistoryFrameLoadVector& different_document_loads) { - DCHECK(provisional_entry_); - DCHECK(current_entry_); - RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame); - const WebHistoryItem& new_item = - provisional_entry_->GetItemForFrame(render_frame); - - // Use the last committed history item for the frame rather than - // current_entry_, since the latter may not accurately reflect which URL is - // currently committed in the frame. See https://crbug.com/612713#c12. - const WebHistoryItem& old_item = render_frame->current_history_item(); - - if (new_item.isNull()) - return; - - if (old_item.isNull() || - new_item.itemSequenceNumber() != old_item.itemSequenceNumber()) { - if (!old_item.isNull() && - new_item.documentSequenceNumber() == - old_item.documentSequenceNumber()) { - same_document_loads.push_back(std::make_pair(frame, new_item)); - - // Returning here (and omitting child frames which have also changed) is - // wrong, but not returning here is worse. See the discussion in - // NavigationControllerImpl::FindFramesToNavigate for more information. - return; - } else { - different_document_loads.push_back(std::make_pair(frame, new_item)); - // For a different document, the subframes will be destroyed, so there's - // no need to consider them. - return; - } - } - - for (WebFrame* child = frame->firstChild(); child; - child = child->nextSibling()) { - RecursiveGoToEntry(child, same_document_loads, different_document_loads); - } -} - -void HistoryController::UpdateForInitialLoadInChildFrame( - RenderFrameImpl* frame, - const WebHistoryItem& item) { - DCHECK_NE(frame->GetWebFrame()->top(), frame->GetWebFrame()); - if (!current_entry_) - return; - if (HistoryEntry::HistoryNode* existing_node = - current_entry_->GetHistoryNodeForFrame(frame)) { - // Clear the children and any NavigationParams if this commit isn't for - // the same item. Otherwise we might have stale data after a redirect. - if (existing_node->item().itemSequenceNumber() != - item.itemSequenceNumber()) { - existing_node->RemoveChildren(); - navigation_params_.reset(); - } - existing_node->set_item(item); - return; - } - RenderFrameImpl* parent = - RenderFrameImpl::FromWebFrame(frame->GetWebFrame()->parent()); - if (!parent) - return; - if (HistoryEntry::HistoryNode* parent_history_node = - current_entry_->GetHistoryNodeForFrame(parent)) { - parent_history_node->AddChild(item); - } -} - -void HistoryController::UpdateForCommit(RenderFrameImpl* frame, - const WebHistoryItem& item, - WebHistoryCommitType commit_type, - bool navigation_within_page) { - switch (commit_type) { - case blink::WebBackForwardCommit: - if (!provisional_entry_) { - // The provisional entry may have been discarded due to a navigation in - // a different frame. For main frames, it is not safe to leave the - // current_entry_ in place, which may have a cross-site page and will be - // included in the PageState for this commit. Replace it with a new - // HistoryEntry corresponding to the commit, and clear any stale - // NavigationParams which might point to the wrong entry. - // - // This will lack any subframe history items that were in the original - // provisional entry, but we don't know what those were after discarding - // it. We'll load the default URL in those subframes instead. - // - // TODO(creis): It's also possible to get here for subframe commits. - // We'll leave a stale current_entry_ in that case, but that only causes - // an earlier URL to load in the subframe when leaving and coming back, - // and only in rare cases. It does not risk a URL spoof, unlike the - // main frame case. Since this bug is not present in the new - // FrameNavigationEntry-based navigation path (https://crbug.com/236848) - // we'll wait for that to fix the subframe case. - if (frame->IsMainFrame()) { - current_entry_.reset(new HistoryEntry(item)); - navigation_params_.reset(); - } - - return; - } - - // If the current entry is null, this must be a main frame commit. - DCHECK(current_entry_ || frame->IsMainFrame()); - - // Commit the provisional entry, but only if it is a plausible transition. - // Do not commit it if the navigation is in a subframe and the provisional - // entry's main frame item does not match the current entry's main frame, - // which can happen if multiple forward navigations occur. In that case, - // committing the provisional entry would corrupt it, leading to a URL - // spoof. See https://crbug.com/597322. (Note that the race in this bug - // does not affect main frame navigations, only navigations in subframes.) - // - // Note that we cannot compare the provisional entry against |item|, since - // |item| may have redirected to a different URL and ISN. We also cannot - // compare against the main frame's URL, since that may have changed due - // to a replaceState. (Even origin can change on replaceState in certain - // modes.) - // - // It would be safe to additionally check the ISNs of all parent frames - // (and not just the root), but that is less critical because it won't - // lead to a URL spoof. - if (frame->IsMainFrame() || - current_entry_->root().itemSequenceNumber() == - provisional_entry_->root().itemSequenceNumber()) { - current_entry_ = std::move(provisional_entry_); - } - - // We're guaranteed to have a current entry now. - DCHECK(current_entry_); - - if (HistoryEntry::HistoryNode* node = - current_entry_->GetHistoryNodeForFrame(frame)) { - // Clear the children and any NavigationParams if this commit isn't for - // the same item. Otherwise we might have stale data from a race. - if (node->item().itemSequenceNumber() != item.itemSequenceNumber()) { - node->RemoveChildren(); - navigation_params_.reset(); - } - - node->set_item(item); - } - break; - case blink::WebStandardCommit: - CreateNewBackForwardItem(frame, item, navigation_within_page); - break; - case blink::WebInitialCommitInChildFrame: - UpdateForInitialLoadInChildFrame(frame, item); - break; - case blink::WebHistoryInertCommit: - // Even for inert commits (e.g., location.replace, client redirects), make - // sure the current entry gets updated, if there is one. - if (current_entry_) { - if (HistoryEntry::HistoryNode* node = - current_entry_->GetHistoryNodeForFrame(frame)) { - // Inert commits that reset the page without changing the item (e.g., - // reloads, location.replace) shouldn't keep the old subtree. - if (!navigation_within_page) - node->RemoveChildren(); - node->set_item(item); - } - } - break; - default: - NOTREACHED() << "Invalid commit type: " << commit_type; - } -} - -HistoryEntry* HistoryController::GetCurrentEntry() { - return current_entry_.get(); -} - -WebHistoryItem HistoryController::GetItemForNewChildFrame( - RenderFrameImpl* frame) const { - if (navigation_params_.get()) { - frame->SetPendingNavigationParams( - base::MakeUnique<NavigationParams>(*navigation_params_.get())); - } - - if (!current_entry_) - return WebHistoryItem(); - return current_entry_->GetItemForFrame(frame); -} - -void HistoryController::RemoveChildrenForRedirect(RenderFrameImpl* frame) { - if (!provisional_entry_) - return; - if (HistoryEntry::HistoryNode* node = - provisional_entry_->GetHistoryNodeForFrame(frame)) - node->RemoveChildren(); -} - -void HistoryController::CreateNewBackForwardItem( - RenderFrameImpl* target_frame, - const WebHistoryItem& new_item, - bool clone_children_of_target) { - if (!current_entry_) { - current_entry_.reset(new HistoryEntry(new_item)); - } else { - current_entry_.reset(current_entry_->CloneAndReplace( - new_item, clone_children_of_target, target_frame, render_view_)); - } -} - -} // namespace content
diff --git a/content/renderer/history_controller.h b/content/renderer/history_controller.h deleted file mode 100644 index ac52241..0000000 --- a/content/renderer/history_controller.h +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/* - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. - * (http://www.torchmobile.com/) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CONTENT_RENDERER_HISTORY_CONTROLLER_H_ -#define CONTENT_RENDERER_HISTORY_CONTROLLER_H_ - -#include <memory> -#include <utility> - -#include "base/containers/hash_tables.h" -#include "base/macros.h" -#include "content/common/content_export.h" -#include "content/renderer/history_entry.h" -#include "third_party/WebKit/public/web/WebHistoryCommitType.h" -#include "third_party/WebKit/public/web/WebHistoryItem.h" - -namespace blink { -class WebFrame; -class WebLocalFrame; -enum class WebCachePolicy; -} - -namespace content { -class RenderFrameImpl; -class RenderViewImpl; -struct NavigationParams; - -// A guide to history state in the renderer: -// -// HistoryController: Owned by RenderView, is the entry point for interacting -// with history. Handles most of the operations to modify history state, -// navigate to an existing back/forward entry, etc. -// -// HistoryEntry: Represents a single entry in the back/forward list, -// encapsulating all frames in the page it represents. It provides access -// to each frame's state via lookups by frame id or frame name. -// HistoryNode: Represents a single frame in a HistoryEntry. Owned by a -// HistoryEntry. HistoryNodes form a tree that mirrors the frame tree in -// the corresponding page. -// HistoryNodes represent the structure of the page, but don't hold any -// per-frame state except a list of child frames. -// WebHistoryItem (lives in blink): The state for a given frame. Can persist -// across navigations. WebHistoryItem is reference counted, and each -// HistoryNode holds a reference to its single corresponding -// WebHistoryItem. Can be referenced by multiple HistoryNodes and can -// therefore exist in multiple HistoryEntry instances. -// -// Suppose we have the following page, foo.com, which embeds foo.com/a in an -// iframe: -// -// HistoryEntry 0: -// HistoryNode 0_0 (WebHistoryItem A (url: foo.com)) -// HistoryNode 0_1: (WebHistoryItem B (url: foo.com/a)) -// -// Now we navigate the top frame to bar.com, which embeds bar.com/b and -// bar.com/c in iframes, and bar.com/b in turn embeds bar.com/d. We will -// create a new HistoryEntry with a tree containing 4 new HistoryNodes. The -// state will be: -// -// HistoryEntry 1: -// HistoryNode 1_0 (WebHistoryItem C (url: bar.com)) -// HistoryNode 1_1: (WebHistoryItem D (url: bar.com/b)) -// HistoryNode 1_3: (WebHistoryItem F (url: bar.com/d)) -// HistoryNode 1_2: (WebHistoryItem E (url: bar.com/c)) -// -// -// Finally, we navigate the first subframe from bar.com/b to bar.com/e, which -// embeds bar.com/f. We will create a new HistoryEntry and new HistoryNode for -// each frame. Any frame that navigates (bar.com/e and its child, bar.com/f) -// will receive a new WebHistoryItem. However, 2 frames were not navigated -// (bar.com and bar.com/c), so those two frames will reuse the existing -// WebHistoryItem: -// -// HistoryEntry 2: -// HistoryNode 2_0 (WebHistoryItem C (url: bar.com)) *REUSED* -// HistoryNode 2_1: (WebHistoryItem G (url: bar.com/e)) -// HistoryNode 2_3: (WebHistoryItem H (url: bar.com/f)) -// HistoryNode 2_2: (WebHistoryItem E (url: bar.com/c)) *REUSED* -// -class CONTENT_EXPORT HistoryController { - public: - explicit HistoryController(RenderViewImpl* render_view); - ~HistoryController(); - - void set_provisional_entry(std::unique_ptr<HistoryEntry> entry) { - provisional_entry_ = std::move(entry); - } - - // Return true if the main frame ended up loading a request as part of the - // history navigation. - bool GoToEntry(blink::WebLocalFrame* main_frame, - std::unique_ptr<HistoryEntry> entry, - std::unique_ptr<NavigationParams> navigation_params, - blink::WebCachePolicy cache_policy); - - void UpdateForCommit(RenderFrameImpl* frame, - const blink::WebHistoryItem& item, - blink::WebHistoryCommitType commit_type, - bool navigation_within_page); - - HistoryEntry* GetCurrentEntry(); - blink::WebHistoryItem GetItemForNewChildFrame(RenderFrameImpl* frame) const; - void RemoveChildrenForRedirect(RenderFrameImpl* frame); - - private: - typedef std::vector<std::pair<blink::WebFrame*, blink::WebHistoryItem> > - HistoryFrameLoadVector; - void RecursiveGoToEntry(blink::WebFrame* frame, - HistoryFrameLoadVector& sameDocumentLoads, - HistoryFrameLoadVector& differentDocumentLoads); - - void UpdateForInitialLoadInChildFrame(RenderFrameImpl* frame, - const blink::WebHistoryItem& item); - void CreateNewBackForwardItem(RenderFrameImpl* frame, - const blink::WebHistoryItem& item, - bool clone_children_of_target); - - RenderViewImpl* render_view_; - - // A HistoryEntry representing the currently-loaded page. - std::unique_ptr<HistoryEntry> current_entry_; - // A HistoryEntry representing the page that is being loaded, or an empty - // scoped_ptr if no page is being loaded. - std::unique_ptr<HistoryEntry> provisional_entry_; - - // The NavigationParams corresponding to the last back/forward load that was - // initiated by |GoToEntry|. This is kept around so that it can be passed into - // existing frames affected by a history navigation in GoToEntry(), and can be - // passed into frames created after the commit that resulted from the - // navigation in GetItemForNewChildFrame(). - // - // This is reset in UpdateForCommit if we see a commit from a different - // navigation, to avoid using stale parameters. - std::unique_ptr<NavigationParams> navigation_params_; - - DISALLOW_COPY_AND_ASSIGN(HistoryController); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_HISTORY_CONTROLLER_H_
diff --git a/content/renderer/history_controller_browsertest.cc b/content/renderer/history_controller_browsertest.cc deleted file mode 100644 index 148c0c3..0000000 --- a/content/renderer/history_controller_browsertest.cc +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "build/build_config.h" -#include "content/common/site_isolation_policy.h" -#include "content/public/test/render_view_test.h" -#include "content/renderer/history_controller.h" -#include "content/renderer/render_frame_impl.h" -#include "content/renderer/render_view_impl.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/web/WebHistoryItem.h" - -namespace content { - -class HistoryControllerTest : public RenderViewTest { - public: - ~HistoryControllerTest() override {} - - // Create a main frame with a single child frame. - void SetUp() override { - RenderViewTest::SetUp(); - LoadHTML("Parent frame <iframe name='frame'></iframe>"); - } - - void TearDown() override { RenderViewTest::TearDown(); } - - HistoryController* history_controller() { - return static_cast<RenderViewImpl*>(view_)->history_controller(); - } -}; - -#if defined(OS_ANDROID) -// See https://crbug.com/472717 -#define MAYBE_InertCommitRemovesChildren DISABLED_InertCommitRemovesChildren -#else -#define MAYBE_InertCommitRemovesChildren InertCommitRemovesChildren -#endif - -TEST_F(HistoryControllerTest, MAYBE_InertCommitRemovesChildren) { - // This test is moot when subframe FrameNavigationEntries are enabled, since - // we don't use HistoryController in that case. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) - return; - - HistoryEntry* entry = history_controller()->GetCurrentEntry(); - ASSERT_TRUE(entry); - ASSERT_EQ(1ul, entry->root_history_node()->children().size()); - - blink::WebHistoryItem item; - item.initialize(); - RenderFrameImpl* main_frame = - static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame()); - - // Don't clear children for in-page navigations. - history_controller()->UpdateForCommit(main_frame, item, - blink::WebHistoryInertCommit, true); - EXPECT_EQ(1ul, entry->root_history_node()->children().size()); - - // Clear children for cross-page navigations. - history_controller()->UpdateForCommit(main_frame, item, - blink::WebHistoryInertCommit, false); - EXPECT_EQ(0ul, entry->root_history_node()->children().size()); -} - -} // namespace
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 4f6c272b..eb5dfd4 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -100,7 +100,7 @@ #include "content/renderer/effective_connection_type_helper.h" #include "content/renderer/external_popup_menu.h" #include "content/renderer/gpu/gpu_benchmarking_extension.h" -#include "content/renderer/history_controller.h" +#include "content/renderer/history_entry.h" #include "content/renderer/history_serialization.h" #include "content/renderer/image_downloader/image_downloader_impl.h" #include "content/renderer/ime_event_guard.h" @@ -1693,10 +1693,7 @@ // other active RenderFrames in it. // Send an UpdateState message before we get deleted. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) - SendUpdateState(); - else - render_view_->SendUpdateState(); + SendUpdateState(); // There should always be a proxy to replace this RenderFrame. Create it now // so its routing id is registered for receiving IPC messages. @@ -3094,8 +3091,7 @@ observer.FrameDetached(frame); // Send a state update before the frame is detached. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) - SendUpdateState(); + SendUpdateState(); // We only notify the browser process when the frame is being detached for // removal and it was initiated from the renderer process. @@ -3297,12 +3293,9 @@ } blink::WebHistoryItem RenderFrameImpl::historyItemForNewChildFrame() { - // OOPIF enabled modes will punt this navigation to the browser in - // decidePolicyForNavigation. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) - return WebHistoryItem(); - - return render_view_->history_controller()->GetItemForNewChildFrame(this); + // We will punt this navigation to the browser in decidePolicyForNavigation. + // TODO(creis): Look into cleaning this up. + return WebHistoryItem(); } void RenderFrameImpl::willSendSubmitEvent(const blink::WebFormElement& form) { @@ -3472,11 +3465,8 @@ blink::WebLocalFrame* frame) { DCHECK_EQ(frame_, frame); - // We don't use HistoryController in OOPIF enabled modes. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) - return; - - render_view_->history_controller()->RemoveChildrenForRedirect(this); + // TODO(creis): Determine if this can be removed or if we need to clear any + // local state here to fix https://crbug.com/671276. } void RenderFrameImpl::didFailProvisionalLoad( @@ -3615,13 +3605,8 @@ // When we perform a new navigation, we need to update the last committed // session history entry with state for the page we are leaving. Do this // before updating the current history item. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - SendUpdateState(); - } else { - render_view_->SendUpdateState(); - render_view_->history_controller()->UpdateForCommit( - this, item, commit_type, navigation_state->WasWithinSamePage()); - } + SendUpdateState(); + // Update the current history item for this frame (both in default Chrome and // subframe FrameNavigationEntry modes). current_history_item_ = item; @@ -4880,31 +4865,14 @@ render_view_->navigation_gesture_ = NavigationGestureUnknown; // Make navigation state a part of the DidCommitProvisionalLoad message so - // that committed entry has it at all times. - int64_t post_id = -1; - if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) { - HistoryEntry* entry = render_view_->history_controller()->GetCurrentEntry(); - if (entry) { - params.page_state = HistoryEntryToPageState(entry); - post_id = ExtractPostId(entry->root()); - } else { - params.page_state = PageState::CreateFromURL(request.url()); - } - } else { - // In --site-per-process, just send a single HistoryItem for this frame, - // rather than the whole tree. It will be stored in the corresponding - // FrameNavigationEntry. - params.page_state = SingleHistoryItemToPageState(item); - post_id = ExtractPostId(item); - } + // that committed entry has it at all times. Send a single HistoryItem for + // this frame, rather than the whole tree. It will be stored in the + // corresponding FrameNavigationEntry. + params.page_state = SingleHistoryItemToPageState(item); - // When using subframe navigation entries, method and post id are set for all - // frames. Otherwise, they are only set for the main frame navigation. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - params.method = request.httpMethod().latin1(); - if (params.method == "POST") - params.post_id = post_id; - } + params.method = request.httpMethod().latin1(); + if (params.method == "POST") + params.post_id = ExtractPostId(item); params.frame_unique_name = item.target().utf8(); params.item_sequence_number = item.itemSequenceNumber(); @@ -4978,14 +4946,6 @@ params.transition | ui::PAGE_TRANSITION_CLIENT_REDIRECT); } - // When using subframe navigation entries, method and post id have already - // been set. - if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) { - params.method = request.httpMethod().latin1(); - if (params.method == "POST") - params.post_id = post_id; - } - // Send the user agent override back. params.is_overriding_user_agent = internal_data->is_overriding_user_agent(); @@ -5297,15 +5257,13 @@ return blink::WebNavigationPolicyIgnore; // Suppress the load here. } - // In OOPIF-enabled modes, back/forward navigations in newly created subframes - // should be sent to the browser if there is a matching FrameNavigationEntry, - // and if it isn't just staying at about:blank. If this frame isn't in the - // map of unique names that have history items, or if it's staying at the - // initial about:blank URL, fall back to loading the default url. (We remove - // each name as we encounter it, because it will only be used once as the - // frame is created.) - if (SiteIsolationPolicy::UseSubframeNavigationEntries() && - info.isHistoryNavigationInNewChildFrame && is_content_initiated && + // Back/forward navigations in newly created subframes should be sent to the + // browser if there is a matching FrameNavigationEntry, and if it isn't just + // staying at about:blank. If this frame isn't in the map of unique names + // that have history items, or if it's staying at the initial about:blank URL, + // fall back to loading the default url. (We remove each name as we encounter + // it, because it will only be used once as the frame is created.) + if (info.isHistoryNavigationInNewChildFrame && is_content_initiated && frame_->parent()) { // Check whether the browser has a history item for this frame that isn't // just staying at the initial about:blank document. @@ -5825,10 +5783,8 @@ WebUserGestureIndicator::consumeUserGesture(); } - if (is_history_navigation_in_new_child) { - DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries()); + if (is_history_navigation_in_new_child) params.is_history_navigation_in_new_child = true; - } Send(new FrameHostMsg_OpenURL(routing_id_, params)); } @@ -5857,11 +5813,7 @@ if (request_params.has_committed_real_load && frame_->parent()) frame_->setCommittedFirstRealLoad(); - bool no_current_entry = - SiteIsolationPolicy::UseSubframeNavigationEntries() - ? current_history_item_.isNull() - : !render_view_->history_controller()->GetCurrentEntry(); - if (is_reload && no_current_entry) { + if (is_reload && current_history_item_.isNull()) { // We cannot reload if we do not have any history state. This happens, for // example, when recovering from a crash. is_reload = false; @@ -5943,78 +5895,62 @@ std::unique_ptr<HistoryEntry> entry = PageStateToHistoryEntry(request_params.page_state); if (entry) { - if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) { - // By default, tell the HistoryController to go the deserialized - // HistoryEntry. This only works if all frames are in the same - // process. - DCHECK(!frame_->parent()); - DCHECK(!browser_side_navigation); - std::unique_ptr<NavigationParams> navigation_params( - new NavigationParams(*pending_navigation_params_.get())); - has_history_navigation_in_frame = - render_view_->history_controller()->GoToEntry( - frame_, std::move(entry), std::move(navigation_params), - cache_policy); - } else { - // In --site-per-process, the browser process sends a single - // WebHistoryItem destined for this frame. - // TODO(creis): Change PageState to FrameState. In the meantime, we - // store the relevant frame's WebHistoryItem in the root of the - // PageState. - item_for_history_navigation = entry->root(); - history_load_type = request_params.is_same_document_history_load - ? blink::WebHistorySameDocumentLoad - : blink::WebHistoryDifferentDocumentLoad; - load_type = request_params.is_history_navigation_in_new_child - ? blink::WebFrameLoadType::InitialHistoryLoad - : blink::WebFrameLoadType::BackForward; - should_load_request = true; + // The browser process sends a single WebHistoryItem for this frame. + // TODO(creis): Change PageState to FrameState. In the meantime, we + // store the relevant frame's WebHistoryItem in the root of the + // PageState. + item_for_history_navigation = entry->root(); + history_load_type = request_params.is_same_document_history_load + ? blink::WebHistorySameDocumentLoad + : blink::WebHistoryDifferentDocumentLoad; + load_type = request_params.is_history_navigation_in_new_child + ? blink::WebFrameLoadType::InitialHistoryLoad + : blink::WebFrameLoadType::BackForward; + should_load_request = true; - // Keep track of which subframes the browser process has history items - // for during a history navigation. - history_subframe_unique_names_ = request_params.subframe_unique_names; + // Keep track of which subframes the browser process has history items + // for during a history navigation. + history_subframe_unique_names_ = request_params.subframe_unique_names; - if (history_load_type == blink::WebHistorySameDocumentLoad) { - // If this is marked as a same document load but we haven't committed - // anything, treat it as a new load. The browser shouldn't let this - // happen. - if (current_history_item_.isNull()) { + if (history_load_type == blink::WebHistorySameDocumentLoad) { + // If this is marked as a same document load but we haven't committed + // anything, treat it as a new load. The browser shouldn't let this + // happen. + if (current_history_item_.isNull()) { + history_load_type = blink::WebHistoryDifferentDocumentLoad; + NOTREACHED(); + } else { + // Additionally, if the |current_history_item_|'s document + // sequence number doesn't match the one sent from the browser, it + // is possible that this renderer has committed a different + // document. In such case, don't use WebHistorySameDocumentLoad. + if (current_history_item_.documentSequenceNumber() != + item_for_history_navigation.documentSequenceNumber()) { history_load_type = blink::WebHistoryDifferentDocumentLoad; - NOTREACHED(); - } else { - // Additionally, if the |current_history_item_|'s document - // sequence number doesn't match the one sent from the browser, it - // is possible that this renderer has committed a different - // document. In such case, don't use WebHistorySameDocumentLoad. - if (current_history_item_.documentSequenceNumber() != - item_for_history_navigation.documentSequenceNumber()) { - history_load_type = blink::WebHistoryDifferentDocumentLoad; - } } } + } - // If this navigation is to a history item for a new child frame, we may - // want to ignore it in some cases. If a Javascript navigation (i.e., - // client redirect) interrupted it and has either been scheduled, - // started loading, or has committed, we should ignore the history item. - bool interrupted_by_client_redirect = - frame_->isNavigationScheduledWithin(0) || - frame_->provisionalDataSource() || - !current_history_item_.isNull(); - if (request_params.is_history_navigation_in_new_child && - interrupted_by_client_redirect) { - should_load_request = false; - has_history_navigation_in_frame = false; - } + // If this navigation is to a history item for a new child frame, we may + // want to ignore it in some cases. If a Javascript navigation (i.e., + // client redirect) interrupted it and has either been scheduled, + // started loading, or has committed, we should ignore the history item. + bool interrupted_by_client_redirect = + frame_->isNavigationScheduledWithin(0) || + frame_->provisionalDataSource() || !current_history_item_.isNull(); + if (request_params.is_history_navigation_in_new_child && + interrupted_by_client_redirect) { + should_load_request = false; + has_history_navigation_in_frame = false; + } - // Generate the request for the load from the HistoryItem. - // PlzNavigate: use the data sent by the browser for the url and the - // HTTP state. The restoration of user state such as scroll position - // will be done based on the history item during the load. - if (!browser_side_navigation && should_load_request) { - request = frame_->requestFromHistoryItem(item_for_history_navigation, - cache_policy); - } + // Generate the request for the load from the HistoryItem. + // PlzNavigate: use the data sent by the browser for the url and the + // HTTP state. The restoration of user state such as scroll position + // will be done based on the history item during the load. + if (!browser_side_navigation && should_load_request) { + request = frame_->requestFromHistoryItem(item_for_history_navigation, + cache_policy); } } } else { @@ -6075,7 +6011,7 @@ // that the load stopped if needed. // Note: in the case of history navigations, |should_load_request| will be // false, and the frame may not have been set in a loading state. Do not - // send a stop message if the HistoryController is loading in this frame + // send a stop message if a history navigation is loading in this frame // nonetheless. This behavior will go away with subframe navigation // entries. if (frame_ && !frame_->isLoading() && !has_history_navigation_in_frame) @@ -6353,7 +6289,6 @@ } void RenderFrameImpl::SendUpdateState() { - DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries()); if (current_history_item_.isNull()) return;
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 25bd75d..0d23fcdd 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -50,7 +50,7 @@ #include "content/renderer/accessibility/render_accessibility_impl.h" #include "content/renderer/devtools/devtools_agent.h" #include "content/renderer/gpu/render_widget_compositor.h" -#include "content/renderer/history_controller.h" +#include "content/renderer/history_entry.h" #include "content/renderer/history_serialization.h" #include "content/renderer/navigation_state_impl.h" #include "content/renderer/render_frame_proxy.h" @@ -585,8 +585,6 @@ // We should NOT have gotten a form state change notification yet. EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching( FrameHostMsg_UpdateState::ID)); - EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching( - ViewHostMsg_UpdateState::ID)); render_thread_->sink().ClearMessages(); // Change the value of the input. We should have gotten an update state @@ -937,10 +935,10 @@ // Check for a valid UpdateState message for page A. ProcessPendingMessages(); const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching( - ViewHostMsg_UpdateState::ID); + FrameHostMsg_UpdateState::ID); ASSERT_TRUE(msg_A); - ViewHostMsg_UpdateState::Param param; - ViewHostMsg_UpdateState::Read(msg_A, ¶m); + FrameHostMsg_UpdateState::Param param; + FrameHostMsg_UpdateState::Read(msg_A, ¶m); PageState state_A = std::get<0>(param); render_thread_->sink().ClearMessages(); @@ -950,9 +948,9 @@ // Check for a valid UpdateState for page B. ProcessPendingMessages(); const IPC::Message* msg_B = render_thread_->sink().GetUniqueMessageMatching( - ViewHostMsg_UpdateState::ID); + FrameHostMsg_UpdateState::ID); ASSERT_TRUE(msg_B); - ViewHostMsg_UpdateState::Read(msg_B, ¶m); + FrameHostMsg_UpdateState::Read(msg_B, ¶m); PageState state_B = std::get<0>(param); EXPECT_NE(state_A, state_B); render_thread_->sink().ClearMessages(); @@ -963,9 +961,9 @@ // Check for a valid UpdateState for page C. ProcessPendingMessages(); const IPC::Message* msg_C = render_thread_->sink().GetUniqueMessageMatching( - ViewHostMsg_UpdateState::ID); + FrameHostMsg_UpdateState::ID); ASSERT_TRUE(msg_C); - ViewHostMsg_UpdateState::Read(msg_C, ¶m); + FrameHostMsg_UpdateState::Read(msg_C, ¶m); PageState state_C = std::get<0>(param); EXPECT_NE(state_B, state_C); render_thread_->sink().ClearMessages(); @@ -978,6 +976,7 @@ request_params_C.current_history_list_length = 4; request_params_C.current_history_list_offset = 3; request_params_C.pending_history_list_offset = 2; + request_params_C.nav_entry_id = 3; request_params_C.page_state = state_C; frame()->Navigate(common_params_C, StartNavigationParams(), request_params_C); ProcessPendingMessages(); @@ -995,6 +994,7 @@ request_params_B.current_history_list_length = 4; request_params_B.current_history_list_offset = 2; request_params_B.pending_history_list_offset = 1; + request_params_B.nav_entry_id = 2; request_params_B.page_state = state_B; frame()->Navigate(common_params_B, StartNavigationParams(), request_params_B); @@ -1006,6 +1006,7 @@ request_params.current_history_list_length = 4; request_params.current_history_list_offset = 2; request_params.pending_history_list_offset = 0; + request_params.nav_entry_id = 1; request_params.page_state = state_A; frame()->Navigate(common_params, StartNavigationParams(), request_params); ProcessPendingMessages(); @@ -1013,9 +1014,9 @@ // Now ensure that the UpdateState message we receive is consistent // and represents page C in state. const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching( - ViewHostMsg_UpdateState::ID); + FrameHostMsg_UpdateState::ID); ASSERT_TRUE(msg); - ViewHostMsg_UpdateState::Read(msg, ¶m); + FrameHostMsg_UpdateState::Read(msg, ¶m); PageState state = std::get<0>(param); EXPECT_NE(state_A, state); EXPECT_NE(state_B, state);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index e157b37..a4ddccb4 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -53,7 +53,6 @@ #include "content/common/input_messages.h" #include "content/common/page_messages.h" #include "content/common/render_message_filter.mojom.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/common/bindings_policy.h" #include "content/public/common/browser_side_navigation_policy.h" @@ -77,7 +76,6 @@ #include "content/renderer/dom_storage/webstoragenamespace_impl.h" #include "content/renderer/drop_data_builder.h" #include "content/renderer/gpu/render_widget_compositor.h" -#include "content/renderer/history_controller.h" #include "content/renderer/history_serialization.h" #include "content/renderer/idle_user_detector.h" #include "content/renderer/ime_event_guard.h" @@ -712,10 +710,6 @@ OnEnableAutoResize(params.min_size, params.max_size); } - // We don't use HistoryController in OOPIF-enabled modes. - if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) - history_controller_.reset(new HistoryController(this)); - new IdleUserDetector(this); if (command_line.HasSwitch(switches::kDomAutomationController)) @@ -1343,18 +1337,6 @@ /////////////////////////////////////////////////////////////////////////////// -void RenderViewImpl::SendUpdateState() { - // We don't use this path in OOPIF-enabled modes. - DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries()); - - HistoryEntry* entry = history_controller_->GetCurrentEntry(); - if (!entry) - return; - - Send(new ViewHostMsg_UpdateState(GetRoutingID(), - HistoryEntryToPageState(entry))); -} - void RenderViewImpl::ShowCreatedPopupWidget(RenderWidget* popup_widget, WebNavigationPolicy policy, const gfx::Rect& initial_rect) { @@ -1371,9 +1353,6 @@ } void RenderViewImpl::SendFrameStateUpdates() { - // We only use this path in OOPIF-enabled modes. - DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries()); - // Tell each frame with pending state to send its UpdateState message. for (int render_frame_routing_id : frames_with_pending_state_) { RenderFrameImpl* frame = @@ -1681,9 +1660,8 @@ } void RenderViewImpl::StartNavStateSyncTimerIfNecessary(RenderFrameImpl* frame) { - // In OOPIF modes, keep track of which frames have pending updates. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) - frames_with_pending_state_.insert(frame->GetRoutingID()); + // Keep track of which frames have pending updates. + frames_with_pending_state_.insert(frame->GetRoutingID()); int delay; if (send_content_state_immediately_) @@ -1702,15 +1680,9 @@ nav_state_sync_timer_.Stop(); } - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - // In OOPIF modes, tell each frame with pending state to inform the browser. - nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this, - &RenderViewImpl::SendFrameStateUpdates); - } else { - // By default, send an UpdateState for the current history item. - nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this, - &RenderViewImpl::SendUpdateState); - } + // Tell each frame with pending state to inform the browser. + nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this, + &RenderViewImpl::SendFrameStateUpdates); } void RenderViewImpl::setMouseOverURL(const WebURL& url) {
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 96b6012..57d38b4 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -94,7 +94,6 @@ namespace content { -class HistoryController; class RendererDateTimePicker; class RenderViewImplTest; class RenderViewObserver; @@ -165,10 +164,6 @@ send_content_state_immediately_ = value; } - HistoryController* history_controller() { - return history_controller_.get(); - } - // Functions to add and remove observers for this object. void AddObserver(RenderViewObserver* observer); void RemoveObserver(RenderViewObserver* observer); @@ -218,9 +213,6 @@ // be coalesced into one update. void StartNavStateSyncTimerIfNecessary(RenderFrameImpl* frame); - // Synchronously sends the current navigation state to the browser. - void SendUpdateState(); - // A popup widget opened by this view needs to be shown. void ShowCreatedPopupWidget(RenderWidget* popup_widget, blink::WebNavigationPolicy policy, @@ -796,8 +788,6 @@ // initialized. SpeechRecognitionDispatcher* speech_recognition_dispatcher_; - std::unique_ptr<HistoryController> history_controller_; - #if defined(OS_ANDROID) // Android Specific ---------------------------------------------------------
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 86c8bb1c..a563ecc 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -654,7 +654,6 @@ "../renderer/accessibility/render_accessibility_impl_browsertest.cc", "../renderer/blink_platform_audio_hardware_browsertest.cc", "../renderer/gin_browsertest.cc", - "../renderer/history_controller_browsertest.cc", "../renderer/media/renderer_webmediaplayer_delegate_browsertest.cc", "../renderer/mouse_lock_dispatcher_browsertest.cc", "../renderer/render_frame_impl_browsertest.cc",
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index 117f9bd..784fb2c 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -24,7 +24,6 @@ #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/common/renderer.mojom.h" -#include "content/common/site_isolation_policy.h" #include "content/public/common/page_state.h" #include "content/public/common/screen_info.h" #include "content/public/renderer/renderer_gamepad_provider.h" @@ -459,9 +458,6 @@ void SyncNavigationState(RenderView* render_view) { // TODO(creis): Add support for testing in OOPIF-enabled modes. // See https://crbug.com/477150. - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) - return; - static_cast<RenderViewImpl*>(render_view)->SendUpdateState(); } void SetFocusAndActivate(RenderView* render_view, bool enable) {
diff --git a/content/test/test_render_view_host.cc b/content/test/test_render_view_host.cc index b03f7b8..380ae45 100644 --- a/content/test/test_render_view_host.cc +++ b/content/test/test_render_view_host.cc
@@ -17,7 +17,6 @@ #include "content/browser/site_instance_impl.h" #include "content/common/dom_storage/dom_storage_types.h" #include "content/common/frame_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -313,11 +312,7 @@ const base::FilePath& file_path) { PageState state = PageState::CreateForTesting(GURL("http://www.google.com"), false, "data", &file_path); - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { - static_cast<RenderFrameHostImpl*>(GetMainFrame())->OnUpdateState(state); - } else { - OnUpdateState(state); - } + static_cast<RenderFrameHostImpl*>(GetMainFrame())->OnUpdateState(state); } RenderViewHostImplTestHarness::RenderViewHostImplTestHarness() {
diff --git a/ios/BUILD.gn b/ios/BUILD.gn index 98cb99a..e4dc67f 100644 --- a/ios/BUILD.gn +++ b/ios/BUILD.gn
@@ -28,6 +28,9 @@ deps = [ # List all the targets that need to be build on iOS by default. "//ios/chrome/app:chrome", + "//ios/chrome/share_extension", + "//ios/chrome/today_extension", + "//ios/chrome/widget_extension", "//ios/clean/chrome/app:chrome_clean_skeleton", "//ios/showcase", "//ios/web/shell:ios_web_shell",
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc index 45b759c..ea0f45cd 100644 --- a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc +++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc
@@ -141,7 +141,11 @@ init_params.url_request_context = browser_state->GetRequestContext(); init_params.debug_identifier = browser_state->GetDebugName(); init_params.channel = ::GetChannel(); - init_params.blocking_pool = web::WebThread::GetBlockingPool(); + base::SequencedWorkerPool* blocking_pool = web::WebThread::GetBlockingPool(); + init_params.blocking_task_runner = + blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior( + blocking_pool->GetSequenceToken(), + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); auto pss = base::MakeUnique<ProfileSyncService>(std::move(init_params));
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc index 9bc40fc..f83e9782 100644 --- a/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc +++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc
@@ -38,7 +38,11 @@ init_params.url_request_context = browser_state->GetRequestContext(); init_params.debug_identifier = browser_state->GetDebugName(); init_params.channel = ::GetChannel(); - init_params.blocking_pool = web::WebThread::GetBlockingPool(); + base::SequencedWorkerPool* blocking_pool = web::WebThread::GetBlockingPool(); + init_params.blocking_task_runner = + blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior( + blocking_pool->GetSequenceToken(), + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); return init_params; }
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 684d845..ad7c532 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -525,6 +525,8 @@ "payments/payment_request_unittest.cc", "public/origin_util_unittest.mm", "public/referrer_util_unittest.cc", + "public/test/crw_mock_web_state_delegate.h", + "public/test/crw_mock_web_state_delegate.mm", "public/web_state/page_viewport_state_unittest.mm", "url_scheme_util_unittest.mm", "url_util_unittest.cc", @@ -548,8 +550,6 @@ "web_state/ui/wk_back_forward_list_item_holder_unittest.mm", "web_state/ui/wk_web_view_configuration_provider_unittest.mm", "web_state/web_state_delegate_bridge_unittest.mm", - "web_state/web_state_delegate_stub.h", - "web_state/web_state_delegate_stub.mm", "web_state/web_state_impl_unittest.mm", "web_state/web_view_internal_creation_util_unittest.mm", "web_state/wk_web_view_security_util_unittest.mm",
diff --git a/ios/web/web_state/web_state_delegate_stub.h b/ios/web/public/test/crw_mock_web_state_delegate.h similarity index 86% rename from ios/web/web_state/web_state_delegate_stub.h rename to ios/web/public/test/crw_mock_web_state_delegate.h index dac17d55..bbf7bcd 100644 --- a/ios/web/web_state/web_state_delegate_stub.h +++ b/ios/web/public/test/crw_mock_web_state_delegate.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_WEB_STATE_WEB_STATE_DELEGATE_STUB_H_ -#define IOS_WEB_WEB_STATE_WEB_STATE_DELEGATE_STUB_H_ +#ifndef IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_ +#define IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_ #import "ios/testing/ocmock_complex_type_helper.h" #import "ios/web/public/web_state/web_state_delegate_bridge.h" // Stub implementation for CRWWebStateDelegate protocol. -@interface CRWWebStateDelegateStub +@interface CRWMockWebStateDelegate : OCMockComplexTypeHelper<CRWWebStateDelegate> // web::WebState::OpenURLParams in |webState:openURLWithParams:| call. @property(nonatomic, readonly) @@ -32,4 +32,4 @@ @end -#endif // IOS_WEB_WEB_STATE_WEB_STATE_DELEGATE_STUB_H_ +#endif // IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_
diff --git a/ios/web/web_state/web_state_delegate_stub.mm b/ios/web/public/test/crw_mock_web_state_delegate.mm similarity index 95% rename from ios/web/web_state/web_state_delegate_stub.mm rename to ios/web/public/test/crw_mock_web_state_delegate.mm index 05e53fb..6b8b15a 100644 --- a/ios/web/web_state/web_state_delegate_stub.mm +++ b/ios/web/public/test/crw_mock_web_state_delegate.mm
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/web/web_state/web_state_delegate_stub.h" +#import "ios/web/public/test/crw_mock_web_state_delegate.h" -#import "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/context_menu_params.h" +#import "ios/web/public/web_state/web_state.h" -@implementation CRWWebStateDelegateStub { +@implementation CRWMockWebStateDelegate { // Backs up the property with the same name. std::unique_ptr<web::WebState::OpenURLParams> _openURLParams; // Backs up the property with the same name.
diff --git a/ios/web/web_state/web_state_delegate_bridge_unittest.mm b/ios/web/web_state/web_state_delegate_bridge_unittest.mm index 1429a63b..fb7d4292 100644 --- a/ios/web/web_state/web_state_delegate_bridge_unittest.mm +++ b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
@@ -11,9 +11,9 @@ #include "base/mac/bind_objc_block.h" #import "base/mac/scoped_nsobject.h" #include "base/strings/utf_string_conversions.h" +#import "ios/web/public/test/crw_mock_web_state_delegate.h" #import "ios/web/public/test/fakes/test_web_state.h" #import "ios/web/public/web_state/context_menu_params.h" -#import "ios/web/web_state/web_state_delegate_stub.h" #include "testing/platform_test.h" #import "third_party/ocmock/gtest_support.h" #include "ui/base/page_transition_types.h" @@ -35,7 +35,7 @@ id originalMockDelegate = [OCMockObject niceMockForProtocol:@protocol(CRWWebStateDelegate)]; - delegate_.reset([[CRWWebStateDelegateStub alloc] + delegate_.reset([[CRWMockWebStateDelegate alloc] initWithRepresentedObject:originalMockDelegate]); empty_delegate_.reset([[TestEmptyWebStateDelegate alloc] init]);
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index d8feb667..489d3246 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1881,18 +1881,18 @@ crbug.com/626703 external/csswg-test/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/logical-physical-mapping-001.html [ Failure ] crbug.com/626703 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-menu.html [ Failure ] crbug.com/626703 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-skip-no-boxes.html [ Failure ] -crbug.com/626703 external/wpt/streams/count-queuing-strategy.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/bad-strategies.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/bad-underlying-sources.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/brand-checks.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/cancel.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/count-queuing-strategy-integration.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/garbage-collection.https.html [ Timeout Failure ] +crbug.com/626703 external/wpt/streams/count-queuing-strategy.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/bad-strategies.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/bad-underlying-sources.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/brand-checks.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/cancel.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/count-queuing-strategy-integration.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/garbage-collection.https.html [ Pass Timeout ] crbug.com/626703 external/wpt/streams/readable-streams/general.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/pipe-through.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/readable-stream-reader.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/tee.https.html [ Timeout Failure ] -crbug.com/626703 external/wpt/streams/readable-streams/templated.https.html [ Timeout Failure ] +crbug.com/626703 external/wpt/streams/readable-streams/pipe-through.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/readable-stream-reader.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/tee.https.html [ Pass Timeout ] +crbug.com/626703 external/wpt/streams/readable-streams/templated.https.html [ Pass Timeout ] crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-timeout.html [ Timeout ] crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-multiple-calls.html [ Timeout ] crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-exception.html [ Timeout ] @@ -2297,8 +2297,6 @@ # ====== End of display: contents tests ====== -crbug.com/682521 inspector/console/console-tests.html [ NeedsManualRebaseline ] - crbug.com/676229 [ Linux ] plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ] crbug.com/678346 [ Win7 Debug ] fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.dedicatedworker-expected.txt deleted file mode 100644 index be287d9..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.dedicatedworker-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -This is a testharness.js-based test. -FAIL Closing must be propagated backward: starts closed; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = undefined (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = null (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = false (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = 0 (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = -0 (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = NaN (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = a (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = 1 (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = Symbol() (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = [object Object] (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true, preventClose = true rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.https-expected.txt deleted file mode 100644 index be287d9..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.https-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -This is a testharness.js-based test. -FAIL Closing must be propagated backward: starts closed; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = undefined (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = null (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = false (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = 0 (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = -0 (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = NaN (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = a (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = 1 (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = Symbol() (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = [object Object] (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true, preventClose = true rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.sharedworker-expected.txt deleted file mode 100644 index be287d9..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-backward.sharedworker-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -This is a testharness.js-based test. -FAIL Closing must be propagated backward: starts closed; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = undefined (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = null (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = false (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = 0 (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = -0 (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = NaN (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = (falsy); fulfilled cancel promise rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = a (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = 1 (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = Symbol() (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = [object Object] (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true rs.pipeTo is not a function -FAIL Closing must be propagated backward: starts closed; preventCancel = true, preventAbort = true, preventClose = true rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.dedicatedworker-expected.txt deleted file mode 100644 index 1862e6d..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.dedicatedworker-expected.txt +++ /dev/null
@@ -1,29 +0,0 @@ -This is a testharness.js-based test. -FAIL Closing must be propagated forward: starts closed; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = undefined (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = null (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = false (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = 0 (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = -0 (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = NaN (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = a (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = 1 (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = Symbol() (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = [object Object] (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true, preventCancel = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.https-expected.txt deleted file mode 100644 index 1862e6d..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.https-expected.txt +++ /dev/null
@@ -1,29 +0,0 @@ -This is a testharness.js-based test. -FAIL Closing must be propagated forward: starts closed; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = undefined (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = null (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = false (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = 0 (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = -0 (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = NaN (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = a (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = 1 (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = Symbol() (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = [object Object] (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true, preventCancel = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.sharedworker-expected.txt deleted file mode 100644 index 1862e6d..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/close-propagation-forward.sharedworker-expected.txt +++ /dev/null
@@ -1,29 +0,0 @@ -This is a testharness.js-based test. -FAIL Closing must be propagated forward: starts closed; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = undefined (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = null (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = false (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = 0 (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = -0 (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = NaN (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = (falsy); fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = a (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = 1 (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = Symbol() (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = [object Object] (truthy) rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: starts closed; preventClose = true, preventAbort = true, preventCancel = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed asynchronously; dest never desires chunks; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; fulfilled close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose omitted; rejected close promise rs.pipeTo is not a function -FAIL Closing must be propagated forward: becomes closed after one chunk; preventClose = true rs.pipeTo is not a function -FAIL Closing must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.dedicatedworker-expected.txt deleted file mode 100644 index cb0fa19..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.dedicatedworker-expected.txt +++ /dev/null
@@ -1,38 +0,0 @@ -This is a testharness.js-based test. -FAIL Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; rejected cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = undefined (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = null (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = false (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = -0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = NaN (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = a (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 1 (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = Symbol() (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = [object Object] (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write, preventCancel = true; preventAbort = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true, preventAbort = true, preventClose = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel omitted (but cancel is never called) rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: erroring via the controller errors once pending write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.https-expected.txt deleted file mode 100644 index cb0fa19..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.https-expected.txt +++ /dev/null
@@ -1,38 +0,0 @@ -This is a testharness.js-based test. -FAIL Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; rejected cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = undefined (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = null (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = false (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = -0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = NaN (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = a (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 1 (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = Symbol() (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = [object Object] (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write, preventCancel = true; preventAbort = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true, preventAbort = true, preventClose = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel omitted (but cancel is never called) rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: erroring via the controller errors once pending write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.sharedworker-expected.txt deleted file mode 100644 index cb0fa19..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-backward.sharedworker-expected.txt +++ /dev/null
@@ -1,38 +0,0 @@ -This is a testharness.js-based test. -FAIL Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; rejected cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = undefined (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = null (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = false (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = -0 (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = NaN (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = (falsy); fulfilled cancel promise promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = a (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 1 (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = Symbol() (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = [object Object] (truthy) promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write, preventCancel = true; preventAbort = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true, preventAbort = true, preventClose = true promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = false; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel omitted (but cancel is never called) rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping due to last write; source is closed; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = false; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected cancel promise rs.pipeTo is not a function -FAIL Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated backward: erroring via the controller errors once pending write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.dedicatedworker-expected.txt deleted file mode 100644 index cc9c3ef2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.dedicatedworker-expected.txt +++ /dev/null
@@ -1,32 +0,0 @@ -This is a testharness.js-based test. -FAIL Errors must be propagated forward: starts errored; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = undefined (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = null (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = false (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = 0 (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = -0 (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = NaN (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = a (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = 1 (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = Symbol() (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = [object Object] (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true, preventClose = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.https-expected.txt deleted file mode 100644 index cc9c3ef2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.https-expected.txt +++ /dev/null
@@ -1,32 +0,0 @@ -This is a testharness.js-based test. -FAIL Errors must be propagated forward: starts errored; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = undefined (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = null (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = false (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = 0 (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = -0 (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = NaN (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = a (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = 1 (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = Symbol() (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = [object Object] (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true, preventClose = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.sharedworker-expected.txt deleted file mode 100644 index cc9c3ef2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/error-propagation-forward.sharedworker-expected.txt +++ /dev/null
@@ -1,32 +0,0 @@ -This is a testharness.js-based test. -FAIL Errors must be propagated forward: starts errored; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = undefined (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = null (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = false (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = 0 (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = -0 (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = NaN (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = (falsy); fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = a (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = 1 (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = Symbol() (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = [object Object] (truthy) rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: starts errored; preventAbort = true, preventCancel = true, preventClose = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored while empty; dest never desires chunks; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; fulfilled abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = false; rejected abort promise rs.pipeTo is not a function -FAIL Errors must be propagated forward: becomes errored after one chunk; dest never desires chunks; preventAbort = true rs.pipeTo is not a function -FAIL Errors must be propagated forward: shutdown must not occur until the final write completes rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.dedicatedworker-expected.txt deleted file mode 100644 index 82ac6f2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.dedicatedworker-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks rs.pipeTo is not a function -FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks, but then does rs.pipeTo is not a function -FAIL Piping from an empty ReadableStream into a WritableStream that does not desire chunks, but then the readable stream becomes non-empty and the writable stream starts desiring chunks promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Piping to a WritableStream that does not consume the writes fast enough exerts backpressure on the ReadableStream promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.https-expected.txt deleted file mode 100644 index 82ac6f2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.https-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks rs.pipeTo is not a function -FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks, but then does rs.pipeTo is not a function -FAIL Piping from an empty ReadableStream into a WritableStream that does not desire chunks, but then the readable stream becomes non-empty and the writable stream starts desiring chunks promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Piping to a WritableStream that does not consume the writes fast enough exerts backpressure on the ReadableStream promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.sharedworker-expected.txt deleted file mode 100644 index 82ac6f2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/flow-control.sharedworker-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks rs.pipeTo is not a function -FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks, but then does rs.pipeTo is not a function -FAIL Piping from an empty ReadableStream into a WritableStream that does not desire chunks, but then the readable stream becomes non-empty and the writable stream starts desiring chunks promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -FAIL Piping to a WritableStream that does not consume the writes fast enough exerts backpressure on the ReadableStream promise_test: Unhandled rejection with value: object "TypeError: rs.pipeTo is not a function" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.dedicatedworker-expected.txt deleted file mode 100644 index cb4eb742..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.dedicatedworker-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping must lock both the ReadableStream and WritableStream rs.pipeTo is not a function -FAIL Piping finishing must unlock both the ReadableStream and WritableStream rs.pipeTo is not a function -FAIL pipeTo must check the brand of its ReadableStream this value Cannot read property 'apply' of undefined -FAIL pipeTo must check the brand of its WritableStream argument Cannot read property 'apply' of undefined -FAIL pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream rs.pipeTo is not a function -FAIL pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream rs.pipeTo is not a function -FAIL Piping from a ReadableStream from which lots of chunks are synchronously readable rs.pipeTo is not a function -FAIL Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo rs.pipeTo is not a function -FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is true rs.pipeTo is not a function -FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is false rs.pipeTo is not a function -FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is true rs.pipeTo is not a function -FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is false rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.https-expected.txt deleted file mode 100644 index cb4eb742..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.https-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping must lock both the ReadableStream and WritableStream rs.pipeTo is not a function -FAIL Piping finishing must unlock both the ReadableStream and WritableStream rs.pipeTo is not a function -FAIL pipeTo must check the brand of its ReadableStream this value Cannot read property 'apply' of undefined -FAIL pipeTo must check the brand of its WritableStream argument Cannot read property 'apply' of undefined -FAIL pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream rs.pipeTo is not a function -FAIL pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream rs.pipeTo is not a function -FAIL Piping from a ReadableStream from which lots of chunks are synchronously readable rs.pipeTo is not a function -FAIL Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo rs.pipeTo is not a function -FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is true rs.pipeTo is not a function -FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is false rs.pipeTo is not a function -FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is true rs.pipeTo is not a function -FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is false rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.sharedworker-expected.txt deleted file mode 100644 index cb4eb742..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/general.sharedworker-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping must lock both the ReadableStream and WritableStream rs.pipeTo is not a function -FAIL Piping finishing must unlock both the ReadableStream and WritableStream rs.pipeTo is not a function -FAIL pipeTo must check the brand of its ReadableStream this value Cannot read property 'apply' of undefined -FAIL pipeTo must check the brand of its WritableStream argument Cannot read property 'apply' of undefined -FAIL pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream rs.pipeTo is not a function -FAIL pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream rs.pipeTo is not a function -FAIL Piping from a ReadableStream from which lots of chunks are synchronously readable rs.pipeTo is not a function -FAIL Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo rs.pipeTo is not a function -FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is true rs.pipeTo is not a function -FAIL an undefined rejection from pull should cause pipeTo() to reject when preventAbort is false rs.pipeTo is not a function -FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is true rs.pipeTo is not a function -FAIL an undefined rejection from write should cause pipeTo() to reject when preventCancel is false rs.pipeTo is not a function -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.dedicatedworker-expected.txt index 859fcbe9..cfd2234 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.dedicatedworker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.dedicatedworker-expected.txt
@@ -1,8 +1,9 @@ +CONSOLE ERROR: line 77: Uncaught (in promise) TypeError: The stream has been aborted This is a testharness.js-based test. -FAIL Piping from an errored readable stream to an errored writable stream rs.pipeTo is not a function -FAIL Piping from an errored readable stream to an errored writable stream; preventAbort = true rs.pipeTo is not a function -FAIL Piping from an errored readable stream to a closed writable stream rs.pipeTo is not a function -FAIL Piping from a closed readable stream to an errored writable stream rs.pipeTo is not a function -FAIL Piping from a closed readable stream to a closed writable stream rs.pipeTo is not a function +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 +FAIL Piping from an errored readable stream to a closed writable stream assert_array_equals: lengths differ, expected 1 got 2 +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/external/wpt/streams/piping/multiple-propagation.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.https-expected.txt index 859fcbe9..cfd2234 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.https-expected.txt
@@ -1,8 +1,9 @@ +CONSOLE ERROR: line 77: Uncaught (in promise) TypeError: The stream has been aborted This is a testharness.js-based test. -FAIL Piping from an errored readable stream to an errored writable stream rs.pipeTo is not a function -FAIL Piping from an errored readable stream to an errored writable stream; preventAbort = true rs.pipeTo is not a function -FAIL Piping from an errored readable stream to a closed writable stream rs.pipeTo is not a function -FAIL Piping from a closed readable stream to an errored writable stream rs.pipeTo is not a function -FAIL Piping from a closed readable stream to a closed writable stream rs.pipeTo is not a function +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 +FAIL Piping from an errored readable stream to a closed writable stream assert_array_equals: lengths differ, expected 1 got 2 +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/external/wpt/streams/piping/multiple-propagation.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.sharedworker-expected.txt index 859fcbe9..32b3cd1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.sharedworker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/multiple-propagation.sharedworker-expected.txt
@@ -1,8 +1,8 @@ This is a testharness.js-based test. -FAIL Piping from an errored readable stream to an errored writable stream rs.pipeTo is not a function -FAIL Piping from an errored readable stream to an errored writable stream; preventAbort = true rs.pipeTo is not a function -FAIL Piping from an errored readable stream to a closed writable stream rs.pipeTo is not a function -FAIL Piping from a closed readable stream to an errored writable stream rs.pipeTo is not a function -FAIL Piping from a closed readable stream to a closed writable stream rs.pipeTo is not a function +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 +FAIL Piping from an errored readable stream to a closed writable stream assert_array_equals: lengths differ, expected 1 got 2 +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/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt deleted file mode 100644 index 0afae02..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping through a duck-typed pass-through transform stream should work sequentialReadableStream(...).pipeThrough is not a function -FAIL Piping through a transform errored on the writable end does not cause an unhandled promise rejection sequentialReadableStream(...).pipeThrough is not a function -FAIL pipeThrough generically calls pipeTo with the appropriate args Cannot read property 'call' of undefined -FAIL pipeThrough can handle calling a pipeTo that returns a non-promise object Cannot read property 'call' of undefined -FAIL pipeThrough can handle calling a pipeTo that returns a non-promise thenable object Cannot read property 'call' of undefined -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.https-expected.txt deleted file mode 100644 index 0afae02..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.https-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping through a duck-typed pass-through transform stream should work sequentialReadableStream(...).pipeThrough is not a function -FAIL Piping through a transform errored on the writable end does not cause an unhandled promise rejection sequentialReadableStream(...).pipeThrough is not a function -FAIL pipeThrough generically calls pipeTo with the appropriate args Cannot read property 'call' of undefined -FAIL pipeThrough can handle calling a pipeTo that returns a non-promise object Cannot read property 'call' of undefined -FAIL pipeThrough can handle calling a pipeTo that returns a non-promise thenable object Cannot read property 'call' of undefined -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt deleted file mode 100644 index 0afae02..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -FAIL Piping through a duck-typed pass-through transform stream should work sequentialReadableStream(...).pipeThrough is not a function -FAIL Piping through a transform errored on the writable end does not cause an unhandled promise rejection sequentialReadableStream(...).pipeThrough is not a function -FAIL pipeThrough generically calls pipeTo with the appropriate args Cannot read property 'call' of undefined -FAIL pipeThrough can handle calling a pipeTo that returns a non-promise object Cannot read property 'call' of undefined -FAIL pipeThrough can handle calling a pipeTo that returns a non-promise thenable object Cannot read property 'call' of undefined -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt index d2b57a8..aa3e4e49 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt
@@ -2,7 +2,7 @@ PASS ReadableStream can be constructed with no errors PASS ReadableStream can't be constructed with garbage PASS ReadableStream can't be constructed with an invalid type -FAIL ReadableStream instances should have the correct list of properties assert_array_equals: should have all the correct methods lengths differ, expected 7 got 5 +PASS ReadableStream instances should have the correct list of properties PASS ReadableStream constructor should throw for non-function start arguments PASS ReadableStream constructor can get initial garbage as cancel argument PASS ReadableStream constructor can get initial garbage as pull argument
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt index d2b57a8..aa3e4e49 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt
@@ -2,7 +2,7 @@ PASS ReadableStream can be constructed with no errors PASS ReadableStream can't be constructed with garbage PASS ReadableStream can't be constructed with an invalid type -FAIL ReadableStream instances should have the correct list of properties assert_array_equals: should have all the correct methods lengths differ, expected 7 got 5 +PASS ReadableStream instances should have the correct list of properties PASS ReadableStream constructor should throw for non-function start arguments PASS ReadableStream constructor can get initial garbage as cancel argument PASS ReadableStream constructor can get initial garbage as pull argument
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.dedicatedworker-expected.txt deleted file mode 100644 index d1308fd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.dedicatedworker-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStream.prototype.pipeThrough should work generically on its this and its arguments Cannot read property 'call' of undefined -PASS ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object -PASS ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method -FAIL ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable assert_throws: pipeThrough should rethrow the error thrown by pipeTo function "() => ReadableStream.prototype.pipeThrough.call(throwingPipeTo, { readable: { }, writable: { } }, {})" threw object "TypeError: Cannot read property 'call' of undefined" ("TypeError") expected object "Error: potato" ("Error") -FAIL ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options Cannot read property 'call' of undefined -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.sharedworker-expected.txt deleted file mode 100644 index d1308fd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/pipe-through.sharedworker-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStream.prototype.pipeThrough should work generically on its this and its arguments Cannot read property 'call' of undefined -PASS ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object -PASS ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method -FAIL ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable assert_throws: pipeThrough should rethrow the error thrown by pipeTo function "() => ReadableStream.prototype.pipeThrough.call(throwingPipeTo, { readable: { }, writable: { } }, {})" threw object "TypeError: Cannot read property 'call' of undefined" ("TypeError") expected object "Error: potato" ("Error") -FAIL ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options Cannot read property 'call' of undefined -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.dedicatedworker-expected.txt deleted file mode 100644 index 927ae8ef..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.dedicatedworker-expected.txt +++ /dev/null
@@ -1,89 +0,0 @@ -This is a testharness.js-based test. -PASS Running templatedRSEmpty with ReadableStream (empty) -FAIL ReadableStream (empty): instances have the correct methods and properties assert_equals: has a pipeThrough method expected "function" but got "undefined" -PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors -PASS Running templatedRSEmptyReader with ReadableStream (empty) reader -PASS ReadableStream (empty) reader: instances have the correct methods and properties -PASS ReadableStream (empty) reader: locked should be true -PASS ReadableStream (empty) reader: read() should never settle -PASS ReadableStream (empty) reader: two read()s should both never settle -PASS ReadableStream (empty) reader: read() should return distinct promises each time -PASS ReadableStream (empty) reader: getReader() again on the stream should fail -PASS ReadableStream (empty) reader: releasing the lock with pending read requests should throw but the read requests should stay pending -PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError -PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError -PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false -PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed -PASS ReadableStream (empty) reader: canceling via the stream should fail -PASS Running templatedRSClosed with ReadableStream (closed via call in start) -PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time -PASS ReadableStream (closed via call in start): locked should be false -PASS ReadableStream (closed via call in start): getReader() should be OK -PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession -PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one -PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader) -PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback -PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined -PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time -PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader) -PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback -PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined -PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time -PASS Running templatedRSClosed with ReadableStream (closed via cancel) -PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time -PASS ReadableStream (closed via cancel): locked should be false -PASS ReadableStream (closed via cancel): getReader() should be OK -PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession -PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one -PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader) -PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback -PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined -PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time -PASS Running templatedRSErrored with ReadableStream (errored via call in start) -PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored -PASS ReadableStream (errored via call in start): read() twice should give the error each time -PASS ReadableStream (errored via call in start): locked should be false -PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start) -PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise -PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock -PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time -PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time -PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start) -PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored -PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time -PASS ReadableStream (errored via returning a rejected promise in start): locked should be false -PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader -PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error -PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity -PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error -PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader) -PASS ReadableStream reader (errored before getting reader): closed should reject with the error -PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (errored before getting reader): read() should reject with the error -PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader) -PASS ReadableStream reader (errored after getting reader): closed should reject with the error -PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (errored after getting reader): read() should reject with the error -PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader -PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential) -PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested) -PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time -PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result -PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader -PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential) -PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested) -PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true -PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false -PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError -PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.sharedworker-expected.txt deleted file mode 100644 index 927ae8ef..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/templated.sharedworker-expected.txt +++ /dev/null
@@ -1,89 +0,0 @@ -This is a testharness.js-based test. -PASS Running templatedRSEmpty with ReadableStream (empty) -FAIL ReadableStream (empty): instances have the correct methods and properties assert_equals: has a pipeThrough method expected "function" but got "undefined" -PASS ReadableStream (empty): calling getReader with invalid arguments should throw appropriate errors -PASS Running templatedRSEmptyReader with ReadableStream (empty) reader -PASS ReadableStream (empty) reader: instances have the correct methods and properties -PASS ReadableStream (empty) reader: locked should be true -PASS ReadableStream (empty) reader: read() should never settle -PASS ReadableStream (empty) reader: two read()s should both never settle -PASS ReadableStream (empty) reader: read() should return distinct promises each time -PASS ReadableStream (empty) reader: getReader() again on the stream should fail -PASS ReadableStream (empty) reader: releasing the lock with pending read requests should throw but the read requests should stay pending -PASS ReadableStream (empty) reader: releasing the lock should cause further read() calls to reject with a TypeError -PASS ReadableStream (empty) reader: releasing the lock should cause closed calls to reject with a TypeError -PASS ReadableStream (empty) reader: releasing the lock should cause locked to become false -PASS ReadableStream (empty) reader: canceling via the reader should cause the reader to act closed -PASS ReadableStream (empty) reader: canceling via the stream should fail -PASS Running templatedRSClosed with ReadableStream (closed via call in start) -PASS ReadableStream (closed via call in start): cancel() should return a distinct fulfilled promise each time -PASS ReadableStream (closed via call in start): locked should be false -PASS ReadableStream (closed via call in start): getReader() should be OK -PASS ReadableStream (closed via call in start): should be able to acquire multiple readers if they are released in succession -PASS ReadableStream (closed via call in start): should not be able to acquire a second reader if we don't release the first one -PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader) -PASS ReadableStream reader (closed before getting reader): read() should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed before getting reader): read() multiple times should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed before getting reader): read() should work when used within another read() fulfill callback -PASS ReadableStream reader (closed before getting reader): closed should fulfill with undefined -PASS ReadableStream reader (closed before getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (closed before getting reader): cancel() should return a distinct fulfilled promise each time -PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader) -PASS ReadableStream reader (closed after getting reader): read() should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed after getting reader): read() multiple times should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed after getting reader): read() should work when used within another read() fulfill callback -PASS ReadableStream reader (closed after getting reader): closed should fulfill with undefined -PASS ReadableStream reader (closed after getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (closed after getting reader): cancel() should return a distinct fulfilled promise each time -PASS Running templatedRSClosed with ReadableStream (closed via cancel) -PASS ReadableStream (closed via cancel): cancel() should return a distinct fulfilled promise each time -PASS ReadableStream (closed via cancel): locked should be false -PASS ReadableStream (closed via cancel): getReader() should be OK -PASS ReadableStream (closed via cancel): should be able to acquire multiple readers if they are released in succession -PASS ReadableStream (closed via cancel): should not be able to acquire a second reader if we don't release the first one -PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader) -PASS ReadableStream reader (closed via cancel after getting reader): read() should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed via cancel after getting reader): read() multiple times should fulfill with { value: undefined, done: true } -PASS ReadableStream reader (closed via cancel after getting reader): read() should work when used within another read() fulfill callback -PASS ReadableStream reader (closed via cancel after getting reader): closed should fulfill with undefined -PASS ReadableStream reader (closed via cancel after getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (closed via cancel after getting reader): cancel() should return a distinct fulfilled promise each time -PASS Running templatedRSErrored with ReadableStream (errored via call in start) -PASS ReadableStream (errored via call in start): getReader() should return a reader that acts errored -PASS ReadableStream (errored via call in start): read() twice should give the error each time -PASS ReadableStream (errored via call in start): locked should be false -PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start) -PASS ReadableStream (errored via call in start): should be able to obtain a second reader, with the correct closed promise -PASS ReadableStream (errored via call in start): should not be able to obtain additional readers if we don't release the first lock -PASS ReadableStream (errored via call in start): cancel() should return a distinct rejected promise each time -PASS ReadableStream (errored via call in start): reader cancel() should return a distinct rejected promise each time -PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start) -PASS ReadableStream (errored via returning a rejected promise in start): getReader() should return a reader that acts errored -PASS ReadableStream (errored via returning a rejected promise in start): read() twice should give the error each time -PASS ReadableStream (errored via returning a rejected promise in start): locked should be false -PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader -PASS ReadableStream (errored via returning a rejected promise in start) reader: closed should reject with the error -PASS ReadableStream (errored via returning a rejected promise in start) reader: releasing the lock should cause closed to reject and change identity -PASS ReadableStream (errored via returning a rejected promise in start) reader: read() should reject with the error -PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader) -PASS ReadableStream reader (errored before getting reader): closed should reject with the error -PASS ReadableStream reader (errored before getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (errored before getting reader): read() should reject with the error -PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader) -PASS ReadableStream reader (errored after getting reader): closed should reject with the error -PASS ReadableStream reader (errored after getting reader): releasing the lock should cause closed to reject and change identity -PASS ReadableStream reader (errored after getting reader): read() should reject with the error -PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader -PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (sequential) -PASS ReadableStream (two chunks enqueued, still open) reader: calling read() twice without waiting will eventually give both chunks (nested) -PASS ReadableStream (two chunks enqueued, still open) reader: read() should return distinct promises each time -PASS ReadableStream (two chunks enqueued, still open) reader: cancel() after a read() should still give that single read result -PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader -PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (sequential) -PASS ReadableStream (two chunks enqueued, then closed) reader: third read(), without waiting, should give { value: undefined, done: true } (nested) -PASS ReadableStream (two chunks enqueued, then closed) reader: draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true -PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock after the stream is closed should cause locked to become false -PASS ReadableStream (two chunks enqueued, then closed) reader: releasing the lock should cause further read() calls to reject with a TypeError -PASS ReadableStream (two chunks enqueued, then closed) reader: reader's closed property always returns the same promise -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt index 4cb1eda8..34ce22c6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/debugger/async-callstack-network-initiator-expected.txt
@@ -1,4 +1,3 @@ -CONSOLE MESSAGE: line 11: console.clear Tests asynchronous call stacks printed in console for a Network.Initiator. Set timer for test function.
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index f0fc9305..9f14b26 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -217,6 +217,25 @@ method toString method transformPoint method translate +interface DOMPoint : DOMPointReadOnly + getter w + getter x + getter y + getter z + method constructor + setter w + setter x + setter y + setter z +interface DOMPointReadOnly + static method fromPoint + getter w + getter x + getter y + getter z + method constructor + method matrixTransform + method toJSON interface DOMStringList getter length method constructor @@ -735,6 +754,8 @@ method cancel method constructor method getReader + method pipeThrough + method pipeTo method tee interface Request getter bodyUsed
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 new file mode 100644 index 0000000..c7951db8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.https.html
@@ -0,0 +1,14 @@ +<!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 new file mode 100644 index 0000000..2c7fd141 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/piping/multiple-propagation.js
@@ -0,0 +1,139 @@ +'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/http/tests/streams/readable-streams/general.js b/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/general.js index 28c0c10..288fcce 100644 --- a/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/general.js +++ b/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/general.js
@@ -37,7 +37,7 @@ test(() => { - const methods = ['cancel', 'constructor', 'getReader', 'tee']; + const methods = ['cancel', 'constructor', 'getReader', 'pipeThrough', 'pipeTo', 'tee']; const properties = methods.concat(['locked']).sort(); const rs = new ReadableStream();
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt index 53baf8a..ba11504 100644 --- a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
@@ -242,6 +242,8 @@ CONSOLE MESSAGE: line 138: method cancel CONSOLE MESSAGE: line 138: method constructor CONSOLE MESSAGE: line 138: method getReader +CONSOLE MESSAGE: line 138: method pipeThrough +CONSOLE MESSAGE: line 138: method pipeTo CONSOLE MESSAGE: line 138: method tee CONSOLE MESSAGE: line 138: interface StylePropertyMap CONSOLE MESSAGE: line 138: method append
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt index d2bbb2c..816acea 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/console/console-clear-function-expected.txt
@@ -1,7 +1,6 @@ CONSOLE MESSAGE: line 10: one CONSOLE MESSAGE: line 11: two CONSOLE MESSAGE: line 12: three -CONSOLE MESSAGE: line 19: console.clear Tests that console is cleared via console.clear() method Bug 101021
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-command-clear-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-command-clear-expected.txt index 75760b6..dc9c35e 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-command-clear-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/console/console-command-clear-expected.txt
@@ -1,7 +1,6 @@ CONSOLE MESSAGE: line 9: one CONSOLE MESSAGE: line 10: two CONSOLE MESSAGE: line 11: three -CONSOLE MESSAGE: line 1: console.clear Tests that console is cleared upon clear() eval in console. === Before clear ===
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-tests-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-tests-expected.txt index 436df7dc..0644e98 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-tests-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/console/console-tests-expected.txt
@@ -41,15 +41,15 @@ console-tests.html:13 error onload @ console-tests.html:13 console-message-wrapper console-error-level > console-message 5console-tests.html:15 repeated console-message-wrapper console-info-level > console-message repeated-message -console-tests.html:17 count: 1 console-message-wrapper console-verbose-level > console-message -console-tests.html:17 count: 2 console-message-wrapper console-verbose-level > console-message +console-tests.html:17 count: 1 console-message-wrapper console-info-level > console-message +console-tests.html:17 count: 2 console-message-wrapper console-info-level > console-message console-tests.html:18 group console-message-wrapper console-info-level > console-message console-group-title console-tests.html:20 1 2 3 console-message-wrapper console-info-level > console-message console-tests.html:21 groupCollapsed console-message-wrapper console-info-level > console-message console-group-title -console-tests.html:33 : 1 console-message-wrapper console-verbose-level > console-message -console-tests.html:34 : 1 console-message-wrapper console-verbose-level > console-message -console-tests.html:35 : 1 console-message-wrapper console-verbose-level > console-message -console-tests.html:36 title: 1 console-message-wrapper console-verbose-level > console-message -console-tests.html:37 title: 2 console-message-wrapper console-verbose-level > console-message -console-tests.html:38 title: 3 console-message-wrapper console-verbose-level > console-message +console-tests.html:33 : 1 console-message-wrapper console-info-level > console-message +console-tests.html:34 : 1 console-message-wrapper console-info-level > console-message +console-tests.html:35 : 1 console-message-wrapper console-info-level > console-message +console-tests.html:36 title: 1 console-message-wrapper console-info-level > console-message +console-tests.html:37 title: 2 console-message-wrapper console-info-level > console-message +console-tests.html:38 title: 3 console-message-wrapper console-info-level > console-message
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-callstack-in-console-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-callstack-in-console-expected.txt index 372acb7..1b0ffa1 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-callstack-in-console-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-async/async-callstack-in-console-expected.txt
@@ -1,4 +1,3 @@ -CONSOLE MESSAGE: line 11: console.clear CONSOLE MESSAGE: line 17: console.trace CONSOLE ERROR: line 24: Uncaught Error: foo CONSOLE MESSAGE: line 29: console.trace
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt index 9e8fd33..eaf8908 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt
@@ -1,4 +1,3 @@ -CONSOLE MESSAGE: line 11: console.clear CONSOLE ERROR: line 25: Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. CONSOLE ERROR: line 20: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. CONSOLE ERROR: line 25: Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'.
diff --git a/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-reconstruction-document-write.html b/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-reconstruction-document-write.html new file mode 100644 index 0000000..f2390975 --- /dev/null +++ b/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-reconstruction-document-write.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<iframe></iframe> +<script> + +function writeDoc() { + var doc = document.querySelector("iframe").contentDocument; + doc.open(); + doc.write(` + <style> + ::-webkit-scrollbar-thumb { background-color: blue; } + ::-webkit-scrollbar { width: 50px; height: 50px; } + body { height: 400px; overflow: scroll; } + </style>`); + doc.close(); + assert_equals(doc.documentElement.offsetWidth, 250); +} + +test(() => { + writeDoc(); + writeDoc(); +}, "Preserve iframe custom scrollbar after replacing contents with document.write."); + +</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 9c59386..20069ec2 100644 --- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -217,6 +217,25 @@ method toString method transformPoint method translate +interface DOMPoint : DOMPointReadOnly + getter w + getter x + getter y + getter z + method constructor + setter w + setter x + setter y + setter z +interface DOMPointReadOnly + static method fromPoint + getter w + getter x + getter y + getter z + method constructor + method matrixTransform + method toJSON interface DOMStringList getter length method constructor @@ -742,6 +761,8 @@ method cancel method constructor method getReader + method pipeThrough + method pipeTo method tee interface Request getter bodyUsed
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt index 9cb32d2..919ec9e6 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt
@@ -55,6 +55,8 @@ [Worker] method cancel [Worker] method constructor [Worker] method getReader +[Worker] method pipeThrough +[Worker] method pipeTo [Worker] method tee [Worker] interface WritableStream [Worker] getter locked
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt index bf1e2d4..a0f69402 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -228,6 +228,27 @@ [Worker] method toString [Worker] method transformPoint [Worker] method translate +[Worker] interface DOMPoint : DOMPointReadOnly +[Worker] attribute @@toStringTag +[Worker] getter w +[Worker] getter x +[Worker] getter y +[Worker] getter z +[Worker] method constructor +[Worker] setter w +[Worker] setter x +[Worker] setter y +[Worker] setter z +[Worker] interface DOMPointReadOnly +[Worker] static method fromPoint +[Worker] attribute @@toStringTag +[Worker] getter w +[Worker] getter x +[Worker] getter y +[Worker] getter z +[Worker] method constructor +[Worker] method matrixTransform +[Worker] method toJSON [Worker] interface DOMStringList [Worker] attribute @@toStringTag [Worker] getter length @@ -743,6 +764,8 @@ [Worker] method cancel [Worker] method constructor [Worker] method getReader +[Worker] method pipeThrough +[Worker] method pipeTo [Worker] method tee [Worker] interface Request [Worker] attribute @@toStringTag
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 40866062..422fe01 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -5015,6 +5015,8 @@ method cancel method constructor method getReader + method pipeThrough + method pipeTo method tee interface RelatedApplication attribute @@toStringTag
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt index 2be997b..8100512 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -228,6 +228,27 @@ [Worker] method toString [Worker] method transformPoint [Worker] method translate +[Worker] interface DOMPoint : DOMPointReadOnly +[Worker] attribute @@toStringTag +[Worker] getter w +[Worker] getter x +[Worker] getter y +[Worker] getter z +[Worker] method constructor +[Worker] setter w +[Worker] setter x +[Worker] setter y +[Worker] setter z +[Worker] interface DOMPointReadOnly +[Worker] static method fromPoint +[Worker] attribute @@toStringTag +[Worker] getter w +[Worker] getter x +[Worker] getter y +[Worker] getter z +[Worker] method constructor +[Worker] method matrixTransform +[Worker] method toJSON [Worker] interface DOMStringList [Worker] attribute @@toStringTag [Worker] getter length @@ -738,6 +759,8 @@ [Worker] method cancel [Worker] method constructor [Worker] method getReader +[Worker] method pipeThrough +[Worker] method pipeTo [Worker] method tee [Worker] interface Request [Worker] attribute @@toStringTag
diff --git a/third_party/WebKit/Source/core/css/CSSMarkup.cpp b/third_party/WebKit/Source/core/css/CSSMarkup.cpp index 3a1b9e6..ce56f45 100644 --- a/third_party/WebKit/Source/core/css/CSSMarkup.cpp +++ b/third_party/WebKit/Source/core/css/CSSMarkup.cpp
@@ -77,7 +77,7 @@ static void serializeCharacterAsCodePoint(UChar32 c, StringBuilder& appendTo) { appendTo.append('\\'); - appendUnsignedAsHex(c, appendTo, Lowercase); + HexNumber::appendUnsignedAsHex(c, appendTo, HexNumber::Lowercase); appendTo.append(' '); }
diff --git a/third_party/WebKit/Source/core/dom/DOMPoint.idl b/third_party/WebKit/Source/core/dom/DOMPoint.idl index 737f446..78672b8 100644 --- a/third_party/WebKit/Source/core/dom/DOMPoint.idl +++ b/third_party/WebKit/Source/core/dom/DOMPoint.idl
@@ -7,7 +7,7 @@ [ Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0, optional unrestricted double z = 0, optional unrestricted double w = 1), - // FIXME: Exposed=(Window,Worker) + Exposed=(Window,Worker), RuntimeEnabled=GeometryInterfaces, ] interface DOMPoint : DOMPointReadOnly { [NewObject] static DOMPoint fromPoint(optional DOMPointInit other);
diff --git a/third_party/WebKit/Source/core/dom/DOMPointReadOnly.idl b/third_party/WebKit/Source/core/dom/DOMPointReadOnly.idl index 7c381bdd..f1b0d0b 100644 --- a/third_party/WebKit/Source/core/dom/DOMPointReadOnly.idl +++ b/third_party/WebKit/Source/core/dom/DOMPointReadOnly.idl
@@ -7,7 +7,7 @@ [ Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0, optional unrestricted double z = 0, optional unrestricted double w = 1), - // FIXME: Exposed=(Window,Worker) + Exposed=(Window,Worker), RuntimeEnabled=GeometryInterfaces, ] interface DOMPointReadOnly { [NewObject] static DOMPointReadOnly fromPoint(optional DOMPointInit other);
diff --git a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp index c7ea4712..4293ed153 100644 --- a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp +++ b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
@@ -269,8 +269,10 @@ for (const auto& coalescedMouseEvent : coalescedMouseEvents) { DCHECK_EQ(mouseEvent.pointerProperties().id, coalescedMouseEvent.pointerProperties().id); - DCHECK_EQ(mouseEvent.pointerProperties().pointerType, - coalescedMouseEvent.pointerProperties().pointerType); + // TODO(crbug.com/684292): We need further investigation of why the + // following DCHECK fails. + // DCHECK_EQ(mouseEvent.pointerProperties().pointerType, + // coalescedMouseEvent.pointerProperties().pointerType); PointerEventInit coalescedEventInit = pointerEventInit; updateMousePointerEventInit(coalescedMouseEvent, view, &coalescedEventInit);
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index 530e1224..fed6ff0 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -639,9 +639,6 @@ m_frame->isMainFrame()) return false; } - - // FIXME: We need to update the scrollbar dynamically as documents change (or - // as doc elements and bodies get discovered that have custom styles). Document* doc = m_frame->document(); // Try the <body> element first as a scrollbar source. @@ -4089,15 +4086,32 @@ } bool FrameView::needsScrollbarReconstruction() const { - Element* customScrollbarElement = nullptr; - bool shouldUseCustom = shouldUseCustomScrollbars(customScrollbarElement); - - bool hasAnyScrollbar = horizontalScrollbar() || verticalScrollbar(); - bool hasCustom = - (horizontalScrollbar() && horizontalScrollbar()->isCustomScrollbar()) || - (verticalScrollbar() && verticalScrollbar()->isCustomScrollbar()); - - return hasAnyScrollbar && (shouldUseCustom != hasCustom); + Scrollbar* scrollbar = horizontalScrollbar(); + if (!scrollbar) + scrollbar = verticalScrollbar(); + if (!scrollbar) { + // We have no scrollbar to reconstruct. + return false; + } + Element* styleSource = nullptr; + bool needsCustom = shouldUseCustomScrollbars(styleSource); + bool isCustom = scrollbar->isCustomScrollbar(); + if (needsCustom != isCustom) { + // We have a native scrollbar that should be custom, or vice versa. + return true; + } + if (!needsCustom) { + // We have a native scrollbar that should remain native. + return false; + } + DCHECK(needsCustom && isCustom); + DCHECK(styleSource); + if (toLayoutScrollbar(scrollbar)->owningLayoutObject() != + styleSource->layoutObject()) { + // We have a custom scrollbar with a stale m_owner. + return true; + } + return false; } bool FrameView::shouldIgnoreOverflowHidden() const {
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h index b427e64..7de27821 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.h +++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -979,7 +979,7 @@ bool shouldUseCustomScrollbars(Element*& customScrollbarElement) const; // Returns true if a scrollbar needs to go from native -> custom or vice - // versa. + // versa, or if a custom scrollbar has a stale owner. bool needsScrollbarReconstruction() const; bool shouldIgnoreOverflowHidden() const;
diff --git a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp index 68399b5e..ef59b8b 100644 --- a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp +++ b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
@@ -301,7 +301,7 @@ void MainThreadDebugger::consoleAPIMessage( int contextGroupId, - v8_inspector::V8ConsoleAPIType type, + v8::Isolate::MessageErrorLevel level, const v8_inspector::StringView& message, const v8_inspector::StringView& url, unsigned lineNumber, @@ -310,18 +310,24 @@ LocalFrame* frame = WeakIdentifierMap<LocalFrame>::lookup(contextGroupId); if (!frame) return; - if (type == v8_inspector::V8ConsoleAPIType::kClear && frame->host()) - frame->host()->consoleMessageStorage().clear(); // TODO(dgozman): we can save a copy of message and url here by making // FrameConsole work with StringView. std::unique_ptr<SourceLocation> location = SourceLocation::create(toCoreString(url), lineNumber, columnNumber, stackTrace ? stackTrace->clone() : nullptr, 0); frame->console().reportMessageToClient(ConsoleAPIMessageSource, - consoleAPITypeToMessageLevel(type), + v8MessageLevelToMessageLevel(level), toCoreString(message), location.get()); } +void MainThreadDebugger::consoleClear(int contextGroupId) { + LocalFrame* frame = WeakIdentifierMap<LocalFrame>::lookup(contextGroupId); + if (!frame) + return; + if (frame->host()) + frame->host()->consoleMessageStorage().clear(); +} + v8::MaybeLocal<v8::Value> MainThreadDebugger::memoryInfo( v8::Isolate* isolate, v8::Local<v8::Context> context) {
diff --git a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h index ad6ad9aa..5f99457 100644 --- a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h +++ b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h
@@ -102,12 +102,13 @@ bool canExecuteScripts(int contextGroupId) override; void runIfWaitingForDebugger(int contextGroupId) override; void consoleAPIMessage(int contextGroupId, - v8_inspector::V8ConsoleAPIType, + v8::Isolate::MessageErrorLevel, const v8_inspector::StringView& message, const v8_inspector::StringView& url, unsigned lineNumber, unsigned columnNumber, v8_inspector::V8StackTrace*) override; + void consoleClear(int contextGroupId) override; void installAdditionalCommandLineAPI(v8::Local<v8::Context>, v8::Local<v8::Object>) override; v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*,
diff --git a/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp index 6e4ac06..1b552c8 100644 --- a/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp +++ b/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp
@@ -45,21 +45,26 @@ } // static -MessageLevel ThreadDebugger::consoleAPITypeToMessageLevel( - v8_inspector::V8ConsoleAPIType type) { - switch (type) { - case v8_inspector::V8ConsoleAPIType::kDebug: - return VerboseMessageLevel; - case v8_inspector::V8ConsoleAPIType::kLog: - case v8_inspector::V8ConsoleAPIType::kInfo: - return InfoMessageLevel; - case v8_inspector::V8ConsoleAPIType::kWarning: - return WarningMessageLevel; - case v8_inspector::V8ConsoleAPIType::kError: - return ErrorMessageLevel; +MessageLevel ThreadDebugger::v8MessageLevelToMessageLevel( + v8::Isolate::MessageErrorLevel level) { + MessageLevel result = InfoMessageLevel; + switch (level) { + case v8::Isolate::kMessageDebug: + result = VerboseMessageLevel; + break; + case v8::Isolate::kMessageWarning: + result = WarningMessageLevel; + break; + case v8::Isolate::kMessageError: + result = ErrorMessageLevel; + break; + case v8::Isolate::kMessageLog: + case v8::Isolate::kMessageInfo: default: - return InfoMessageLevel; + result = InfoMessageLevel; + break; } + return result; } void ThreadDebugger::willExecuteScript(v8::Isolate* isolate, int scriptId) {
diff --git a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h index cc687d13..6d49f1f 100644 --- a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h +++ b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
@@ -68,8 +68,8 @@ v8::Local<v8::Array>, int index, v8::Local<v8::Value>); - static MessageLevel consoleAPITypeToMessageLevel( - v8_inspector::V8ConsoleAPIType); + static MessageLevel v8MessageLevelToMessageLevel( + v8::Isolate::MessageErrorLevel); v8::Isolate* m_isolate;
diff --git a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp index 12752767..55707d7 100644 --- a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp +++ b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp
@@ -194,7 +194,7 @@ void WorkerThreadDebugger::consoleAPIMessage( int contextGroupId, - v8_inspector::V8ConsoleAPIType type, + v8::Isolate::MessageErrorLevel level, const v8_inspector::StringView& message, const v8_inspector::StringView& url, unsigned lineNumber, @@ -202,17 +202,20 @@ v8_inspector::V8StackTrace* stackTrace) { DCHECK(m_workerThreads.contains(contextGroupId)); WorkerThread* workerThread = m_workerThreads.get(contextGroupId); - - if (type == v8_inspector::V8ConsoleAPIType::kClear) - workerThread->consoleMessageStorage()->clear(); std::unique_ptr<SourceLocation> location = SourceLocation::create(toCoreString(url), lineNumber, columnNumber, stackTrace ? stackTrace->clone() : nullptr, 0); workerThread->workerReportingProxy().reportConsoleMessage( - ConsoleAPIMessageSource, consoleAPITypeToMessageLevel(type), + ConsoleAPIMessageSource, v8MessageLevelToMessageLevel(level), toCoreString(message), location.get()); } +void WorkerThreadDebugger::consoleClear(int contextGroupId) { + DCHECK(m_workerThreads.contains(contextGroupId)); + WorkerThread* workerThread = m_workerThreads.get(contextGroupId); + workerThread->consoleMessageStorage()->clear(); +} + v8::MaybeLocal<v8::Value> WorkerThreadDebugger::memoryInfo( v8::Isolate*, v8::Local<v8::Context>) {
diff --git a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h index 1313603..f5e87a2 100644 --- a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h +++ b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h
@@ -77,12 +77,13 @@ v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*, v8::Local<v8::Context>) override; void consoleAPIMessage(int contextGroupId, - v8_inspector::V8ConsoleAPIType, + v8::Isolate::MessageErrorLevel, const v8_inspector::StringView& message, const v8_inspector::StringView& url, unsigned lineNumber, unsigned columnNumber, v8_inspector::V8StackTrace*) override; + void consoleClear(int contextGroupId) override; int m_pausedContextGroupId; WTF::HashMap<int, WorkerThread*> m_workerThreads;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp index c23b5d93..f945e82 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
@@ -145,7 +145,7 @@ result.append('\\'); result.append('x'); result.append('{'); - appendUnsignedAsHex(c, result); + HexNumber::appendUnsignedAsHex(c, result); result.append('}'); } }
diff --git a/third_party/WebKit/Source/core/streams/README.md b/third_party/WebKit/Source/core/streams/README.md index 9069fd3..44a89f51 100644 --- a/third_party/WebKit/Source/core/streams/README.md +++ b/third_party/WebKit/Source/core/streams/README.md
@@ -6,9 +6,11 @@ - ByteLengthQueuingStrategy.js - CountQueuingStrategy.js - ReadableStream.js +- ReadableStreamExperimentalPipeTo.js - ReadableStreamController.h - ReadableStreamOperations.{cpp,h} - UnderlyingSourceBase.{cpp,h,idl} +- WritableStream.js These files implement ReadableStream using [V8 extras][1]. All new code should use this implementation.
diff --git a/third_party/WebKit/Source/core/streams/ReadableStream.js b/third_party/WebKit/Source/core/streams/ReadableStream.js index b8d33caf..50b37750 100644 --- a/third_party/WebKit/Source/core/streams/ReadableStream.js +++ b/third_party/WebKit/Source/core/streams/ReadableStream.js
@@ -49,6 +49,7 @@ const defineProperty = global.Object.defineProperty; const hasOwnProperty = v8.uncurryThis(global.Object.hasOwnProperty); const callFunction = v8.uncurryThis(global.Function.prototype.call); + const applyFunction = v8.uncurryThis(global.Function.prototype.apply); const TypeError = global.TypeError; const RangeError = global.RangeError; @@ -93,6 +94,9 @@ const errTmplMustBeFunctionOrUndefined = name => `${name} must be a function or undefined`; + const errCannotPipeLockedStream = 'Cannot pipe a locked stream'; + const errCannotPipeToALockedStream = 'Cannot pipe to a locked stream'; + const errDestinationStreamClosed = 'Destination stream closed'; class ReadableStream { constructor() { @@ -181,6 +185,207 @@ } } + // TODO(ricea): Move this into the class definition once it ships. + function ReadableStream_prototype_pipeThrough({writable, readable}, options) { + this.pipeTo(writable, options); + return readable; + } + + // TODO(ricea): Move this into the class definition once it ships. + function ReadableStream_prototype_pipeTo( + dest, {preventClose, preventAbort, preventCancel} = {}) { + if (!IsReadableStream(this)) { + return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + } + + if (!binding.IsWritableStream(dest)) { + // TODO(ricea): Think about having a better error message. + return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + } + + preventClose = Boolean(preventClose); + preventAbort = Boolean(preventAbort); + preventCancel = Boolean(preventCancel); + + const readable = this; + if (IsReadableStreamLocked(readable)) { + return Promise_reject(new TypeError(errCannotPipeLockedStream)); + } + + if (binding.IsWritableStreamLocked(dest)) { + return Promise_reject(new TypeError(errCannotPipeToALockedStream)); + } + + const reader = AcquireReadableStreamDefaultReader(readable); + const writer = binding.AcquireWritableStreamDefaultWriter(dest); + let shuttingDown = false; + const promise = v8.createPromise(); + let reading = false; + + if (checkInitialState()) { + // Need to detect closing and error when we are not reading. + thenPromise(reader[_closedPromise], onReaderClosed, readableError); + // Need to detect error when we are not writing. + thenPromise( + binding.getWritableStreamDefaultWriterClosedPromise(writer), + undefined, writableError); + pump(); + } + + // Checks the state of the streams and executes the shutdown handlers if + // necessary. Returns true if piping can continue. + function checkInitialState() { + const state = ReadableStreamGetState(readable); + + // Both streams can be errored or closed. To perform the right action the + // order of the checks must match the standard. + if (state === STATE_ERRORED) { + readableError(readable[_storedError]); + return false; + } + + if (binding.isWritableStreamErrored(dest)) { + writableError(binding.getWritableStreamStoredError(dest)); + return false; + } + + if (state === STATE_CLOSED) { + readableClosed(); + return false; + } + + if (binding.isWritableStreamClosingOrClosed(dest)) { + writableStartedClosed(); + return false; + } + + return true; + } + + function pump() { + if (shuttingDown) { + return; + } + const desiredSize = + binding.WritableStreamDefaultWriterGetDesiredSize(writer); + if (desiredSize === null) { + writableError(binding.getWritableStreamStoredError(dest)); + } + if (desiredSize <= 0) { + thenPromise( + binding.getWritableStreamDefaultWriterReadyPromise(writer), pump, + writableError); + return; + } + reading = true; + // TODO(ricea): Delay reads heuristically when desiredSize is low. + thenPromise( + ReadableStreamDefaultReaderRead(reader), readFulfilled, readRejected); + } + + function readFulfilled({value, done}) { + reading = false; + if (shuttingDown) { + return; + } + if (done) { + readableClosed(); + return; + } + const write = binding.WritableStreamDefaultWriterWrite(writer, value); + thenPromise(write, undefined, writableError); + pump(); + } + + function readRejected() { + reading = false; + readableError(readable[_storedError]); + } + + // If read() is in progress, then wait for it to tell us that the stream is + // closed so that we write all the data before shutdown. + function onReaderClosed() { + if (!reading) { + readableClosed(); + } + } + + // These steps are from "Errors must be propagated forward" in the + // standard. + function readableError(error) { + if (!preventAbort) { + shutdownWithAction( + binding.WritableStreamAbort, [dest, error], error, true); + } else { + shutdown(error, true); + } + } + + // These steps are from "Errors must be propagated backward". + function writableError(error) { + if (!preventCancel) { + shutdownWithAction( + ReadableStreamCancel, [readable, error], error, true); + } else { + shutdown(error, true); + } + } + + // These steps are from "Closing must be propagated forward". + function readableClosed() { + if (!preventClose) { + shutdownWithAction( + binding.WritableStreamDefaultWriterCloseWithErrorPropagation, + [writer]); + } else { + shutdown(); + } + } + + // These steps are from "Closing must be propagated backward". + function writableStartedClosed() { + const destClosed = new TypeError(errDestinationStreamClosed); + if (!preventCancel) { + shutdownWithAction( + ReadableStreamCancel, [readable, destClosed], destClosed, true); + } else { + shutdown(destClosed, true); + } + } + + function shutdownWithAction( + action, args, originalError = undefined, errorGiven = false) { + if (shuttingDown) { + return; + } + shuttingDown = true; + const p = applyFunction(action, undefined, args); + thenPromise( + p, () => finalize(originalError, errorGiven), + newError => finalize(newError, true)); + } + + function shutdown(error = undefined, errorGiven = false) { + if (shuttingDown) { + return; + } + shuttingDown = true; + finalize(error, errorGiven); + } + + function finalize(error, errorGiven) { + binding.WritableStreamDefaultWriterRelease(writer); + ReadableStreamReaderGenericRelease(reader); + if (errorGiven) { + v8.rejectPromise(promise, error); + } else { + v8.resolvePromise(promise, undefined); + } + } + + return promise; + } + class ReadableStreamDefaultController { constructor(stream, underlyingSource, size, highWaterMark, isExternallyControlled) { if (IsReadableStream(stream) === false) { @@ -973,4 +1178,9 @@ return new ReadableStream( underlyingSource, strategy, createWithExternalControllerSentinel); }; + + // Temporary exports while pipeTo() and pipeThrough() are behind flags + binding.ReadableStream_prototype_pipeThrough = + ReadableStream_prototype_pipeThrough; + binding.ReadableStream_prototype_pipeTo = ReadableStream_prototype_pipeTo; });
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamExperimentalPipeTo.js b/third_party/WebKit/Source/core/streams/ReadableStreamExperimentalPipeTo.js new file mode 100644 index 0000000..870c18b7 --- /dev/null +++ b/third_party/WebKit/Source/core/streams/ReadableStreamExperimentalPipeTo.js
@@ -0,0 +1,25 @@ +// Copyright 2016 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 pipeTo() and pipeThrough() on the global ReadableStream object when +// the experimental flag is enabled. + +(function(global, binding, v8) { + 'use strict'; + + const defineProperty = global.Object.defineProperty; + defineProperty(global.ReadableStream.prototype, 'pipeThrough', { + value: binding.ReadableStream_prototype_pipeThrough, + enumerable: false, + configurable: true, + writable: true + }); + + defineProperty(global.ReadableStream.prototype, 'pipeTo', { + value: binding.ReadableStream_prototype_pipeTo, + enumerable: false, + configurable: true, + writable: true + }); +});
diff --git a/third_party/WebKit/Source/core/streams/WritableStream.js b/third_party/WebKit/Source/core/streams/WritableStream.js index e987cedd..38f7adc 100644 --- a/third_party/WebKit/Source/core/streams/WritableStream.js +++ b/third_party/WebKit/Source/core/streams/WritableStream.js
@@ -364,6 +364,26 @@ } } + // 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.'); + return stream[_state] === ERRORED; + } + + function isWritableStreamClosingOrClosed(stream) { + TEMP_ASSERT( + IsWritableStream(stream), '! IsWritableStream(stream) is true.'); + return stream[_state] === CLOSING || stream[_state] === CLOSED; + } + + function getWritableStreamStoredError(stream) { + TEMP_ASSERT( + IsWritableStream(stream), '! IsWritableStream(stream) is true.'); + return stream[_storedError]; + } + class WritableStreamDefaultWriter { constructor(stream) { if (!IsWritableStream(stream)) { @@ -504,6 +524,20 @@ return stream[_pendingCloseRequest]; } + function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { + const stream = writer[_ownerWritableStream]; + TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); + const state = stream[_state]; + if (state === CLOSING || state === CLOSED) { + return Promise_resolve(undefined); + } + if (state === ERRORED) { + return Promise_reject(stream[_storedError]); + } + TEMP_ASSERT(state === WRITABLE, 'state is "writable".'); + return WritableStreamDefaultWriterClose(writer); + } + function WritableStreamDefaultWriterGetDesiredSize(writer) { const stream = writer[_ownerWritableStream]; const state = stream[_state]; @@ -563,6 +597,22 @@ return promise; } + // 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.'); + return writer[_closedPromise]; + } + + function getWritableStreamDefaultWriterReadyPromise(writer) { + TEMP_ASSERT( + IsWritableStreamDefaultWriter(writer), + 'writer is a WritableStreamDefaultWriter.'); + return writer[_readyPromise]; + } + class WritableStreamDefaultController { constructor(stream, underlyingSink, size, highWaterMark) { if (!IsWritableStream(stream)) { @@ -934,4 +984,25 @@ }); // TODO(ricea): Exports to Blink + + // Exports for ReadableStream + binding.AcquireWritableStreamDefaultWriter = + AcquireWritableStreamDefaultWriter; + binding.IsWritableStream = IsWritableStream; + binding.isWritableStreamClosingOrClosed = isWritableStreamClosingOrClosed; + binding.isWritableStreamErrored = isWritableStreamErrored; + binding.IsWritableStreamLocked = IsWritableStreamLocked; + binding.WritableStreamAbort = WritableStreamAbort; + binding.WritableStreamDefaultWriterCloseWithErrorPropagation = + WritableStreamDefaultWriterCloseWithErrorPropagation; + binding.getWritableStreamDefaultWriterClosedPromise = + getWritableStreamDefaultWriterClosedPromise; + binding.WritableStreamDefaultWriterGetDesiredSize = + WritableStreamDefaultWriterGetDesiredSize; + binding.getWritableStreamDefaultWriterReadyPromise = + getWritableStreamDefaultWriterReadyPromise; + binding.WritableStreamDefaultWriterRelease = + WritableStreamDefaultWriterRelease; + binding.WritableStreamDefaultWriterWrite = WritableStreamDefaultWriterWrite; + binding.getWritableStreamStoredError = getWritableStreamStoredError; });
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp index 3e284b4..47c782e 100644 --- a/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp +++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp
@@ -366,8 +366,9 @@ String BluetoothUUID::canonicalUUID(unsigned alias) { StringBuilder builder; builder.reserveCapacity(36 /* 36 chars or 128 bits, length of a UUID */); - appendUnsignedAsHexFixedSize( - alias, builder, 8 /* 8 chars or 32 bits, prefix length */, Lowercase); + HexNumber::appendUnsignedAsHexFixedSize( + alias, builder, 8 /* 8 chars or 32 bits, prefix length */, + HexNumber::Lowercase); builder.append("-0000-1000-8000-00805f9b34fb"); return builder.toString();
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 6d9c382..6cc8afe 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1185,6 +1185,7 @@ "scheduler/base/intrusive_heap.h", "scheduler/base/lazy_now.cc", "scheduler/base/lazy_now.h", + "scheduler/base/moveable_auto_lock.h", "scheduler/base/pollable_thread_safe_flag.cc", "scheduler/base/pollable_thread_safe_flag.h", "scheduler/base/queueing_time_estimator.cc",
diff --git a/third_party/WebKit/Source/platform/graphics/Color.cpp b/third_party/WebKit/Source/platform/graphics/Color.cpp index 3b406bf..c82a1e0 100644 --- a/third_party/WebKit/Source/platform/graphics/Color.cpp +++ b/third_party/WebKit/Source/platform/graphics/Color.cpp
@@ -231,9 +231,9 @@ StringBuilder builder; builder.reserveCapacity(7); builder.append('#'); - appendByteAsHex(red(), builder, Lowercase); - appendByteAsHex(green(), builder, Lowercase); - appendByteAsHex(blue(), builder, Lowercase); + HexNumber::appendByteAsHex(red(), builder, HexNumber::Lowercase); + HexNumber::appendByteAsHex(green(), builder, HexNumber::Lowercase); + HexNumber::appendByteAsHex(blue(), builder, HexNumber::Lowercase); return builder.toString(); }
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp index 4937207..da8c238 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp +++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
@@ -550,13 +550,19 @@ sk_sp<SkImage> image = m_surface->newImageSnapshot(PreferNoAcceleration, SnapshotReasonPaint); + // image can be null if alloaction failed in which case we should just + // abort the surface switch to reatain the old surface which is still + // functional. + if (!image) + return; + if (surface->isRecording()) { // Using a GPU-backed image with RecordingImageBufferSurface // will fail at playback time. image = image->makeNonTextureImage(); } - surface->canvas()->drawImage(image.get(), 0, 0); + surface->setImageBuffer(this); if (m_client) m_client->restoreCanvasMatrixClipStack(surface->canvas());
diff --git a/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp b/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp index 8de896ce..137e1847 100644 --- a/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp +++ b/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp
@@ -326,7 +326,7 @@ // #AARRGGBB. Vector<LChar, 9> result; result.push_back('#'); - appendUnsignedAsHex(color, result); + HexNumber::appendUnsignedAsHex(color, result); return String(result.data(), result.size()); }
diff --git a/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp b/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp index d45201e..47cb531 100644 --- a/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp +++ b/third_party/WebKit/Source/platform/network/FormDataEncoder.cpp
@@ -48,7 +48,7 @@ static inline void appendPercentEncoded(Vector<char>& buffer, unsigned char c) { append(buffer, '%'); - appendByteAsHex(c, buffer); + HexNumber::appendByteAsHex(c, buffer); } static void appendQuotedString(Vector<char>& buffer, const CString& string) {
diff --git a/third_party/WebKit/Source/platform/scheduler/base/moveable_auto_lock.h b/third_party/WebKit/Source/platform/scheduler/base/moveable_auto_lock.h new file mode 100644 index 0000000..ac2b8a8 --- /dev/null +++ b/third_party/WebKit/Source/platform/scheduler/base/moveable_auto_lock.h
@@ -0,0 +1,41 @@ +// Copyright 2016 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 THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_MOVEABLE_AUTO_LOCK_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_MOVEABLE_AUTO_LOCK_H_ + +#include "base/synchronization/lock.h" + +namespace blink { +namespace scheduler { + +class MoveableAutoLock { + public: + explicit MoveableAutoLock(base::Lock& lock) : lock_(lock), moved_(false) { + lock_.Acquire(); + } + + explicit MoveableAutoLock(MoveableAutoLock&& other) + : lock_(other.lock_), moved_(other.moved_) { + lock_.AssertAcquired(); + other.moved_ = true; + } + + ~MoveableAutoLock() { + if (moved_) + return; + lock_.AssertAcquired(); + lock_.Release(); + } + + private: + base::Lock& lock_; + bool moved_; + DISALLOW_COPY_AND_ASSIGN(MoveableAutoLock); +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_MOVEABLE_AUTO_LOCK_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc index 94694b6..762f079 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
@@ -336,7 +336,7 @@ RunsTasksOnCurrentThread() && (!IsQueueEnabled() || main_thread_only().current_fence); any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork( - this, queue_is_blocked); + this, sequence_number, queue_is_blocked); any_thread().time_domain->OnQueueHasImmediateWork(this); } any_thread().immediate_incoming_queue.emplace_back( @@ -678,6 +678,16 @@ main_thread_only().current_fence; } +bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const { + if (!IsQueueEnabled()) + return false; + + if (!main_thread_only().current_fence) + return true; + + return enqueue_order < main_thread_only().current_fence; +} + EnqueueOrder TaskQueueImpl::GetFenceForTest() const { return main_thread_only().current_fence; }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h index 209a86b2..8381157 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
@@ -140,6 +140,11 @@ const char* GetName() const override; QueueType GetQueueType() const override; + // Returns true if a (potentially hypothetical) task with the specified + // |enqueue_order| could run on the queue. Must be called from the main + // thread. + bool CouldTaskRun(EnqueueOrder enqueue_order) const; + // Must only be called from the thread this task queue was created on. void ReloadImmediateWorkQueueIfEmpty();
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc index 16dc908..e42fee1 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
@@ -75,12 +75,10 @@ "TaskQueueManager", this); selector_.SetTaskQueueSelectorObserver(this); - from_main_thread_immediate_do_work_closure_ = - base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), - base::TimeTicks(), true); - from_other_thread_immediate_do_work_closure_ = - base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), - base::TimeTicks(), false); + delayed_do_work_closure_ = + base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true); + immediate_do_work_closure_ = + base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false); // TODO(alexclarke): Change this to be a parameter that's passed in. RegisterTimeDomain(real_time_domain_.get()); @@ -100,7 +98,10 @@ delegate_->RemoveNestingObserver(this); } -TaskQueueManager::AnyThread::AnyThread() : other_thread_pending_wakeup(false) {} +TaskQueueManager::AnyThread::AnyThread() + : do_work_running_count(0), + immediate_do_work_posted_count(0), + is_nested(false) {} void TaskQueueManager::RegisterTimeDomain(TimeDomain* time_domain) { time_domains_.insert(time_domain); @@ -155,14 +156,13 @@ } void TaskQueueManager::ReloadEmptyWorkQueues( - const std::unordered_set<internal::TaskQueueImpl*>& queues_to_reload) - const { + const IncomingImmediateWorkMap& queues_to_reload) const { // There are two cases where a queue needs reloading. First, it might be // completely empty and we've just posted a task (this method handles that // case). Secondly if the work queue becomes empty in when calling // WorkQueue::TakeTaskFromWorkQueue (handled there). - for (internal::TaskQueueImpl* queue : queues_to_reload) { - queue->ReloadImmediateWorkQueueIfEmpty(); + for (const auto& pair : queues_to_reload) { + pair.first->ReloadImmediateWorkQueueIfEmpty(); } } @@ -183,59 +183,49 @@ void TaskQueueManager::OnBeginNestedMessageLoop() { // We just entered a nested message loop, make sure there's a DoWork posted or // the system will grind to a halt. - delegate_->PostTask(FROM_HERE, from_main_thread_immediate_do_work_closure_); + { + base::AutoLock lock(any_thread_lock_); + any_thread().immediate_do_work_posted_count++; + any_thread().is_nested = true; + } + delegate_->PostTask(FROM_HERE, immediate_do_work_closure_); } void TaskQueueManager::OnQueueHasIncomingImmediateWork( internal::TaskQueueImpl* queue, + internal::EnqueueOrder enqueue_order, bool queue_is_blocked) { - bool on_main_thread = delegate_->BelongsToCurrentThread(); - - { - base::AutoLock lock(any_thread_lock_); - any_thread().has_incoming_immediate_work.insert(queue); - - if (queue_is_blocked) - return; - - // De-duplicate DoWork posts. - if (on_main_thread) { - if (!main_thread_pending_wakeups_.insert(base::TimeTicks()).second) - return; - } else { - if (any_thread().other_thread_pending_wakeup) - return; - any_thread().other_thread_pending_wakeup = true; - } - } - - if (on_main_thread) { - delegate_->PostTask(FROM_HERE, from_main_thread_immediate_do_work_closure_); - } else { - delegate_->PostTask(FROM_HERE, - from_other_thread_immediate_do_work_closure_); - } + MoveableAutoLock lock(any_thread_lock_); + any_thread().has_incoming_immediate_work.insert( + std::make_pair(queue, enqueue_order)); + if (!queue_is_blocked) + MaybeScheduleImmediateWorkLocked(FROM_HERE, std::move(lock)); } void TaskQueueManager::MaybeScheduleImmediateWork( const tracked_objects::Location& from_here) { - bool on_main_thread = delegate_->BelongsToCurrentThread(); - // De-duplicate DoWork posts. - if (on_main_thread) { - if (!main_thread_pending_wakeups_.insert(base::TimeTicks()).second) { + MoveableAutoLock lock(any_thread_lock_); + MaybeScheduleImmediateWorkLocked(from_here, std::move(lock)); +} + +void TaskQueueManager::MaybeScheduleImmediateWorkLocked( + const tracked_objects::Location& from_here, + MoveableAutoLock&& lock) { + { + MoveableAutoLock auto_lock(std::move(lock)); + // Unless we're nested, try to avoid posting redundant DoWorks. + if (!any_thread().is_nested && + (any_thread().do_work_running_count == 1 || + any_thread().immediate_do_work_posted_count > 0)) { return; } - delegate_->PostTask(from_here, from_main_thread_immediate_do_work_closure_); - } else { - { - base::AutoLock lock(any_thread_lock_); - if (any_thread().other_thread_pending_wakeup) - return; - any_thread().other_thread_pending_wakeup = true; - } - delegate_->PostTask(from_here, - from_other_thread_immediate_do_work_closure_); + + any_thread().immediate_do_work_posted_count++; } + + TRACE_EVENT0(disabled_by_default_tracing_category_, + "TaskQueueManager::MaybeScheduleImmediateWorkLocked::PostTask"); + delegate_->PostTask(from_here, immediate_do_work_closure_); } void TaskQueueManager::MaybeScheduleDelayedWork( @@ -244,54 +234,70 @@ base::TimeDelta delay) { DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK_GE(delay, base::TimeDelta()); + { + base::AutoLock lock(any_thread_lock_); - // If there's a pending immediate DoWork then we rely on - // TryAdvanceTimeDomains getting the TimeDomain to call - // MaybeScheduleDelayedWork again when the immediate DoWork is complete. - if (main_thread_pending_wakeups_.find(base::TimeTicks()) != - main_thread_pending_wakeups_.end()) { - return; + // Unless we're nested, don't post a delayed DoWork if there's an immediate + // DoWork in flight or we're inside a DoWork. We can rely on DoWork posting + // a delayed continuation as needed. + if (!any_thread().is_nested && + (any_thread().immediate_do_work_posted_count > 0 || + any_thread().do_work_running_count == 1)) { + return; + } } + // De-duplicate DoWork posts. base::TimeTicks run_time = now + delay; - if (!main_thread_pending_wakeups_.empty() && - *main_thread_pending_wakeups_.begin() <= run_time) { + if (next_scheduled_delayed_do_work_time_ <= run_time && + !next_scheduled_delayed_do_work_time_.is_null()) return; - } - main_thread_pending_wakeups_.insert(run_time); + + TRACE_EVENT1(disabled_by_default_tracing_category_, + "TaskQueueManager::MaybeScheduleDelayedWork::PostDelayedTask", + "delay_ms", delay.InMillisecondsF()); + + cancelable_delayed_do_work_closure_.Reset(delayed_do_work_closure_); + next_scheduled_delayed_do_work_time_ = run_time; delegate_->PostDelayedTask( - from_here, base::Bind(&TaskQueueManager::DoWork, - weak_factory_.GetWeakPtr(), run_time, true), - delay); + from_here, cancelable_delayed_do_work_closure_.callback(), delay); } -void TaskQueueManager::DoWork(base::TimeTicks run_time, bool from_main_thread) { +void TaskQueueManager::DoWork(bool delayed) { DCHECK(main_thread_checker_.CalledOnValidThread()); - TRACE_EVENT1(tracing_category_, "TaskQueueManager::DoWork", - "from_main_thread", from_main_thread); + TRACE_EVENT1(tracing_category_, "TaskQueueManager::DoWork", "delayed", + delayed); - if (from_main_thread) { - main_thread_pending_wakeups_.erase(run_time); - } else { - base::AutoLock lock(any_thread_lock_); - any_thread().other_thread_pending_wakeup = false; - } - - // Posting a DoWork while a DoWork is running leads to spurious DoWorks. - main_thread_pending_wakeups_.insert(base::TimeTicks()); - + LazyNow lazy_now(real_time_domain()->CreateLazyNow()); bool is_nested = delegate_->IsNested(); if (!is_nested) queues_to_delete_.clear(); - LazyNow lazy_now(real_time_domain()->CreateLazyNow()); - WakeupReadyDelayedQueues(&lazy_now); + // This must be done before running any tasks because they could invoke a + // nested message loop and we risk having a stale + // |next_scheduled_delayed_do_work_time_|. + if (delayed) + next_scheduled_delayed_do_work_time_ = base::TimeTicks(); for (int i = 0; i < work_batch_size_; i++) { - std::unordered_set<internal::TaskQueueImpl*> queues_to_reload; + IncomingImmediateWorkMap queues_to_reload; { base::AutoLock lock(any_thread_lock_); + if (i == 0) { + any_thread().do_work_running_count++; + + if (!delayed) { + any_thread().immediate_do_work_posted_count--; + DCHECK_GE(any_thread().immediate_do_work_posted_count, 0); + } + } else { + // Ideally we'd have an OnNestedMessageloopExit observer, but in it's + // absence we may need to clear this flag after running a task (which + // ran a nested messageloop). + any_thread().is_nested = is_nested; + } + DCHECK_EQ(any_thread().is_nested, delegate_->IsNested()); std::swap(queues_to_reload, any_thread().has_incoming_immediate_work); } @@ -299,10 +305,13 @@ // avoid a lock order inversion. ReloadEmptyWorkQueues(queues_to_reload); - internal::WorkQueue* work_queue; + WakeupReadyDelayedQueues(&lazy_now); + + internal::WorkQueue* work_queue = nullptr; if (!SelectWorkQueueToService(&work_queue)) break; + // NB this may unregister |work_queue|. base::TimeTicks time_after_task; switch (ProcessTaskFromWorkQueue(work_queue, is_nested, lazy_now, &time_after_task)) { @@ -315,11 +324,8 @@ return; // The TaskQueueManager got deleted, we must bail out. } - work_queue = nullptr; // The queue may have been unregistered. - lazy_now = time_after_task.is_null() ? real_time_domain()->CreateLazyNow() : LazyNow(time_after_task); - WakeupReadyDelayedQueues(&lazy_now); // Only run a single task per batch in nested run loops so that we can // properly exit the nested loop when someone calls RunLoop::Quit(). @@ -327,45 +333,104 @@ break; } - main_thread_pending_wakeups_.erase(base::TimeTicks()); - // TODO(alexclarke): Consider refactoring the above loop to terminate only // when there's no more work left to be done, rather than posting a // continuation task. - base::Optional<base::TimeDelta> next_delay = - ComputeDelayTillNextTask(&lazy_now); - if (!next_delay) - return; + { + MoveableAutoLock lock(any_thread_lock_); + base::Optional<base::TimeDelta> next_delay = + ComputeDelayTillNextTaskLocked(&lazy_now); - base::TimeDelta delay = next_delay.value(); - if (delay.is_zero()) { - MaybeScheduleImmediateWork(FROM_HERE); - } else { - MaybeScheduleDelayedWork(FROM_HERE, lazy_now.Now(), delay); + any_thread().do_work_running_count--; + DCHECK_GE(any_thread().do_work_running_count, 0); + + any_thread().is_nested = is_nested; + DCHECK_EQ(any_thread().is_nested, delegate_->IsNested()); + + PostDoWorkContinuationLocked(next_delay, &lazy_now, std::move(lock)); } } -base::Optional<base::TimeDelta> TaskQueueManager::ComputeDelayTillNextTask( - LazyNow* lazy_now) { +void TaskQueueManager::PostDoWorkContinuationLocked( + base::Optional<base::TimeDelta> next_delay, + LazyNow* lazy_now, + MoveableAutoLock&& lock) { DCHECK(main_thread_checker_.CalledOnValidThread()); + base::TimeDelta delay; - std::unordered_set<internal::TaskQueueImpl*> queues_to_reload; { - base::AutoLock lock(any_thread_lock_); - std::swap(queues_to_reload, any_thread().has_incoming_immediate_work); + MoveableAutoLock auto_lock(std::move(lock)); + + // If there are no tasks left then we don't need to post a continuation. + if (!next_delay) { + // If there's a pending delayed DoWork, cancel it because it's not needed. + if (!next_scheduled_delayed_do_work_time_.is_null()) { + next_scheduled_delayed_do_work_time_ = base::TimeTicks(); + cancelable_delayed_do_work_closure_.Cancel(); + } + return; + } + + // If an immediate DoWork is posted, we don't need to post a continuation. + if (any_thread().immediate_do_work_posted_count > 0) + return; + + delay = next_delay.value(); + + // This isn't supposed to happen, but in case it does convert to + // non-delayed. + if (delay < base::TimeDelta()) + delay = base::TimeDelta(); + + if (delay.is_zero()) { + // If a delayed DoWork is pending then we don't need to post a + // continuation because it should run immediately. + if (!next_scheduled_delayed_do_work_time_.is_null() && + next_scheduled_delayed_do_work_time_ <= lazy_now->Now()) { + return; + } + + any_thread().immediate_do_work_posted_count++; + } else { + base::TimeTicks run_time = lazy_now->Now() + delay; + if (next_scheduled_delayed_do_work_time_ == run_time) + return; + + next_scheduled_delayed_do_work_time_ = run_time; + } } - // It's important we call ReloadEmptyWorkQueues out side of the lock to - // avoid a lock order inversion. - ReloadEmptyWorkQueues(queues_to_reload); + // We avoid holding |any_thread_lock_| while posting the task. + if (delay.is_zero()) { + delegate_->PostTask(FROM_HERE, immediate_do_work_closure_); + } else { + cancelable_delayed_do_work_closure_.Reset(delayed_do_work_closure_); + delegate_->PostDelayedTask( + FROM_HERE, cancelable_delayed_do_work_closure_.callback(), delay); + } +} + +base::Optional<base::TimeDelta> +TaskQueueManager::ComputeDelayTillNextTaskLocked(LazyNow* lazy_now) { + DCHECK(main_thread_checker_.CalledOnValidThread()); + + // Unfortunately because |any_thread_lock_| is held it's not safe to call + // ReloadEmptyWorkQueues here (possible lock order inversion), however this + // check is equavalent to calling ReloadEmptyWorkQueues first. + for (const auto& pair : any_thread().has_incoming_immediate_work) { + if (pair.first->CouldTaskRun(pair.second)) + return base::TimeDelta(); + } // If the selector has non-empty queues we trivially know there is immediate // work to be done. if (!selector_.EnabledWorkQueuesEmpty()) return base::TimeDelta(); - // Otherwise we need to find the shortest delay, if any. + // Otherwise we need to find the shortest delay, if any. NB we don't need to + // call WakeupReadyDelayedQueues because it's assumed DelayTillNextTask will + // return base::TimeDelta>() if the delayed task is due to run now. base::Optional<base::TimeDelta> next_continuation; for (TimeDomain* time_domain : time_domains_) { base::Optional<base::TimeDelta> continuation = @@ -578,10 +643,15 @@ state->EndArray(); { base::AutoLock lock(any_thread_lock_); + state->SetBoolean("is_nested", any_thread().is_nested); + state->SetInteger("do_work_running_count", + any_thread().do_work_running_count); + state->SetInteger("immediate_do_work_posted_count", + any_thread().immediate_do_work_posted_count); + state->BeginArray("has_incoming_immediate_work"); - for (internal::TaskQueueImpl* task_queue : - any_thread().has_incoming_immediate_work) { - state->AppendString(task_queue->GetName()); + for (const auto& pair : any_thread().has_incoming_immediate_work) { + state->AppendString(pair.first->GetName()); } state->EndArray(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h index 8016827..21c4aedc 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h
@@ -8,6 +8,7 @@ #include <map> #include "base/atomic_sequence_num.h" +#include "base/cancelable_callback.h" #include "base/debug/task_annotator.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -16,6 +17,7 @@ #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" #include "platform/scheduler/base/enqueue_order.h" +#include "platform/scheduler/base/moveable_auto_lock.h" #include "platform/scheduler/base/task_queue_impl.h" #include "platform/scheduler/base/task_queue_selector.h" @@ -159,9 +161,6 @@ }; // Unregisters a TaskQueue previously created by |NewTaskQueue()|. - // NOTE we have to flush the queue from |newly_updatable_| which means as a - // side effect MoveNewlyUpdatableQueuesIntoUpdatableQueueSet is called by this - // function. void UnregisterTaskQueue(scoped_refptr<internal::TaskQueueImpl> task_queue); // TaskQueueSelector::Observer implementation: @@ -176,7 +175,12 @@ void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task); // Use the selector to choose a pending task and run it. - void DoWork(base::TimeTicks run_time, bool from_main_thread); + void DoWork(bool delayed); + + // Post a DoWork continuation if |next_delay| is not empty. + void PostDoWorkContinuationLocked(base::Optional<base::TimeDelta> next_delay, + LazyNow* lazy_now, + MoveableAutoLock&& lock); // Delayed Tasks with run_times <= Now() are enqueued onto the work queue and // reloads any empty work queues. @@ -212,7 +216,8 @@ // Calls DelayTillNextTask on all time domains and returns the smallest delay // requested if any. - base::Optional<base::TimeDelta> ComputeDelayTillNextTask(LazyNow* lazy_now); + base::Optional<base::TimeDelta> ComputeDelayTillNextTaskLocked( + LazyNow* lazy_now); void MaybeRecordTaskDelayHistograms( const internal::TaskQueueImpl::Task& pending_task, @@ -222,16 +227,24 @@ AsValueWithSelectorResult(bool should_run, internal::WorkQueue* selected_work_queue) const; + void MaybeScheduleImmediateWorkLocked( + const tracked_objects::Location& from_here, + MoveableAutoLock&& lock); + // Adds |queue| to |any_thread().has_incoming_immediate_work_| and if // |queue_is_blocked| is false it makes sure a DoWork is posted. // Can be called from any thread. void OnQueueHasIncomingImmediateWork(internal::TaskQueueImpl* queue, + internal::EnqueueOrder enqueue_order, bool queue_is_blocked); + using IncomingImmediateWorkMap = + std::unordered_map<internal::TaskQueueImpl*, internal::EnqueueOrder>; + // Calls |ReloadImmediateWorkQueueIfEmpty| on all queues in // |queues_to_reload|. - void ReloadEmptyWorkQueues(const std::unordered_set<internal::TaskQueueImpl*>& - queues_to_reload) const; + void ReloadEmptyWorkQueues( + const IncomingImmediateWorkMap& queues_to_reload) const; std::set<TimeDomain*> time_domains_; std::unique_ptr<RealTimeDomain> real_time_domain_; @@ -249,22 +262,21 @@ scoped_refptr<TaskQueueManagerDelegate> delegate_; internal::TaskQueueSelector selector_; - base::Closure from_main_thread_immediate_do_work_closure_; - base::Closure from_other_thread_immediate_do_work_closure_; + base::Closure immediate_do_work_closure_; + base::Closure delayed_do_work_closure_; + base::CancelableClosure cancelable_delayed_do_work_closure_; bool task_was_run_on_quiescence_monitored_queue_; - // To reduce locking overhead we track pending calls to DoWork separately for - // the main thread and other threads. - std::set<base::TimeTicks> main_thread_pending_wakeups_; - struct AnyThread { AnyThread(); - // Set of task queues with newly available work on the incoming queue. - std::unordered_set<internal::TaskQueueImpl*> has_incoming_immediate_work; + // Task queues with newly available work on the incoming queue. + IncomingImmediateWorkMap has_incoming_immediate_work; - bool other_thread_pending_wakeup; + int do_work_running_count; + int immediate_do_work_posted_count; + bool is_nested; // Whether or not the message loop is currently nested. }; // TODO(alexclarke): Add a MainThreadOnly struct too. @@ -281,6 +293,8 @@ return any_thread_; } + base::TimeTicks next_scheduled_delayed_do_work_time_; + bool record_task_delay_histograms_; int work_batch_size_;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc index d36cacb..fc290a3 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
@@ -121,9 +121,34 @@ } base::Optional<base::TimeDelta> ComputeDelayTillNextTask(LazyNow* lazy_now) { - // TODO(alexclarke): Remove this once the DoWork refactor lands. - manager_->WakeupReadyDelayedQueues(lazy_now); - return manager_->ComputeDelayTillNextTask(lazy_now); + base::AutoLock lock(manager_->any_thread_lock_); + return manager_->ComputeDelayTillNextTaskLocked(lazy_now); + } + + void PostDoWorkContinuation(base::Optional<base::TimeDelta> next_delay, + LazyNow* lazy_now) { + MoveableAutoLock lock(manager_->any_thread_lock_); + return manager_->PostDoWorkContinuationLocked(next_delay, lazy_now, + std::move(lock)); + } + + int immediate_do_work_posted_count() const { + base::AutoLock lock(manager_->any_thread_lock_); + return manager_->any_thread().immediate_do_work_posted_count; + } + + base::TimeTicks next_scheduled_delayed_do_work_time() const { + return manager_->next_scheduled_delayed_do_work_time_; + } + + EnqueueOrder GetNextSequenceNumber() const { + return manager_->GetNextSequenceNumber(); + } + + void MaybeScheduleImmediateWorkLocked( + const tracked_objects::Location& from_here) { + MoveableAutoLock lock(manager_->any_thread_lock_); + manager_->MaybeScheduleImmediateWorkLocked(from_here, std::move(lock)); } // Runs all immediate tasks until there is no more work to do and advances @@ -2330,7 +2355,19 @@ manager_->UnregisterTimeDomain(domain2.get()); } -TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_TaskBlocked) { +TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_Disabled) { + Initialize(1u); + + std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = + runners_[0]->CreateQueueEnabledVoter(); + voter->SetQueueEnabled(false); + runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); + + LazyNow lazy_now(now_src_.get()); + EXPECT_FALSE(ComputeDelayTillNextTask(&lazy_now)); +} + +TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_Fence) { Initialize(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW); @@ -2340,6 +2377,131 @@ EXPECT_FALSE(ComputeDelayTillNextTask(&lazy_now)); } +TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_FenceUnblocking) { + Initialize(1u); + + runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW); + runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); + runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW); + + LazyNow lazy_now(now_src_.get()); + EXPECT_EQ(base::TimeDelta(), ComputeDelayTillNextTask(&lazy_now).value()); +} + +TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask_DelayedTaskReady) { + Initialize(1u); + + runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), + base::TimeDelta::FromSeconds(1)); + + now_src_->Advance(base::TimeDelta::FromSeconds(10)); + + LazyNow lazy_now(now_src_.get()); + EXPECT_EQ(base::TimeDelta(), ComputeDelayTillNextTask(&lazy_now).value()); +} + +TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_NoMoreWork) { + Initialize(1u); + + LazyNow lazy_now(now_src_.get()); + PostDoWorkContinuation(base::Optional<base::TimeDelta>(), &lazy_now); + + EXPECT_EQ(0u, test_task_runner_->NumPendingTasks()); + EXPECT_EQ(0, immediate_do_work_posted_count()); + EXPECT_TRUE(next_scheduled_delayed_do_work_time().is_null()); +} + +TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_ImmediateWork) { + Initialize(1u); + + LazyNow lazy_now(now_src_.get()); + PostDoWorkContinuation(base::TimeDelta(), &lazy_now); + + EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); + EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(1, immediate_do_work_posted_count()); + EXPECT_TRUE(next_scheduled_delayed_do_work_time().is_null()); +} + +TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_DelayedWork) { + Initialize(1u); + + LazyNow lazy_now(now_src_.get()); + PostDoWorkContinuation(base::TimeDelta::FromSeconds(1), &lazy_now); + + EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), + test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(0, immediate_do_work_posted_count()); + EXPECT_EQ(lazy_now.Now() + base::TimeDelta::FromSeconds(1), + next_scheduled_delayed_do_work_time()); +} + +TEST_F(TaskQueueManagerTest, + PostDoWorkContinuation_DelayedWorkButImmediateDoWorkAlreadyPosted) { + Initialize(1u); + + MaybeScheduleImmediateWorkLocked(FROM_HERE); + EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); + EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(1, immediate_do_work_posted_count()); + + LazyNow lazy_now(now_src_.get()); + PostDoWorkContinuation(base::TimeDelta::FromSeconds(1), &lazy_now); + + // Test that a delayed task didn't get posted. + EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); + EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(1, immediate_do_work_posted_count()); + EXPECT_TRUE(next_scheduled_delayed_do_work_time().is_null()); +} + +TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_DelayedWorkTimeChanges) { + Initialize(1u); + + LazyNow lazy_now(now_src_.get()); + PostDoWorkContinuation(base::TimeDelta::FromSeconds(1), &lazy_now); + + EXPECT_TRUE(test_task_runner_->HasPendingTasks()); + EXPECT_EQ(0, immediate_do_work_posted_count()); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), + test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(lazy_now.Now() + base::TimeDelta::FromSeconds(1), + next_scheduled_delayed_do_work_time()); + + PostDoWorkContinuation(base::TimeDelta::FromSeconds(10), &lazy_now); + + // This should have resulted in the previous task getting canceled and a new + // one getting posted. + EXPECT_EQ(2u, test_task_runner_->NumPendingTasks()); + test_task_runner_->RemoveCancelledTasks(); + EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), + test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(0, immediate_do_work_posted_count()); + EXPECT_EQ(lazy_now.Now() + base::TimeDelta::FromSeconds(10), + next_scheduled_delayed_do_work_time()); +} + +TEST_F(TaskQueueManagerTest, + PostDoWorkContinuation_ImmediateWorkButDelayedDoWorkPending) { + Initialize(1u); + + LazyNow lazy_now(now_src_.get()); + PostDoWorkContinuation(base::TimeDelta::FromSeconds(1), &lazy_now); + + now_src_->Advance(base::TimeDelta::FromSeconds(1)); + lazy_now = LazyNow(now_src_.get()); + PostDoWorkContinuation(base::TimeDelta(), &lazy_now); + + // Because the delayed DoWork was pending we don't expect an immediate DoWork + // to get posted. + EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); + EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(0, immediate_do_work_posted_count()); + EXPECT_EQ(lazy_now.Now(), next_scheduled_delayed_do_work_time()); +} + namespace { void MessageLoopTaskWithDelayedQuit( base::MessageLoop* message_loop, @@ -2395,5 +2557,48 @@ run_loop.Run(); } +TEST_F(TaskQueueManagerTest, CouldTaskRun_DisableAndReenable) { + Initialize(1u); + + EnqueueOrder enqueue_order = GetNextSequenceNumber(); + EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order)); + + std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = + runners_[0]->CreateQueueEnabledVoter(); + voter->SetQueueEnabled(false); + EXPECT_FALSE(runners_[0]->CouldTaskRun(enqueue_order)); + + voter->SetQueueEnabled(true); + EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order)); +} + +TEST_F(TaskQueueManagerTest, CouldTaskRun_Fence) { + Initialize(1u); + + EnqueueOrder enqueue_order = GetNextSequenceNumber(); + EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order)); + + runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW); + EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order)); + + runners_[0]->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); + EXPECT_FALSE(runners_[0]->CouldTaskRun(enqueue_order)); + + runners_[0]->RemoveFence(); + EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order)); +} + +TEST_F(TaskQueueManagerTest, CouldTaskRun_FenceBeforeThenAfter) { + Initialize(1u); + + runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW); + + EnqueueOrder enqueue_order = GetNextSequenceNumber(); + EXPECT_FALSE(runners_[0]->CouldTaskRun(enqueue_order)); + + runners_[0]->InsertFence(TaskQueue::InsertFencePosition::NOW); + EXPECT_TRUE(runners_[0]->CouldTaskRun(enqueue_order)); +} + } // namespace scheduler } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index 0a5b5e9..0e621fd 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -1798,14 +1798,12 @@ browserControls().updateConstraintsAndState(constraint, current, animate); - // If the controls are going from a locked hidden to unlocked state, or vice - // versa, the ICB size needs to change but we can't rely on getting a - // WebViewImpl::resize since the top controls shown state may not have - // changed. - if ((oldPermittedState == WebBrowserControlsHidden && - constraint == WebBrowserControlsBoth) || - (oldPermittedState == WebBrowserControlsBoth && - constraint == WebBrowserControlsHidden)) { + // If the controls are going from a locked to an unlocked state, or + // vice-versa, then we need to force a recompute of the ICB size since that + // depends on the permitted browser controls state. + if (oldPermittedState != constraint && + (oldPermittedState == WebBrowserControlsBoth || + constraint == WebBrowserControlsBoth)) { performResize(); }
diff --git a/third_party/WebKit/Source/wtf/HexNumber.h b/third_party/WebKit/Source/wtf/HexNumber.h index 6956430..a0ea7b5c 100644 --- a/third_party/WebKit/Source/wtf/HexNumber.h +++ b/third_party/WebKit/Source/wtf/HexNumber.h
@@ -24,66 +24,80 @@ namespace WTF { -enum HexConversionMode { Lowercase, Uppercase }; - namespace Internal { const LChar lowerHexDigits[17] = "0123456789abcdef"; const LChar upperHexDigits[17] = "0123456789ABCDEF"; -inline const LChar* hexDigitsForMode(HexConversionMode mode) { - return mode == Lowercase ? lowerHexDigits : upperHexDigits; -} } // namespace Internal -template <typename T> -inline void appendByteAsHex(unsigned char byte, - T& destination, - HexConversionMode mode = Uppercase) { - const LChar* hexDigits = Internal::hexDigitsForMode(mode); - destination.append(hexDigits[byte >> 4]); - destination.append(hexDigits[byte & 0xF]); -} +class HexNumber final { + STATIC_ONLY(HexNumber); -template <typename T> -inline void appendUnsignedAsHex(unsigned number, - T& destination, - HexConversionMode mode = Uppercase) { - const LChar* hexDigits = Internal::hexDigitsForMode(mode); - Vector<LChar, 8> result; - do { - result.prepend(hexDigits[number % 16]); - number >>= 4; - } while (number > 0); + public: + enum HexConversionMode { Lowercase, Uppercase }; - destination.append(result.data(), result.size()); -} + template <typename T> + static inline void appendByteAsHex(unsigned char byte, + T& destination, + HexConversionMode mode = Uppercase) { + const LChar* hexDigits = hexDigitsForMode(mode); + destination.append(hexDigits[byte >> 4]); + destination.append(hexDigits[byte & 0xF]); + } -// Same as appendUnsignedAsHex, but using exactly 'desiredDigits' for the -// conversion. -template <typename T> -inline void appendUnsignedAsHexFixedSize(unsigned number, + static inline void appendByteAsHex(unsigned char byte, + Vector<LChar>& destination, + HexConversionMode mode = Uppercase) { + const LChar* hexDigits = hexDigitsForMode(mode); + destination.push_back(hexDigits[byte >> 4]); + destination.push_back(hexDigits[byte & 0xF]); + } + + template <typename T> + static inline void appendUnsignedAsHex(unsigned number, T& destination, - unsigned desiredDigits, HexConversionMode mode = Uppercase) { - DCHECK(desiredDigits); + const LChar* hexDigits = hexDigitsForMode(mode); + Vector<LChar, 8> result; + do { + result.prepend(hexDigits[number % 16]); + number >>= 4; + } while (number > 0); - const LChar* hexDigits = Internal::hexDigitsForMode(mode); - Vector<LChar, 8> result; - do { - result.prepend(hexDigits[number % 16]); - number >>= 4; - } while (result.size() < desiredDigits); + destination.append(result.data(), result.size()); + } - DCHECK_EQ(result.size(), desiredDigits); - destination.append(result.data(), result.size()); -} + // Same as appendUnsignedAsHex, but using exactly 'desiredDigits' for the + // conversion. + template <typename T> + static inline void appendUnsignedAsHexFixedSize( + unsigned number, + T& destination, + unsigned desiredDigits, + HexConversionMode mode = Uppercase) { + DCHECK(desiredDigits); + + const LChar* hexDigits = hexDigitsForMode(mode); + Vector<LChar, 8> result; + do { + result.prepend(hexDigits[number % 16]); + number >>= 4; + } while (result.size() < desiredDigits); + + DCHECK_EQ(result.size(), desiredDigits); + destination.append(result.data(), result.size()); + } + + private: + static inline const LChar* hexDigitsForMode(HexConversionMode mode) { + return mode == Lowercase ? Internal::lowerHexDigits + : Internal::upperHexDigits; + } +}; } // namespace WTF -using WTF::appendByteAsHex; -using WTF::appendUnsignedAsHex; -using WTF::appendUnsignedAsHexFixedSize; -using WTF::Lowercase; +using WTF::HexNumber; #endif // HexNumber_h
diff --git a/third_party/WebKit/Source/wtf/text/WTFString.cpp b/third_party/WebKit/Source/wtf/text/WTFString.cpp index 0cfe473..bc751f5a 100644 --- a/third_party/WebKit/Source/wtf/text/WTFString.cpp +++ b/third_party/WebKit/Source/wtf/text/WTFString.cpp
@@ -58,7 +58,7 @@ } else { buffer.push_back('\\'); buffer.push_back('u'); - appendUnsignedAsHexFixedSize(ch, buffer, 4); + HexNumber::appendUnsignedAsHexFixedSize(ch, buffer, 4); } } buffer.push_back('\0');
diff --git a/third_party/libjingle_xmpp/BUILD.gn b/third_party/libjingle_xmpp/BUILD.gn index f359263a..c44fbab 100644 --- a/third_party/libjingle_xmpp/BUILD.gn +++ b/third_party/libjingle_xmpp/BUILD.gn
@@ -3,7 +3,7 @@ # found in the LICENSE file. # TODO(kjellander): Remove remaining dependencies on the WebRTC codebase. -import("../webrtc/build/webrtc.gni") +import("../webrtc/webrtc.gni") group("libjingle_xmpp") { public_deps = [
diff --git a/tools/chrome_proxy/webdriver/html5.py b/tools/chrome_proxy/webdriver/html5.py new file mode 100644 index 0000000..036b019e --- /dev/null +++ b/tools/chrome_proxy/webdriver/html5.py
@@ -0,0 +1,30 @@ +# 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. + +import common +from common import TestDriver +from common import IntegrationTest + + +class HTML5(IntegrationTest): + + # This test site has a div with id="pointsPanel" that is rendered if the + # browser is capable of using HTML5. + def testHTML5(self): + with TestDriver() as t: + t.AddChromeArg('--enable-spdy-proxy-auth') + t.LoadURL('http://html5test.com/') + t.WaitForJavascriptExpression( + 'document.getElementsByClassName("pointsPanel")', 15) + checked_main_page = False + for response in t.GetHTTPResponses(): + # Site has a lot on it, just check the main page. + if (response.url == 'http://html5test.com/' + or response.url == 'http://html5test.com/index.html'): + self.assertHasChromeProxyViaHeader(response) + checked_main_page = True + if not checked_main_page: + self.fail("Did not check any page!") +if __name__ == '__main__': + IntegrationTest.RunAllTests()
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp index 82d41d3..a8b8f4b 100644 --- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp +++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -1215,28 +1215,29 @@ // Find location of the gmock_##MockedMethod identifier. clang::SourceLocation target_loc = Base::GetTargetLoc(result); - // Find location of EXPECT_CALL macro invocation. + // Find location of EXPECT_CALL or ON_CALL macro invocation. clang::SourceLocation macro_call_loc = result.SourceManager->getExpansionLoc(target_loc); // Map |macro_call_loc| to argument location (location of the method name // that needs renaming). - auto it = expect_call_to_2nd_arg.find(macro_call_loc); - if (it == expect_call_to_2nd_arg.end()) + auto it = gmock_macro_call_to_2nd_arg.find(macro_call_loc); + if (it == gmock_macro_call_to_2nd_arg.end()) return clang::SourceLocation(); return it->second; } private: - std::map<clang::SourceLocation, clang::SourceLocation> expect_call_to_2nd_arg; + std::map<clang::SourceLocation, clang::SourceLocation> + gmock_macro_call_to_2nd_arg; - // Called from PPCallbacks with the locations of EXPECT_CALL macro invocation: - // Example: + // Called from PPCallbacks with the locations of EXPECT_CALL and ON_CALL macro + // invocation. Example: // EXPECT_CALL(my_mock, myMethod(123, 456)); // ^- expansion_loc ^- actual_arg_loc - void RecordExpectCallMacroInvocation(clang::SourceLocation expansion_loc, - clang::SourceLocation second_arg_loc) { - expect_call_to_2nd_arg[expansion_loc] = second_arg_loc; + void RecordGMockMacroInvocation(clang::SourceLocation expansion_loc, + clang::SourceLocation second_arg_loc) { + gmock_macro_call_to_2nd_arg[expansion_loc] = second_arg_loc; } class PPCallbacks : public clang::PPCallbacks { @@ -1251,7 +1252,7 @@ if (!id) return; - if (id->getName() != "EXPECT_CALL") + if (id->getName() != "EXPECT_CALL" && id->getName() != "ON_CALL") return; if (def.getMacroInfo()->getNumArgs() != 2) @@ -1261,7 +1262,7 @@ // is in testing/gmock/include/gmock/gmock-spec-builders.h but I don't // know how to get clang::SourceManager to call getFileName. - rewriter_->RecordExpectCallMacroInvocation( + rewriter_->RecordGMockMacroInvocation( name.getLocation(), args->getUnexpArgument(1)->getLocation()); } @@ -1824,7 +1825,9 @@ // GMock calls lookup ======== // Given // EXPECT_CALL(obj, myMethod(...)) - // will match obj.gmock_myMethod(...) call generated by the macro + // or + // ON_CALL(obj, myMethod(...)) + // will match obj.gmock_myMethod(...) call generated by the macros // (but only if it mocks a Blink method). auto gmock_member_matcher = id("expr", memberExpr(hasDeclaration(
diff --git a/tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc index 66b6fc3..e4f199b 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc
@@ -25,6 +25,10 @@ mocked_interface, // A comment to prevent reformatting into single line. MyMethod(1)); mocked_interface.MyMethod(123); + + int arg; + ON_CALL(mocked_interface, MyMethod(1)) + .WillByDefault(testing::SaveArg<0>(&arg)); } } // namespace simple_test
diff --git a/tools/clang/rewrite_to_chrome_style/tests/gmock-original.cc b/tools/clang/rewrite_to_chrome_style/tests/gmock-original.cc index 81150e11..71eda686 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/gmock-original.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/gmock-original.cc
@@ -25,6 +25,10 @@ mockedInterface, // A comment to prevent reformatting into single line. myMethod(1)); mockedInterface.myMethod(123); + + int arg; + ON_CALL(mockedInterface, myMethod(1)) + .WillByDefault(testing::SaveArg<0>(&arg)); } } // namespace simple_test
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ae1a8e6..35b3c77 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -8368,7 +8368,7 @@ <summary>The exception code encountered in a crash on Mac OS X.</summary> </histogram> -<histogram name="Crashpad.ExceptionCode.Win" enum="CrashExitCodes"> +<histogram name="Crashpad.ExceptionCode.Win" enum="CrashpadWinExceptionCodes"> <owner>crashpad-dev@chromium.org</owner> <summary>The exception code encountered in a crash on Windows.</summary> </histogram> @@ -8391,7 +8391,8 @@ </summary> </histogram> -<histogram name="Crashpad.HandlerCrash.ExceptionCode.Win" enum="CrashExitCodes"> +<histogram name="Crashpad.HandlerCrash.ExceptionCode.Win" + enum="CrashpadWinExceptionCodes"> <owner>crashpad-dev@chromium.org</owner> <summary> The exception code encountered for a crash of the crash handler process on @@ -82654,7 +82655,7 @@ <int value="786949" label="EXC_GUARD/GUARD_TYPE_FD/kGUARD_EXC_MISMATCH"/> <int value="786950" label="EXC_GUARD/GUARD_TYPE_FD/kGUARD_EXC_WRITE"/> <int value="851968" label="EXC_CORPSE_NOTIFY/0"/> - <int value="1129345912" label="kMachExceptionSimulated"/> + <int value="1129345912" label="crashpad::kMachExceptionSimulated"/> </enum> <enum name="CrashpadReportPending" type="int"> @@ -82675,6 +82676,73 @@ <int value="4" label="kUploadFailed"/> </enum> +<enum name="CrashpadWinExceptionCodes" type="int"> + <int value="-2147483647" label="EXCEPTION_GUARD_PAGE"/> + <int value="-2147483646" label="EXCEPTION_DATATYPE_MISALIGNMENT"/> + <int value="-2147483645" label="EXCEPTION_BREAKPOINT"/> + <int value="-2147483644" label="EXCEPTION_SINGLE_STEP"/> + <int value="-1073741822" label="STATUS_NOT_IMPLEMENTED"/> + <int value="-1073741819" label="EXCEPTION_ACCESS_VIOLATION"/> + <int value="-1073741818" label="EXCEPTION_IN_PAGE_ERROR"/> + <int value="-1073741816" label="EXCEPTION_INVALID_HANDLE"/> + <int value="-1073741811" label="STATUS_INVALID_PARAMETER"/> + <int value="-1073741803" label="STATUS_NONEXISTENT_SECTOR"/> + <int value="-1073741801" label="STATUS_NO_MEMORY"/> + <int value="-1073741795" label="EXCEPTION_ILLEGAL_INSTRUCTION"/> + <int value="-1073741794" label="STATUS_INVALID_LOCK_SEQUENCE"/> + <int value="-1073741790" label="STATUS_ACCESS_DENIED"/> + <int value="-1073741788" label="STATUS_OBJECT_TYPE_MISMATCH"/> + <int value="-1073741739" label="STATUS_LOCK_NOT_GRANTED"/> + <int value="-1073741684" label="EXCEPTION_ARRAY_BOUNDS_EXCEEDED"/> + <int value="-1073741682" label="EXCEPTION_FLT_DIVIDE_BY_ZERO"/> + <int value="-1073741681" label="EXCEPTION_FLT_INEXACT_RESULT"/> + <int value="-1073741680" label="EXCEPTION_FLT_INVALID_OPERATION"/> + <int value="-1073741679" label="EXCEPTION_FLT_OVERFLOW"/> + <int value="-1073741678" label="EXCEPTION_FLT_STACK_CHECK"/> + <int value="-1073741677" label="EXCEPTION_FLT_UNDERFLOW"/> + <int value="-1073741676" label="EXCEPTION_INT_DIVIDE_BY_ZERO"/> + <int value="-1073741675" label="EXCEPTION_INT_OVERFLOW"/> + <int value="-1073741674" label="EXCEPTION_PRIV_INSTRUCTION"/> + <int value="-1073741571" label="EXCEPTION_STACK_OVERFLOW"/> + <int value="-1073741569" label="STATUS_BAD_FUNCTION_TABLE"/> + <int value="-1073741420" label="EXCEPTION_POSSIBLE_DEADLOCK"/> + <int value="-1073741224" label="STATUS_NO_CALLBACK_ACTIVE"/> + <int value="-1073741212" label="STATUS_RESOURCE_NOT_OWNED"/> + <int value="-1073741132" label="STATUS_FLOAT_MULTIPLE_FAULTS"/> + <int value="-1073741131" label="STATUS_FLOAT_MULTIPLE_TRAPS"/> + <int value="-1073740791" label="STATUS_STACK_BUFFER_OVERRUN"/> + <int value="-1073740022" label="STATUS_THREADPOOL_HANDLE_EXCEPTION"/> + <int value="-1073740021" + label="STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED"/> + <int value="-1073740020" + label="STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED"/> + <int value="-1073740018" + label="STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED"/> + <int value="-1073740016" + label="STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING"/> + <int value="-1073740004" label="STATUS_INVALID_THREAD"/> + <int value="-1073740003" label="STATUS_CALLBACK_RETURNED_TRANSACTION"/> + <int value="-1073740002" label="STATUS_CALLBACK_RETURNED_LDR_LOCK"/> + <int value="-1073740001" label="STATUS_CALLBACK_RETURNED_LANG"/> + <int value="-1073610685" label="RPC_NT_INTERNAL_ERROR"/> + <int value="-1072365553" label="STATUS_SXS_EARLY_DEACTIVATION"/> + <int value="-1072365552" label="STATUS_SXS_INVALID_DEACTIVATION"/> + <int value="-1072365551" label="STATUS_SXS_MULTIPLE_DEACTIVATION"/> + <int value="-1072365548" label="STATUS_SXS_CORRUPT_ACTIVATION_STACK"/> + <int value="-1066598274" label="FACILITY_VISUALCPP/ERROR_MOD_NOT_FOUND"/> + <int value="-1066598273" label="FACILITY_VISUALCPP/ERROR_PROC_NOT_FOUND"/> + <int value="-536870904" label="base::win::kOomExceptionCode"/> + <int value="-529697949" label="EH_EXCEPTION_NUMBER"/> + <int value="1285" label="ERROR_DELAY_LOAD_FAILED"/> + <int value="1717" label="RPC_S_UNKNOWN_IF"/> + <int value="1722" label="RPC_S_SERVER_UNAVAILABLE"/> + <int value="1726" label="RPC_S_CALL_FAILED"/> + <int value="1766" label="RPC_S_INTERNAL_ERROR"/> + <int value="1783" label="RPC_X_BAD_STUB_DATA"/> + <int value="1818" label="RPC_S_CALL_CANCELLED"/> + <int value="85436397" label="crashpad::kSimulatedExceptionCode"/> +</enum> + <enum name="CreatePersistentHistogramResult" type="int"> <int value="0" label="Success: Histogram created in persistent space."/> <int value="1" label="Error: Invalid metadata pointer. (coding error)"/>