diff --git a/DEPS b/DEPS index e9984c8..bb2068c 100644 --- a/DEPS +++ b/DEPS
@@ -105,11 +105,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': '903fb041a2f86e6273afa501e8e15335cd4e9972', + 'skia_revision': '734b2a859784af0b16dbbe07570e6d2f5da34e76', # 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': '22a88d89e037d3e95dc320f09544b16e9959a407', + 'v8_revision': '696e3951665ffc632c6a154a1d2b14c3b3e92212', # 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. @@ -117,7 +117,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '522095f7d7fe04bf1479a20a9707372d988a9da2', + 'angle_revision': '06235df9ff91acdf3cf50f2a6febb38b5e26cc6b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -125,11 +125,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '8fb6f6a129f5ed809db7ba3a8bc862dd5e7bc75d', + 'swiftshader_revision': 'be5fe7797f1e1dbf96f3f337604a4711e871a30a', # 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': 'c62aa207e9acb919c33df5f3694fe159619dda86', + 'pdfium_revision': 'aa50728980036f07fda232cea974fd80c89b7cb7', # 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. @@ -165,7 +165,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '2a64e6b6d554193f50f82d9557442615457365d9', + 'catapult_revision': 'ca2b32c844637750526112f1af7fbb28b17a8f83', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -539,7 +539,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'b96253cab7d9acd6c40a22e1f8f192e61fbc027a', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'dad47a9531e45fd79083ff2c0919e39cbafef28c', 'condition': 'checkout_linux', }, @@ -912,7 +912,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'ee5a26d974beef5a5bdab7d6cf0e97785a7e1c48', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '43ee74f7bd72edebbe5c7642d4df956dbf52bd03', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1034,7 +1034,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '21dbf06b5aa6c7dc8cf56314d4a3f96f57956c53', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '25cc8ad198731ff8eee35859d82919949afbdff7', + Var('webrtc_git') + '/src.git' + '@' + 'e09e6ef947d7bb6c29fa36c331bd855baacfafbc', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni index 2c0f997..09fd7aa 100644 --- a/android_webview/system_webview_apk_tmpl.gni +++ b/android_webview/system_webview_apk_tmpl.gni
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//base/android/proguard/proguard.gni") import("//build/config/android/config.gni") import("//build/config/android/rules.gni") import("//build/config/locales.gni") @@ -53,8 +54,14 @@ "//android_webview/apk/java/proguard.flags", "//base/android/proguard/chromium_apk.flags", "//base/android/proguard/chromium_code.flags", - "//base/android/proguard/disable_all_obfuscation.flags", ] + if (enable_proguard_obfuscation) { + proguard_configs += + [ "//base/android/proguard/enable_obfuscation.flags" ] + } else { + proguard_configs += + [ "//base/android/proguard/disable_all_obfuscation.flags" ] + } png_to_webp = true } command_line_flags_file = "webview-command-line"
diff --git a/base/allocator/partition_allocator/address_space_randomization.cc b/base/allocator/partition_allocator/address_space_randomization.cc index a7e17c7c..8701f56 100644 --- a/base/allocator/partition_allocator/address_space_randomization.cc +++ b/base/allocator/partition_allocator/address_space_randomization.cc
@@ -22,7 +22,7 @@ // This is the same PRNG as used by tcmalloc for mapping address randomness; // see http://burtleburtle.net/bob/rand/smallprng.html -struct ranctx { +struct RandomContext { subtle::SpinLock lock; bool initialized; uint32_t a; @@ -31,11 +31,12 @@ uint32_t d; }; -static LazyInstance<ranctx>::Leaky s_ranctx = LAZY_INSTANCE_INITIALIZER; +static LazyInstance<RandomContext>::Leaky s_RandomContext = + LAZY_INSTANCE_INITIALIZER; #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) -uint32_t ranvalInternal(ranctx* x) { +uint32_t RandomValueInternal(RandomContext* x) { uint32_t e = x->a - rot(x->b, 27); x->a = x->b ^ rot(x->c, 17); x->b = x->c + x->d; @@ -46,7 +47,7 @@ #undef rot -uint32_t ranval(ranctx* x) { +uint32_t RandomValue(RandomContext* x) { subtle::SpinLock::Guard guard(x->lock); if (UNLIKELY(!x->initialized)) { const uint64_t r1 = RandUint64(); @@ -60,13 +61,13 @@ x->initialized = true; } - return ranvalInternal(x); + return RandomValueInternal(x); } } // namespace void SetRandomPageBaseSeed(int64_t seed) { - ranctx* x = s_ranctx.Pointer(); + RandomContext* x = s_RandomContext.Pointer(); subtle::SpinLock::Guard guard(x->lock); // Set RNG to initial state. x->initialized = true; @@ -75,11 +76,12 @@ } void* GetRandomPageBase() { - uintptr_t random = static_cast<uintptr_t>(ranval(s_ranctx.Pointer())); + uintptr_t random = + static_cast<uintptr_t>(RandomValue(s_RandomContext.Pointer())); #if defined(ARCH_CPU_64_BITS) random <<= 32ULL; - random |= static_cast<uintptr_t>(ranval(s_ranctx.Pointer())); + random |= static_cast<uintptr_t>(RandomValue(s_RandomContext.Pointer())); // The kASLRMask and kASLROffset constants will be suitable for the // OS and build configuration.
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc index 8554673..e730aac 100644 --- a/base/allocator/partition_allocator/partition_alloc.cc +++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -146,7 +146,7 @@ // code simpler and the structures more generic. size_t i, j; size_t current_size = kGenericSmallestBucket; - size_t currentIncrement = + size_t current_increment = kGenericSmallestBucket >> kGenericNumBucketsPerOrderBits; internal::PartitionBucket* bucket = &this->buckets[0]; for (i = 0; i < kGenericNumBucketedOrders; ++i) { @@ -155,40 +155,40 @@ // Disable psuedo buckets so that touching them faults. if (current_size % kGenericSmallestBucket) bucket->active_pages_head = nullptr; - current_size += currentIncrement; + current_size += current_increment; ++bucket; } - currentIncrement <<= 1; + current_increment <<= 1; } DCHECK(current_size == 1 << kGenericMaxBucketedOrder); DCHECK(bucket == &this->buckets[0] + kGenericNumBuckets); // Then set up the fast size -> bucket lookup table. bucket = &this->buckets[0]; - internal::PartitionBucket** bucketPtr = &this->bucket_lookups[0]; + internal::PartitionBucket** bucket_ptr = &this->bucket_lookups[0]; for (order = 0; order <= kBitsPerSizeT; ++order) { for (j = 0; j < kGenericNumBucketsPerOrder; ++j) { if (order < kGenericMinBucketedOrder) { // Use the bucket of the finest granularity for malloc(0) etc. - *bucketPtr++ = &this->buckets[0]; + *bucket_ptr++ = &this->buckets[0]; } else if (order > kGenericMaxBucketedOrder) { - *bucketPtr++ = internal::PartitionBucket::get_sentinel_bucket(); + *bucket_ptr++ = internal::PartitionBucket::get_sentinel_bucket(); } else { - internal::PartitionBucket* validBucket = bucket; + internal::PartitionBucket* valid_bucket = bucket; // Skip over invalid buckets. - while (validBucket->slot_size % kGenericSmallestBucket) - validBucket++; - *bucketPtr++ = validBucket; + while (valid_bucket->slot_size % kGenericSmallestBucket) + valid_bucket++; + *bucket_ptr++ = valid_bucket; bucket++; } } } DCHECK(bucket == &this->buckets[0] + kGenericNumBuckets); - DCHECK(bucketPtr == &this->bucket_lookups[0] + - ((kBitsPerSizeT + 1) * kGenericNumBucketsPerOrder)); + DCHECK(bucket_ptr == &this->bucket_lookups[0] + + ((kBitsPerSizeT + 1) * kGenericNumBucketsPerOrder)); // And there's one last bucket lookup that will be hit for e.g. malloc(-1), // which tries to overflow to a non-existant order. - *bucketPtr = internal::PartitionBucket::get_sentinel_bucket(); + *bucket_ptr = internal::PartitionBucket::get_sentinel_bucket(); } bool PartitionReallocDirectMappedInPlace(PartitionRootGeneric* root, @@ -221,9 +221,9 @@ return false; // Shrink by decommitting unneeded pages and making them inaccessible. - size_t decommitSize = current_size - new_size; - root->DecommitSystemPages(char_ptr + new_size, decommitSize); - CHECK(SetSystemPagesAccess(char_ptr + new_size, decommitSize, + size_t decommit_size = current_size - new_size; + root->DecommitSystemPages(char_ptr + new_size, decommit_size); + CHECK(SetSystemPagesAccess(char_ptr + new_size, decommit_size, PageInaccessible)); } else if (new_size <= internal::PartitionDirectMapExtent::FromPage(page)->map_size) { @@ -303,7 +303,7 @@ // new size is a significant percentage smaller. We could do the same if we // determine it is a win. if (actual_new_size == actual_old_size) { - // Trying to allocate a block of size new_size would give us a block of + // Trying to allocate a block of size |new_size| would give us a block of // the same size as the one we've already got, so re-use the allocation // after updating statistics (and cookies, if present). page->set_raw_size(internal::PartitionCookieSizeAdjustAdd(new_size)); @@ -341,6 +341,13 @@ return PartitionReallocGenericFlags(this, 0, ptr, new_size, type_name); } +void* PartitionRootGeneric::TryRealloc(void* ptr, + size_t new_size, + const char* type_name) { + return PartitionReallocGenericFlags(this, PartitionAllocReturnNull, ptr, + new_size, type_name); +} + static size_t PartitionPurgePage(internal::PartitionPage* page, bool discard) { const internal::PartitionBucket* bucket = page->bucket; size_t slot_size = bucket->slot_size; @@ -352,12 +359,12 @@ size_t raw_size = page->get_raw_size(); if (raw_size) { - uint32_t usedBytes = static_cast<uint32_t>(RoundUpToSystemPage(raw_size)); - discardable_bytes = bucket->slot_size - usedBytes; + uint32_t used_bytes = static_cast<uint32_t>(RoundUpToSystemPage(raw_size)); + discardable_bytes = bucket->slot_size - used_bytes; if (discardable_bytes && discard) { char* ptr = reinterpret_cast<char*>(internal::PartitionPage::ToPointer(page)); - ptr += usedBytes; + ptr += used_bytes; DiscardSystemPages(ptr, discardable_bytes); } return discardable_bytes; @@ -380,23 +387,23 @@ // are not in use. for (internal::PartitionFreelistEntry* entry = page->freelist_head; entry; /**/) { - size_t slotIndex = (reinterpret_cast<char*>(entry) - ptr) / slot_size; - DCHECK(slotIndex < num_slots); - slot_usage[slotIndex] = 0; + size_t slot_index = (reinterpret_cast<char*>(entry) - ptr) / slot_size; + DCHECK(slot_index < num_slots); + slot_usage[slot_index] = 0; entry = internal::PartitionFreelistEntry::Transform(entry->next); #if !defined(OS_WIN) - // If we have a slot where the masked freelist entry is 0, we can - // actually discard that freelist entry because touching a discarded - // page is guaranteed to return original content or 0. - // (Note that this optimization won't fire on big endian machines - // because the masking function is negation.) + // If we have a slot where the masked freelist entry is 0, we can actually + // discard that freelist entry because touching a discarded page is + // guaranteed to return original content or 0. (Note that this optimization + // won't fire on big-endian machines because the masking function is + // negation.) if (!internal::PartitionFreelistEntry::Transform(entry)) - last_slot = slotIndex; + last_slot = slot_index; #endif } - // If the slot(s) at the end of the slot span are not in used, we can - // truncate them entirely and rewrite the freelist. + // If the slot(s) at the end of the slot span are not in used, we can truncate + // them entirely and rewrite the freelist. size_t truncated_slots = 0; while (!slot_usage[num_slots - 1]) { truncated_slots++; @@ -411,8 +418,8 @@ char* end_ptr = begin_ptr + (slot_size * truncated_slots); begin_ptr = reinterpret_cast<char*>( RoundUpToSystemPage(reinterpret_cast<size_t>(begin_ptr))); - // We round the end pointer here up and not down because we're at the - // end of a slot span, so we "own" all the way up the page boundary. + // We round the end pointer here up and not down because we're at the end of + // a slot span, so we "own" all the way up the page boundary. end_ptr = reinterpret_cast<char*>( RoundUpToSystemPage(reinterpret_cast<size_t>(end_ptr))); DCHECK(end_ptr <= ptr + bucket->get_bytes_per_span()); @@ -426,16 +433,16 @@ page->num_unprovisioned_slots += static_cast<uint16_t>(truncated_slots); // Rewrite the freelist. internal::PartitionFreelistEntry** entry_ptr = &page->freelist_head; - for (size_t slotIndex = 0; slotIndex < num_slots; ++slotIndex) { - if (slot_usage[slotIndex]) + for (size_t slot_index = 0; slot_index < num_slots; ++slot_index) { + if (slot_usage[slot_index]) continue; auto* entry = reinterpret_cast<internal::PartitionFreelistEntry*>( - ptr + (slot_size * slotIndex)); + ptr + (slot_size * slot_index)); *entry_ptr = internal::PartitionFreelistEntry::Transform(entry); entry_ptr = reinterpret_cast<internal::PartitionFreelistEntry**>(entry); num_new_entries++; #if !defined(OS_WIN) - last_slot = slotIndex; + last_slot = slot_index; #endif } // Terminate the freelist chain. @@ -449,16 +456,15 @@ } } - // Next, walk the slots and for any not in use, consider where the system - // page boundaries occur. We can release any system pages back to the - // system as long as we don't interfere with a freelist pointer or an - // adjacent slot. + // Next, walk the slots and for any not in use, consider where the system page + // boundaries occur. We can release any system pages back to the system as + // long as we don't interfere with a freelist pointer or an adjacent slot. for (size_t i = 0; i < num_slots; ++i) { if (slot_usage[i]) continue; // The first address we can safely discard is just after the freelist - // pointer. There's one quirk: if the freelist pointer is actually a - // null, we can discard that pointer value too. + // pointer. There's one quirk: if the freelist pointer is actually NULL, we + // can discard that pointer value too. char* begin_ptr = ptr + (i * slot_size); char* end_ptr = begin_ptr + slot_size; #if !defined(OS_WIN) @@ -496,9 +502,9 @@ if (flags & PartitionPurgeDecommitEmptyPages) DecommitEmptyPages(); // We don't currently do anything for PartitionPurgeDiscardUnusedSystemPages - // here because that flag is only useful for allocations >= system page - // size. We only have allocations that large inside generic partitions - // at the moment. + // here because that flag is only useful for allocations >= system page size. + // We only have allocations that large inside generic partitions at the + // moment. } void PartitionRootGeneric::PurgeMemory(int flags) { @@ -553,9 +559,8 @@ DCHECK(!bucket->is_direct_mapped()); stats_out->is_valid = false; // If the active page list is empty (== - // internal::PartitionPage::get_sentinel_page()), - // the bucket might still need to be reported if it has a list of empty, - // decommitted or full pages. + // internal::PartitionPage::get_sentinel_page()), the bucket might still need + // to be reported if it has a list of empty, decommitted or full pages. if (bucket->active_pages_head == internal::PartitionPage::get_sentinel_page() && !bucket->empty_pages_head && !bucket->decommitted_pages_head && @@ -693,10 +698,10 @@ memory_stats = std::unique_ptr<PartitionBucketMemoryStats[]>( new PartitionBucketMemoryStats[kMaxReportableBuckets]); - const size_t partitionNumBuckets = this->num_buckets; - DCHECK(partitionNumBuckets <= kMaxReportableBuckets); + const size_t partition_num_buckets = this->num_buckets; + DCHECK(partition_num_buckets <= kMaxReportableBuckets); - for (size_t i = 0; i < partitionNumBuckets; ++i) { + for (size_t i = 0; i < partition_num_buckets; ++i) { PartitionBucketMemoryStats bucket_stats = {0}; PartitionDumpBucketStats(&bucket_stats, &this->buckets()[i]); if (bucket_stats.is_valid) { @@ -716,7 +721,7 @@ // PartitionsDumpBucketStats is called after collecting stats because it // can use PartitionRoot::Alloc() to allocate and this can affect the // statistics. - for (size_t i = 0; i < partitionNumBuckets; ++i) { + for (size_t i = 0; i < partition_num_buckets; ++i) { if (memory_stats[i].is_valid) dumper->PartitionsDumpBucketStats(partition_name, &memory_stats[i]); }
diff --git a/base/allocator/partition_allocator/partition_alloc.h b/base/allocator/partition_allocator/partition_alloc.h index 79d09053..0294ef92 100644 --- a/base/allocator/partition_allocator/partition_alloc.h +++ b/base/allocator/partition_allocator/partition_alloc.h
@@ -148,6 +148,9 @@ ALWAYS_INLINE void Free(void* ptr); NOINLINE void* Realloc(void* ptr, size_t new_size, const char* type_name); + // Overload that may return nullptr if reallocation isn't possible. In this + // case, |ptr| remains valid. + NOINLINE void* TryRealloc(void* ptr, size_t new_size, const char* type_name); ALWAYS_INLINE size_t ActualSize(size_t size);
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index afff0906b..ad91965 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -182,7 +182,13 @@ } } - void DoReturnNullTest(size_t allocSize, bool use_realloc) { + enum ReturnNullTestMode { + kPartitionAllocGenericFlags, + kPartitionReallocGenericFlags, + kPartitionRootGenericTryRealloc, + }; + + void DoReturnNullTest(size_t alloc_size, ReturnNullTestMode mode) { // TODO(crbug.com/678782): Where necessary and possible, disable the // platform's OOM-killing behavior. OOM-killing makes this test flaky on // low-memory devices. @@ -195,30 +201,42 @@ ASSERT_TRUE(SetAddressSpaceLimit()); // Work out the number of allocations for 6 GB of memory. - const int numAllocations = (6 * 1024 * 1024) / (allocSize / 1024); + const int num_allocations = (6 * 1024 * 1024) / (alloc_size / 1024); void** ptrs = reinterpret_cast<void**>(generic_allocator.root()->Alloc( - numAllocations * sizeof(void*), type_name)); + num_allocations * sizeof(void*), type_name)); int i; - for (i = 0; i < numAllocations; ++i) { - if (use_realloc) { - ptrs[i] = PartitionAllocGenericFlags( - generic_allocator.root(), PartitionAllocReturnNull, 1, type_name); - ptrs[i] = PartitionReallocGenericFlags(generic_allocator.root(), + for (i = 0; i < num_allocations; ++i) { + switch (mode) { + case kPartitionAllocGenericFlags: { + ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), PartitionAllocReturnNull, - ptrs[i], allocSize, type_name); - } else { - ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), - PartitionAllocReturnNull, - allocSize, type_name); + alloc_size, type_name); + break; + } + case kPartitionReallocGenericFlags: { + ptrs[i] = PartitionAllocGenericFlags( + generic_allocator.root(), PartitionAllocReturnNull, 1, type_name); + ptrs[i] = PartitionReallocGenericFlags( + generic_allocator.root(), PartitionAllocReturnNull, ptrs[i], + alloc_size, type_name); + break; + } + case kPartitionRootGenericTryRealloc: { + ptrs[i] = PartitionAllocGenericFlags( + generic_allocator.root(), PartitionAllocReturnNull, 1, type_name); + ptrs[i] = generic_allocator.root()->TryRealloc(ptrs[i], alloc_size, + type_name); + } } + if (!i) EXPECT_TRUE(ptrs[0]); if (!ptrs[i]) { ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), PartitionAllocReturnNull, - allocSize, type_name); + alloc_size, type_name); EXPECT_FALSE(ptrs[i]); break; } @@ -226,14 +244,14 @@ // We shouldn't succeed in allocating all 6 GB of memory. If we do, then // we're not actually testing anything here. - EXPECT_LT(i, numAllocations); + EXPECT_LT(i, num_allocations); // Free, reallocate and free again each block we allocated. We do this to // check that freeing memory also works correctly after a failed allocation. for (--i; i >= 0; --i) { generic_allocator.root()->Free(ptrs[i]); ptrs[i] = PartitionAllocGenericFlags(generic_allocator.root(), - PartitionAllocReturnNull, allocSize, + PartitionAllocReturnNull, alloc_size, type_name); EXPECT_TRUE(ptrs[i]); generic_allocator.root()->Free(ptrs[i]); @@ -335,11 +353,11 @@ // Check that the most basic of allocate / free pairs work. TEST_F(PartitionAllocTest, Basic) { PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex]; - PartitionPage* seedPage = PartitionPage::get_sentinel_page(); + PartitionPage* seed_page = PartitionPage::get_sentinel_page(); EXPECT_FALSE(bucket->empty_pages_head); EXPECT_FALSE(bucket->decommitted_pages_head); - EXPECT_EQ(seedPage, bucket->active_pages_head); + EXPECT_EQ(seed_page, bucket->active_pages_head); EXPECT_EQ(nullptr, bucket->active_pages_head->next_page); void* ptr = allocator.root()->Alloc(kTestAllocSize, type_name); @@ -467,9 +485,9 @@ PartitionFree(ptr); // Trying to allocate at this time should cause us to cycle around to page2 // and find the recently freed slot. - char* newPtr = reinterpret_cast<char*>( + char* new_ptr = reinterpret_cast<char*>( allocator.root()->Alloc(kTestAllocSize, type_name)); - EXPECT_EQ(ptr, newPtr); + EXPECT_EQ(ptr, new_ptr); EXPECT_EQ(page2, bucket->active_pages_head); EXPECT_EQ(page3, page2->next_page); @@ -479,9 +497,9 @@ reinterpret_cast<char*>(PartitionPage::ToPointer(page1)) + kPointerOffset; PartitionFree(ptr); // This allocation should be satisfied by page1. - newPtr = reinterpret_cast<char*>( + new_ptr = reinterpret_cast<char*>( allocator.root()->Alloc(kTestAllocSize, type_name)); - EXPECT_EQ(ptr, newPtr); + EXPECT_EQ(ptr, new_ptr); EXPECT_EQ(page1, bucket->active_pages_head); EXPECT_EQ(page2, page1->next_page); @@ -500,19 +518,19 @@ TEST_F(PartitionAllocTest, FreePageListPageTransitions) { PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex]; - size_t numToFillFreeListPage = + size_t num_to_fill_free_list_page = kPartitionPageSize / (sizeof(PartitionPage) + kExtraAllocSize); // The +1 is because we need to account for the fact that the current page // never gets thrown on the freelist. - ++numToFillFreeListPage; - auto pages = std::make_unique<PartitionPage* []>(numToFillFreeListPage); + ++num_to_fill_free_list_page; + auto pages = std::make_unique<PartitionPage* []>(num_to_fill_free_list_page); size_t i; - for (i = 0; i < numToFillFreeListPage; ++i) { + for (i = 0; i < num_to_fill_free_list_page; ++i) { pages[i] = GetFullPage(kTestAllocSize); } - EXPECT_EQ(pages[numToFillFreeListPage - 1], bucket->active_pages_head); - for (i = 0; i < numToFillFreeListPage; ++i) + EXPECT_EQ(pages[num_to_fill_free_list_page - 1], bucket->active_pages_head); + for (i = 0; i < num_to_fill_free_list_page; ++i) FreeFullPage(pages[i]); EXPECT_EQ(PartitionPage::get_sentinel_page(), bucket->active_pages_head); EXPECT_TRUE(bucket->empty_pages_head); @@ -525,12 +543,12 @@ FreeFullPage(page1); FreeFullPage(page2); - for (i = 0; i < numToFillFreeListPage; ++i) { + for (i = 0; i < num_to_fill_free_list_page; ++i) { pages[i] = GetFullPage(kTestAllocSize); } - EXPECT_EQ(pages[numToFillFreeListPage - 1], bucket->active_pages_head); + EXPECT_EQ(pages[num_to_fill_free_list_page - 1], bucket->active_pages_head); - for (i = 0; i < numToFillFreeListPage; ++i) + for (i = 0; i < num_to_fill_free_list_page; ++i) FreeFullPage(pages[i]); EXPECT_EQ(PartitionPage::get_sentinel_page(), bucket->active_pages_head); EXPECT_TRUE(bucket->empty_pages_head); @@ -541,32 +559,32 @@ TEST_F(PartitionAllocTest, MultiPageAllocs) { // This is guaranteed to cross a super page boundary because the first // partition page "slot" will be taken up by a guard page. - size_t numPagesNeeded = kNumPartitionPagesPerSuperPage; + size_t num_pages_needed = kNumPartitionPagesPerSuperPage; // The super page should begin and end in a guard so we one less page in // order to allocate a single page in the new super page. - --numPagesNeeded; + --num_pages_needed; - EXPECT_GT(numPagesNeeded, 1u); - auto pages = std::make_unique<PartitionPage* []>(numPagesNeeded); - uintptr_t firstSuperPageBase = 0; + EXPECT_GT(num_pages_needed, 1u); + auto pages = std::make_unique<PartitionPage* []>(num_pages_needed); + uintptr_t first_super_page_base = 0; size_t i; - for (i = 0; i < numPagesNeeded; ++i) { + for (i = 0; i < num_pages_needed; ++i) { pages[i] = GetFullPage(kTestAllocSize); - void* storagePtr = PartitionPage::ToPointer(pages[i]); + void* storage_ptr = PartitionPage::ToPointer(pages[i]); if (!i) - firstSuperPageBase = - reinterpret_cast<uintptr_t>(storagePtr) & kSuperPageBaseMask; - if (i == numPagesNeeded - 1) { - uintptr_t secondSuperPageBase = - reinterpret_cast<uintptr_t>(storagePtr) & kSuperPageBaseMask; - uintptr_t secondSuperPageOffset = - reinterpret_cast<uintptr_t>(storagePtr) & kSuperPageOffsetMask; - EXPECT_FALSE(secondSuperPageBase == firstSuperPageBase); + first_super_page_base = + reinterpret_cast<uintptr_t>(storage_ptr) & kSuperPageBaseMask; + if (i == num_pages_needed - 1) { + uintptr_t second_super_page_base = + reinterpret_cast<uintptr_t>(storage_ptr) & kSuperPageBaseMask; + uintptr_t second_super_page_offset = + reinterpret_cast<uintptr_t>(storage_ptr) & kSuperPageOffsetMask; + EXPECT_FALSE(second_super_page_base == first_super_page_base); // Check that we allocated a guard page for the second page. - EXPECT_EQ(kPartitionPageSize, secondSuperPageOffset); + EXPECT_EQ(kPartitionPageSize, second_super_page_offset); } } - for (i = 0; i < numPagesNeeded; ++i) + for (i = 0; i < num_pages_needed; ++i) FreeFullPage(pages[i]); } @@ -582,81 +600,81 @@ ptr = generic_allocator.root()->Alloc(1, type_name); EXPECT_TRUE(ptr); - void* origPtr = ptr; - char* charPtr = static_cast<char*>(ptr); - *charPtr = 'A'; + void* orig_ptr = ptr; + char* char_ptr = static_cast<char*>(ptr); + *char_ptr = 'A'; // Change the size of the realloc, remaining inside the same bucket. - void* newPtr = generic_allocator.root()->Realloc(ptr, 2, type_name); - EXPECT_EQ(ptr, newPtr); - newPtr = generic_allocator.root()->Realloc(ptr, 1, type_name); - EXPECT_EQ(ptr, newPtr); - newPtr = + void* new_ptr = generic_allocator.root()->Realloc(ptr, 2, type_name); + EXPECT_EQ(ptr, new_ptr); + new_ptr = generic_allocator.root()->Realloc(ptr, 1, type_name); + EXPECT_EQ(ptr, new_ptr); + new_ptr = generic_allocator.root()->Realloc(ptr, kGenericSmallestBucket, type_name); - EXPECT_EQ(ptr, newPtr); + EXPECT_EQ(ptr, new_ptr); // Change the size of the realloc, switching buckets. - newPtr = generic_allocator.root()->Realloc(ptr, kGenericSmallestBucket + 1, - type_name); - EXPECT_NE(newPtr, ptr); + new_ptr = generic_allocator.root()->Realloc(ptr, kGenericSmallestBucket + 1, + type_name); + EXPECT_NE(new_ptr, ptr); // Check that the realloc copied correctly. - char* newCharPtr = static_cast<char*>(newPtr); - EXPECT_EQ(*newCharPtr, 'A'); + char* new_char_ptr = static_cast<char*>(new_ptr); + EXPECT_EQ(*new_char_ptr, 'A'); #if DCHECK_IS_ON() // Subtle: this checks for an old bug where we copied too much from the // source of the realloc. The condition can be detected by a trashing of // the uninitialized value in the space of the upsized allocation. - EXPECT_EQ(kUninitializedByte, - static_cast<unsigned char>(*(newCharPtr + kGenericSmallestBucket))); + EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>( + *(new_char_ptr + kGenericSmallestBucket))); #endif - *newCharPtr = 'B'; + *new_char_ptr = 'B'; // The realloc moved. To check that the old allocation was freed, we can // do an alloc of the old allocation size and check that the old allocation // address is at the head of the freelist and reused. - void* reusedPtr = generic_allocator.root()->Alloc(1, type_name); - EXPECT_EQ(reusedPtr, origPtr); - generic_allocator.root()->Free(reusedPtr); + void* reused_ptr = generic_allocator.root()->Alloc(1, type_name); + EXPECT_EQ(reused_ptr, orig_ptr); + generic_allocator.root()->Free(reused_ptr); // Downsize the realloc. - ptr = newPtr; - newPtr = generic_allocator.root()->Realloc(ptr, 1, type_name); - EXPECT_EQ(newPtr, origPtr); - newCharPtr = static_cast<char*>(newPtr); - EXPECT_EQ(*newCharPtr, 'B'); - *newCharPtr = 'C'; + ptr = new_ptr; + new_ptr = generic_allocator.root()->Realloc(ptr, 1, type_name); + EXPECT_EQ(new_ptr, orig_ptr); + new_char_ptr = static_cast<char*>(new_ptr); + EXPECT_EQ(*new_char_ptr, 'B'); + *new_char_ptr = 'C'; // Upsize the realloc to outside the partition. - ptr = newPtr; - newPtr = generic_allocator.root()->Realloc(ptr, kGenericMaxBucketed + 1, - type_name); - EXPECT_NE(newPtr, ptr); - newCharPtr = static_cast<char*>(newPtr); - EXPECT_EQ(*newCharPtr, 'C'); - *newCharPtr = 'D'; + ptr = new_ptr; + new_ptr = generic_allocator.root()->Realloc(ptr, kGenericMaxBucketed + 1, + type_name); + EXPECT_NE(new_ptr, ptr); + new_char_ptr = static_cast<char*>(new_ptr); + EXPECT_EQ(*new_char_ptr, 'C'); + *new_char_ptr = 'D'; // Upsize and downsize the realloc, remaining outside the partition. - ptr = newPtr; - newPtr = generic_allocator.root()->Realloc(ptr, kGenericMaxBucketed * 10, - type_name); - newCharPtr = static_cast<char*>(newPtr); - EXPECT_EQ(*newCharPtr, 'D'); - *newCharPtr = 'E'; - ptr = newPtr; - newPtr = generic_allocator.root()->Realloc(ptr, kGenericMaxBucketed * 2, - type_name); - newCharPtr = static_cast<char*>(newPtr); - EXPECT_EQ(*newCharPtr, 'E'); - *newCharPtr = 'F'; + ptr = new_ptr; + new_ptr = generic_allocator.root()->Realloc(ptr, kGenericMaxBucketed * 10, + type_name); + new_char_ptr = static_cast<char*>(new_ptr); + EXPECT_EQ(*new_char_ptr, 'D'); + *new_char_ptr = 'E'; + ptr = new_ptr; + new_ptr = generic_allocator.root()->Realloc(ptr, kGenericMaxBucketed * 2, + type_name); + new_char_ptr = static_cast<char*>(new_ptr); + EXPECT_EQ(*new_char_ptr, 'E'); + *new_char_ptr = 'F'; // Downsize the realloc to inside the partition. - ptr = newPtr; - newPtr = generic_allocator.root()->Realloc(ptr, 1, type_name); - EXPECT_NE(newPtr, ptr); - EXPECT_EQ(newPtr, origPtr); - newCharPtr = static_cast<char*>(newPtr); - EXPECT_EQ(*newCharPtr, 'F'); + ptr = new_ptr; + new_ptr = generic_allocator.root()->Realloc(ptr, 1, type_name); + EXPECT_NE(new_ptr, ptr); + EXPECT_EQ(new_ptr, orig_ptr); + new_char_ptr = static_cast<char*>(new_ptr); + EXPECT_EQ(*new_char_ptr, 'F'); - generic_allocator.root()->Free(newPtr); + generic_allocator.root()->Free(new_ptr); } // Test the generic allocation functions can handle some specific sizes of @@ -706,10 +724,10 @@ EXPECT_NE(-1, page->empty_cache_index); EXPECT_EQ(0, page->num_allocated_slots); EXPECT_EQ(0, page->num_unprovisioned_slots); - void* newPtr = generic_allocator.root()->Alloc(size, type_name); - EXPECT_EQ(ptr3, newPtr); - newPtr = generic_allocator.root()->Alloc(size, type_name); - EXPECT_EQ(ptr2, newPtr); + void* new_ptr = generic_allocator.root()->Alloc(size, type_name); + EXPECT_EQ(ptr3, new_ptr); + new_ptr = generic_allocator.root()->Alloc(size, type_name); + EXPECT_EQ(ptr2, new_ptr); #if defined(OS_LINUX) && !DCHECK_IS_ON() // On Linux, we have a guarantee that freelisting a page should cause its // contents to be nulled out. We check for null here to detect an bug we @@ -718,9 +736,9 @@ // We only run the check when asserts are disabled because when they are // enabled, the allocated area is overwritten with an "uninitialized" // byte pattern. - EXPECT_EQ(0, *(reinterpret_cast<char*>(newPtr) + (size - 1))); + EXPECT_EQ(0, *(reinterpret_cast<char*>(new_ptr) + (size - 1))); #endif - generic_allocator.root()->Free(newPtr); + generic_allocator.root()->Free(new_ptr); generic_allocator.root()->Free(ptr3); generic_allocator.root()->Free(ptr4); @@ -739,8 +757,8 @@ size -= kSystemPageSize; size -= 1; ptr = generic_allocator.root()->Alloc(size, type_name); - char* charPtr = reinterpret_cast<char*>(ptr); - *(charPtr + (size - 1)) = 'A'; + char* char_ptr = reinterpret_cast<char*>(ptr); + *(char_ptr + (size - 1)) = 'A'; generic_allocator.root()->Free(ptr); // Can we free null? @@ -794,8 +812,8 @@ EXPECT_EQ(predicted_size, actual_size); EXPECT_EQ(requested_size + kSystemPageSize, actual_size); // Check that we can write at the end of the reported size too. - char* charPtr = reinterpret_cast<char*>(ptr); - *(charPtr + (actual_size - 1)) = 'A'; + char* char_ptr = reinterpret_cast<char*>(ptr); + *(char_ptr + (actual_size - 1)) = 'A'; generic_allocator.root()->Free(ptr); // Allocate something very large, and uneven. @@ -837,22 +855,22 @@ memset(ptr, 'A', size); ptr2 = generic_allocator.root()->Realloc(ptr, size + 1, type_name); EXPECT_NE(ptr, ptr2); - char* charPtr2 = static_cast<char*>(ptr2); - EXPECT_EQ('A', charPtr2[0]); - EXPECT_EQ('A', charPtr2[size - 1]); + char* char_ptr2 = static_cast<char*>(ptr2); + EXPECT_EQ('A', char_ptr2[0]); + EXPECT_EQ('A', char_ptr2[size - 1]); #if DCHECK_IS_ON() - EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr2[size])); + EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(char_ptr2[size])); #endif // Test that shrinking an allocation with realloc() also copies everything // from the old allocation. ptr = generic_allocator.root()->Realloc(ptr2, size - 1, type_name); EXPECT_NE(ptr2, ptr); - char* charPtr = static_cast<char*>(ptr); - EXPECT_EQ('A', charPtr[0]); - EXPECT_EQ('A', charPtr[size - 2]); + char* char_ptr = static_cast<char*>(ptr); + EXPECT_EQ('A', char_ptr[0]); + EXPECT_EQ('A', char_ptr[size - 2]); #if DCHECK_IS_ON() - EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr[size - 1])); + EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(char_ptr[size - 1])); #endif generic_allocator.root()->Free(ptr); @@ -895,10 +913,10 @@ PartitionPage* page = PartitionPage::FromPointer(PartitionCookieFreePointerAdjust(ptr)); - size_t totalSlots = + size_t total_slots = (page->bucket->num_system_pages_per_slot_span * kSystemPageSize) / (big_size + kExtraAllocSize); - EXPECT_EQ(4u, totalSlots); + EXPECT_EQ(4u, total_slots); // The freelist should have one entry, because we were able to exactly fit // one object slot and one freelist pointer (the null that the head points // to) into a system page. @@ -958,12 +976,12 @@ EXPECT_TRUE(ptr); page = PartitionPage::FromPointer(PartitionCookieFreePointerAdjust(ptr)); EXPECT_EQ(1, page->num_allocated_slots); - totalSlots = + total_slots = (page->bucket->num_system_pages_per_slot_span * kSystemPageSize) / (mediumSize + kExtraAllocSize); - size_t firstPageSlots = kSystemPageSize / (mediumSize + kExtraAllocSize); - EXPECT_EQ(2u, firstPageSlots); - EXPECT_EQ(totalSlots - firstPageSlots, page->num_unprovisioned_slots); + size_t first_page_slots = kSystemPageSize / (mediumSize + kExtraAllocSize); + EXPECT_EQ(2u, first_page_slots); + EXPECT_EQ(total_slots - first_page_slots, page->num_unprovisioned_slots); PartitionFree(ptr); @@ -976,11 +994,11 @@ EXPECT_TRUE(ptr); page = PartitionPage::FromPointer(PartitionCookieFreePointerAdjust(ptr)); EXPECT_EQ(1, page->num_allocated_slots); - totalSlots = + total_slots = (page->bucket->num_system_pages_per_slot_span * kSystemPageSize) / (smallSize + kExtraAllocSize); - firstPageSlots = kSystemPageSize / (smallSize + kExtraAllocSize); - EXPECT_EQ(totalSlots - firstPageSlots, page->num_unprovisioned_slots); + first_page_slots = kSystemPageSize / (smallSize + kExtraAllocSize); + EXPECT_EQ(total_slots - first_page_slots, page->num_unprovisioned_slots); PartitionFree(ptr); EXPECT_TRUE(page->freelist_head); @@ -995,11 +1013,11 @@ EXPECT_TRUE(ptr); page = PartitionPage::FromPointer(PartitionCookieFreePointerAdjust(ptr)); EXPECT_EQ(1, page->num_allocated_slots); - totalSlots = + total_slots = (page->bucket->num_system_pages_per_slot_span * kSystemPageSize) / (verySmallSize + kExtraAllocSize); - firstPageSlots = kSystemPageSize / (verySmallSize + kExtraAllocSize); - EXPECT_EQ(totalSlots - firstPageSlots, page->num_unprovisioned_slots); + first_page_slots = kSystemPageSize / (verySmallSize + kExtraAllocSize); + EXPECT_EQ(total_slots - first_page_slots, page->num_unprovisioned_slots); PartitionFree(ptr); EXPECT_TRUE(page->freelist_head); @@ -1007,17 +1025,17 @@ // And try an allocation size (against the generic allocator) that is // larger than a system page. - size_t pageAndAHalfSize = + size_t page_and_a_half_size = (kSystemPageSize + (kSystemPageSize / 2)) - kExtraAllocSize; - ptr = generic_allocator.root()->Alloc(pageAndAHalfSize, type_name); + ptr = generic_allocator.root()->Alloc(page_and_a_half_size, type_name); EXPECT_TRUE(ptr); page = PartitionPage::FromPointer(PartitionCookieFreePointerAdjust(ptr)); EXPECT_EQ(1, page->num_allocated_slots); EXPECT_TRUE(page->freelist_head); - totalSlots = + total_slots = (page->bucket->num_system_pages_per_slot_span * kSystemPageSize) / - (pageAndAHalfSize + kExtraAllocSize); - EXPECT_EQ(totalSlots - 2, page->num_unprovisioned_slots); + (page_and_a_half_size + kExtraAllocSize); + EXPECT_EQ(total_slots - 2, page->num_unprovisioned_slots); generic_allocator.root()->Free(ptr); // And then make sure than exactly the page size only faults one page. @@ -1027,10 +1045,10 @@ page = PartitionPage::FromPointer(PartitionCookieFreePointerAdjust(ptr)); EXPECT_EQ(1, page->num_allocated_slots); EXPECT_FALSE(page->freelist_head); - totalSlots = + total_slots = (page->bucket->num_system_pages_per_slot_span * kSystemPageSize) / (pageSize + kExtraAllocSize); - EXPECT_EQ(totalSlots - 1, page->num_unprovisioned_slots); + EXPECT_EQ(total_slots - 1, page->num_unprovisioned_slots); generic_allocator.root()->Free(ptr); } @@ -1092,49 +1110,50 @@ TEST_F(PartitionAllocTest, MappingCollision) { // The -2 is because the first and last partition pages in a super page are // guard pages. - size_t numPartitionPagesNeeded = kNumPartitionPagesPerSuperPage - 2; - auto firstSuperPagePages = - std::make_unique<PartitionPage* []>(numPartitionPagesNeeded); - auto secondSuperPagePages = - std::make_unique<PartitionPage* []>(numPartitionPagesNeeded); + size_t num_partition_pages_needed = kNumPartitionPagesPerSuperPage - 2; + auto first_super_page_pages = + std::make_unique<PartitionPage* []>(num_partition_pages_needed); + auto second_super_page_pages = + std::make_unique<PartitionPage* []>(num_partition_pages_needed); size_t i; - for (i = 0; i < numPartitionPagesNeeded; ++i) - firstSuperPagePages[i] = GetFullPage(kTestAllocSize); + for (i = 0; i < num_partition_pages_needed; ++i) + first_super_page_pages[i] = GetFullPage(kTestAllocSize); - char* pageBase = - reinterpret_cast<char*>(PartitionPage::ToPointer(firstSuperPagePages[0])); + char* page_base = reinterpret_cast<char*>( + PartitionPage::ToPointer(first_super_page_pages[0])); EXPECT_EQ(kPartitionPageSize, - reinterpret_cast<uintptr_t>(pageBase) & kSuperPageOffsetMask); - pageBase -= kPartitionPageSize; + reinterpret_cast<uintptr_t>(page_base) & kSuperPageOffsetMask); + page_base -= kPartitionPageSize; // Map a single system page either side of the mapping for our allocations, // with the goal of tripping up alignment of the next mapping. - void* map1 = AllocPages(pageBase - kPageAllocationGranularity, + void* map1 = AllocPages(page_base - kPageAllocationGranularity, kPageAllocationGranularity, kPageAllocationGranularity, PageInaccessible); EXPECT_TRUE(map1); - void* map2 = AllocPages(pageBase + kSuperPageSize, kPageAllocationGranularity, - kPageAllocationGranularity, PageInaccessible); + void* map2 = + AllocPages(page_base + kSuperPageSize, kPageAllocationGranularity, + kPageAllocationGranularity, PageInaccessible); EXPECT_TRUE(map2); - for (i = 0; i < numPartitionPagesNeeded; ++i) - secondSuperPagePages[i] = GetFullPage(kTestAllocSize); + for (i = 0; i < num_partition_pages_needed; ++i) + second_super_page_pages[i] = GetFullPage(kTestAllocSize); FreePages(map1, kPageAllocationGranularity); FreePages(map2, kPageAllocationGranularity); - pageBase = reinterpret_cast<char*>( - PartitionPage::ToPointer(secondSuperPagePages[0])); + page_base = reinterpret_cast<char*>( + PartitionPage::ToPointer(second_super_page_pages[0])); EXPECT_EQ(kPartitionPageSize, - reinterpret_cast<uintptr_t>(pageBase) & kSuperPageOffsetMask); - pageBase -= kPartitionPageSize; + reinterpret_cast<uintptr_t>(page_base) & kSuperPageOffsetMask); + page_base -= kPartitionPageSize; // Map a single system page either side of the mapping for our allocations, // with the goal of tripping up alignment of the next mapping. - map1 = AllocPages(pageBase - kPageAllocationGranularity, + map1 = AllocPages(page_base - kPageAllocationGranularity, kPageAllocationGranularity, kPageAllocationGranularity, PageReadWrite); EXPECT_TRUE(map1); - map2 = AllocPages(pageBase + kSuperPageSize, kPageAllocationGranularity, + map2 = AllocPages(page_base + kSuperPageSize, kPageAllocationGranularity, kPageAllocationGranularity, PageReadWrite); EXPECT_TRUE(map2); EXPECT_TRUE( @@ -1142,32 +1161,32 @@ EXPECT_TRUE( SetSystemPagesAccess(map2, kPageAllocationGranularity, PageInaccessible)); - PartitionPage* pageInThirdSuperPage = GetFullPage(kTestAllocSize); + PartitionPage* page_in_third_super_page = GetFullPage(kTestAllocSize); FreePages(map1, kPageAllocationGranularity); FreePages(map2, kPageAllocationGranularity); EXPECT_EQ(0u, reinterpret_cast<uintptr_t>( - PartitionPage::ToPointer(pageInThirdSuperPage)) & + PartitionPage::ToPointer(page_in_third_super_page)) & kPartitionPageOffsetMask); // And make sure we really did get a page in a new superpage. EXPECT_NE(reinterpret_cast<uintptr_t>( - PartitionPage::ToPointer(firstSuperPagePages[0])) & + PartitionPage::ToPointer(first_super_page_pages[0])) & kSuperPageBaseMask, reinterpret_cast<uintptr_t>( - PartitionPage::ToPointer(pageInThirdSuperPage)) & + PartitionPage::ToPointer(page_in_third_super_page)) & kSuperPageBaseMask); EXPECT_NE(reinterpret_cast<uintptr_t>( - PartitionPage::ToPointer(secondSuperPagePages[0])) & + PartitionPage::ToPointer(second_super_page_pages[0])) & kSuperPageBaseMask, reinterpret_cast<uintptr_t>( - PartitionPage::ToPointer(pageInThirdSuperPage)) & + PartitionPage::ToPointer(page_in_third_super_page)) & kSuperPageBaseMask); - FreeFullPage(pageInThirdSuperPage); - for (i = 0; i < numPartitionPagesNeeded; ++i) { - FreeFullPage(firstSuperPagePages[i]); - FreeFullPage(secondSuperPagePages[i]); + FreeFullPage(page_in_third_super_page); + for (i = 0; i < num_partition_pages_needed; ++i) { + FreeFullPage(first_super_page_pages[i]); + FreeFullPage(second_super_page_pages[i]); } } @@ -1315,23 +1334,41 @@ // process, so they won't pollute other tests. TEST_F(PartitionAllocDeathTest, RepeatedAllocReturnNullDirect) { // A direct-mapped allocation size. - EXPECT_DEATH(DoReturnNullTest(32 * 1024 * 1024, false), "DoReturnNullTest"); + EXPECT_DEATH(DoReturnNullTest(32 * 1024 * 1024, kPartitionAllocGenericFlags), + "DoReturnNullTest"); } // Repeating above test with Realloc TEST_F(PartitionAllocDeathTest, RepeatedReallocReturnNullDirect) { - EXPECT_DEATH(DoReturnNullTest(32 * 1024 * 1024, true), "DoReturnNullTest"); + EXPECT_DEATH( + DoReturnNullTest(32 * 1024 * 1024, kPartitionReallocGenericFlags), + "DoReturnNullTest"); +} + +// Repeating above test with TryRealloc +TEST_F(PartitionAllocDeathTest, RepeatedTryReallocReturnNullDirect) { + EXPECT_DEATH( + DoReturnNullTest(32 * 1024 * 1024, kPartitionRootGenericTryRealloc), + "DoReturnNullTest"); } // Test "return null" with a 512 kB block size. TEST_F(PartitionAllocDeathTest, RepeatedAllocReturnNull) { // A single-slot but non-direct-mapped allocation size. - EXPECT_DEATH(DoReturnNullTest(512 * 1024, false), "DoReturnNullTest"); + EXPECT_DEATH(DoReturnNullTest(512 * 1024, kPartitionAllocGenericFlags), + "DoReturnNullTest"); } // Repeating above test with Realloc. TEST_F(PartitionAllocDeathTest, RepeatedReallocReturnNull) { - EXPECT_DEATH(DoReturnNullTest(512 * 1024, true), "DoReturnNullTest"); + EXPECT_DEATH(DoReturnNullTest(512 * 1024, kPartitionReallocGenericFlags), + "DoReturnNullTest"); +} + +// Repeating above test with TryRealloc. +TEST_F(PartitionAllocDeathTest, RepeatedTryReallocReturnNull) { + EXPECT_DEATH(DoReturnNullTest(512 * 1024, kPartitionRootGenericTryRealloc), + "DoReturnNullTest"); } #endif // !defined(ARCH_CPU_64_BITS) || (defined(OS_POSIX) && @@ -1398,10 +1435,10 @@ void* ptr = generic_allocator.root()->Alloc(size, type_name); EXPECT_TRUE(ptr); - char* charPtr = reinterpret_cast<char*>(ptr) - kPointerOffset; + char* char_ptr = reinterpret_cast<char*>(ptr) - kPointerOffset; - EXPECT_DEATH(*(charPtr - 1) = 'A', ""); - EXPECT_DEATH(*(charPtr + size + kExtraAllocSize) = 'A', ""); + EXPECT_DEATH(*(char_ptr - 1) = 'A', ""); + EXPECT_DEATH(*(char_ptr + size + kExtraAllocSize) = 'A', ""); generic_allocator.root()->Free(ptr); } @@ -1428,10 +1465,10 @@ TEST_F(PartitionAllocTest, DumpMemoryStats) { { void* ptr = allocator.root()->Alloc(kTestAllocSize, type_name); - MockPartitionStatsDumper mockStatsDumper; + MockPartitionStatsDumper mock_stats_dumper; allocator.root()->DumpStats("mock_allocator", false /* detailed dump */, - &mockStatsDumper); - EXPECT_TRUE(mockStatsDumper.IsMemoryAllocationRecorded()); + &mock_stats_dumper); + EXPECT_TRUE(mock_stats_dumper.IsMemoryAllocationRecorded()); PartitionFree(ptr); } @@ -1720,13 +1757,13 @@ // state of the free cache ring. generic_allocator.root()->PurgeMemory(PartitionPurgeDecommitEmptyPages); - char* bigPtr = reinterpret_cast<char*>( + char* big_ptr = reinterpret_cast<char*>( generic_allocator.root()->Alloc(256 * 1024, type_name)); - generic_allocator.root()->Free(bigPtr); + generic_allocator.root()->Free(big_ptr); generic_allocator.root()->PurgeMemory(PartitionPurgeDecommitEmptyPages); CHECK_PAGE_IN_CORE(ptr - kPointerOffset, false); - CHECK_PAGE_IN_CORE(bigPtr - kPointerOffset, false); + CHECK_PAGE_IN_CORE(big_ptr - kPointerOffset, false); } // Tests that we prefer to allocate into a non-empty partition page over an
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc index fcea5232..01d5b42f 100644 --- a/base/allocator/partition_allocator/partition_bucket.cc +++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -38,7 +38,7 @@ map_size &= kPageAllocationGranularityBaseMask; // TODO: these pages will be zero-filled. Consider internalizing an - // allocZeroed() API so we can avoid a memset() entirely in this case. + // AllocZeroed() API so we can avoid a memset() entirely in this case. char* ptr = reinterpret_cast<char*>( AllocPages(nullptr, map_size, kSuperPageSize, PageReadWrite)); if (UNLIKELY(!ptr)) @@ -217,9 +217,9 @@ // address region as much as possible. This is important for not causing // page table bloat and not fragmenting address spaces in 32 bit // architectures. - char* requestedAddress = root->next_super_page; + char* requested_address = root->next_super_page; char* super_page = reinterpret_cast<char*>(AllocPages( - requestedAddress, kSuperPageSize, kSuperPageSize, PageReadWrite)); + requested_address, kSuperPageSize, kSuperPageSize, PageReadWrite)); if (UNLIKELY(!super_page)) return nullptr; @@ -262,7 +262,7 @@ // distributions will allocate the mapping directly before the last // successful mapping, which is far from random. So we just get fresh // randomness for the next mapping attempt. - if (requestedAddress && requestedAddress != super_page) + if (requested_address && requested_address != super_page) root->next_super_page = nullptr; // We allocated a new super page so update super page metadata. @@ -281,8 +281,8 @@ latest_extent->next = nullptr; PartitionSuperPageExtentEntry* current_extent = root->current_extent; - bool isNewExtent = (super_page != requestedAddress); - if (UNLIKELY(isNewExtent)) { + bool is_new_extent = (super_page != requested_address); + if (UNLIKELY(is_new_extent)) { if (UNLIKELY(!current_extent)) { DCHECK(!root->first_extent); root->first_extent = latest_extent; @@ -512,9 +512,9 @@ } else { // Third. If we get here, we need a brand new page. uint16_t num_partition_pages = this->get_pages_per_slot_span(); - void* rawPages = AllocNewSlotSpan(root, flags, num_partition_pages); - if (LIKELY(rawPages != nullptr)) { - new_page = PartitionPage::FromPointerNoAlignmentCheck(rawPages); + void* raw_pages = AllocNewSlotSpan(root, flags, num_partition_pages); + if (LIKELY(raw_pages != nullptr)) { + new_page = PartitionPage::FromPointerNoAlignmentCheck(raw_pages); InitializeSlotSpan(new_page); } }
diff --git a/base/android/proguard/proguard.gni b/base/android/proguard/proguard.gni new file mode 100644 index 0000000..1e78bc0 --- /dev/null +++ b/base/android/proguard/proguard.gni
@@ -0,0 +1,9 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +declare_args() { + # Controls whether proguard obfuscation is enabled for targets + # configured to use it. + enable_proguard_obfuscation = true +}
diff --git a/base/logging.cc b/base/logging.cc index 8eabda0e..7752cce 100644 --- a/base/logging.cc +++ b/base/logging.cc
@@ -852,7 +852,11 @@ } #endif // Crash the process to generate a dump. +#if defined(OFFICIAL_BUILD) && defined(NDEBUG) + IMMEDIATE_CRASH(); +#else base::debug::BreakDebugger(); +#endif } } }
diff --git a/base/message_loop/incoming_task_queue.cc b/base/message_loop/incoming_task_queue.cc index 6821730f..c05c38f 100644 --- a/base/message_loop/incoming_task_queue.cc +++ b/base/message_loop/incoming_task_queue.cc
@@ -72,9 +72,6 @@ } #endif - if (!delay.is_zero()) - UMA_HISTOGRAM_LONG_TIMES("MessageLoop.DelayedTaskQueue.PostedDelay", delay); - return PostPendingTask(&pending_task); } @@ -85,7 +82,7 @@ void IncomingTaskQueue::ReportMetricsOnIdle() const { UMA_HISTOGRAM_COUNTS_1M( - "MessageLoop.DelayedTaskQueue.PendingTasksCountOnIdle", + "MessageLoop.DelayedTaskQueueForUI.PendingTasksCountOnIdle", delayed_tasks_.Size()); }
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index 1b76cbb3..3723960a 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc
@@ -15,7 +15,6 @@ #include "base/message_loop/message_pump_default.h" #include "base/message_loop/message_pump_for_io.h" #include "base/message_loop/message_pump_for_ui.h" -#include "base/metrics/histogram_macros.h" #include "base/run_loop.h" #include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/threading/thread_id_name_manager.h" @@ -36,37 +35,6 @@ return pump; } -enum class ScheduledWakeupResult { - // The MessageLoop went to sleep with a timeout and woke up because of that - // timeout. - kCompleted, - // The MessageLoop went to sleep with a timeout but was woken up before it - // fired. - kInterrupted, -}; - -// Reports a ScheduledWakeup's result when waking up from a non-infinite sleep. -// Reports are using a 14 day spread (maximum examined delay for -// https://crbug.com/850450#c3), with 50 buckets that still yields 7 buckets -// under 16ms and hence plenty of resolution. -void ReportScheduledWakeupResult(ScheduledWakeupResult result, - TimeDelta intended_sleep) { - switch (result) { - case ScheduledWakeupResult::kCompleted: - UMA_HISTOGRAM_CUSTOM_TIMES("MessageLoop.ScheduledSleep.Completed", - intended_sleep, - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromDays(14), 50); - break; - case ScheduledWakeupResult::kInterrupted: - UMA_HISTOGRAM_CUSTOM_TIMES("MessageLoop.ScheduledSleep.Interrupted", - intended_sleep, - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromDays(14), 50); - break; - } -} - } // namespace class MessageLoop::Controller : public internal::IncomingTaskQueue::Observer { @@ -496,20 +464,6 @@ // Execute oldest task. while (incoming_task_queue_->triage_tasks().HasTasks()) { - if (!scheduled_wakeup_.next_run_time.is_null()) { - // While the frontmost task may racily be ripe. The MessageLoop was awaken - // without needing the timeout anyways. Since this metric is about - // determining whether sleeping for long periods ever succeeds: it's - // easier to just consider any untriaged task as an interrupt (this also - // makes the logic simpler for untriaged delayed tasks which may alter the - // top of the task queue prior to DoDelayedWork() but did cause a wakeup - // regardless -- per currently requiring this immediate triage step even - // for long delays). - ReportScheduledWakeupResult(ScheduledWakeupResult::kInterrupted, - scheduled_wakeup_.intended_sleep); - scheduled_wakeup_ = ScheduledWakeup(); - } - PendingTask pending_task = incoming_task_queue_->triage_tasks().Pop(); if (pending_task.task.IsCancelled()) continue; @@ -533,27 +487,9 @@ } bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { - if (!task_execution_allowed_) { + if (!task_execution_allowed_ || + !incoming_task_queue_->delayed_tasks().HasTasks()) { *next_delayed_work_time = TimeTicks(); - // |scheduled_wakeup_| isn't used in nested loops that don't process - // application tasks. - DCHECK(scheduled_wakeup_.next_run_time.is_null()); - return false; - } - - if (!incoming_task_queue_->delayed_tasks().HasTasks()) { - *next_delayed_work_time = TimeTicks(); - - // It's possible to be woken up by a system event and have it cancel the - // upcoming delayed task from under us before DoDelayedWork() -- see comment - // under |next_run_time > recent_time_|. This condition covers the special - // case where such a system event cancelled *all* pending delayed tasks. - if (!scheduled_wakeup_.next_run_time.is_null()) { - ReportScheduledWakeupResult(ScheduledWakeupResult::kInterrupted, - scheduled_wakeup_.intended_sleep); - scheduled_wakeup_ = ScheduledWakeup(); - } - return false; } @@ -571,36 +507,10 @@ recent_time_ = TimeTicks::Now(); // Get a better view of Now(); if (next_run_time > recent_time_) { *next_delayed_work_time = CapAtOneDay(next_run_time); - - // If the loop was woken up early by an untriaged task: - // |scheduled_wakeup_| will have been handled already in DoWork(). If it - // wasn't, it means the early wake up was caused by a system event (e.g. - // MessageLoopForUI or IO). - if (!scheduled_wakeup_.next_run_time.is_null()) { - // Handling the system event may have resulted in cancelling the - // upcoming delayed task (and then it being pruned by - // DelayedTaskQueue::HasTasks()); hence, we cannot check for strict - // equality here. We can however check that the pending task is either - // still there or that a later delay replaced it in front of the queue. - // There shouldn't have been new tasks added in |delayed_tasks()| per - // DoWork() not having triaged new tasks since the last DoIdleWork(). - DCHECK_GE(next_run_time, scheduled_wakeup_.next_run_time); - - ReportScheduledWakeupResult(ScheduledWakeupResult::kInterrupted, - scheduled_wakeup_.intended_sleep); - scheduled_wakeup_ = ScheduledWakeup(); - } - return false; } } - if (next_run_time == scheduled_wakeup_.next_run_time) { - ReportScheduledWakeupResult(ScheduledWakeupResult::kCompleted, - scheduled_wakeup_.intended_sleep); - scheduled_wakeup_ = ScheduledWakeup(); - } - PendingTask pending_task = incoming_task_queue_->delayed_tasks().Pop(); if (incoming_task_queue_->delayed_tasks().HasTasks()) { @@ -619,43 +529,19 @@ bool need_high_res_timers = false; #endif - // Do not report idle metrics nor do any logic related to delayed tasks if - // about to quit the loop and/or in a nested loop where - // |!task_execution_allowed_|. In the former case, the loop isn't going to - // sleep and in the latter case DoDelayedWork() will not actually do the work - // this is prepping for. + // Do not report idle metrics if about to quit the loop and/or in a nested + // loop where |!task_execution_allowed_|. In the former case, the loop isn't + // going to sleep and in the latter case DoDelayedWork() will not actually do + // the work this is prepping for. if (ShouldQuitWhenIdle()) { pump_->Quit(); } else if (task_execution_allowed_) { - incoming_task_queue_->ReportMetricsOnIdle(); - - if (incoming_task_queue_->delayed_tasks().HasTasks()) { - TimeTicks scheduled_wakeup_time = - incoming_task_queue_->delayed_tasks().Peek().delayed_run_time; - - if (!scheduled_wakeup_.next_run_time.is_null()) { - // It's possible for DoIdleWork() to be invoked twice in a row (e.g. if - // the MessagePump processed system work and became idle twice in a row - // without application tasks in between -- some pumps with a native - // message loop do not invoke DoWork() / DoDelayedWork() when awaken for - // system work only). As in DoDelayedWork(), we cannot check for strict - // equality below as the system work may have cancelled the frontmost - // task. - DCHECK_GE(scheduled_wakeup_time, scheduled_wakeup_.next_run_time); - - ReportScheduledWakeupResult(ScheduledWakeupResult::kInterrupted, - scheduled_wakeup_.intended_sleep); - scheduled_wakeup_ = ScheduledWakeup(); - } - - // Store the remaining delay as well as the programmed wakeup time in - // order to know next time this MessageLoop wakes up whether it woke up - // because of this pending task (is it still the frontmost task in the - // queue?) and be able to report the slept delta (which is lost if not - // saved here). - scheduled_wakeup_ = ScheduledWakeup{ - scheduled_wakeup_time, scheduled_wakeup_time - TimeTicks::Now()}; - } + // Only track idle metrics in MessageLoopForUI to avoid too much contention + // logging the histogram (https://crbug.com/860801) -- there's typically + // only one UI thread per process and, for practical purposes, restricting + // the MessageLoop diagnostic metrics to it yields similar information. + if (type_ == TYPE_UI) + incoming_task_queue_->ReportMetricsOnIdle(); #if defined(OS_WIN) // On Windows we activate the high resolution timer so that the wait
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h index ab49d87..7c31a12 100644 --- a/base/message_loop/message_loop.h +++ b/base/message_loop/message_loop.h
@@ -287,15 +287,6 @@ // A recent snapshot of Time::Now(), used to check delayed_work_queue_. TimeTicks recent_time_; - // Non-null when the last thing this MessageLoop did is become idle with - // pending delayed tasks. Used to report metrics on the following wake up. - struct ScheduledWakeup { - // The scheduled time of the next delayed task when this loop became idle. - TimeTicks next_run_time; - // The delta until |next_run_time| when this loop became idle. - TimeDelta intended_sleep; - } scheduled_wakeup_; - ObserverList<DestructionObserver> destruction_observers_; // A boolean which prevents unintentional reentrant task execution (e.g. from
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc index 1a21fc5..f0b07d4 100644 --- a/base/message_loop/message_loop_unittest.cc +++ b/base/message_loop/message_loop_unittest.cc
@@ -23,7 +23,9 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/task_scheduler/task_scheduler.h" +#include "base/test/bind_test_util.h" #include "base/test/gtest_util.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/test_simple_task_runner.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" @@ -1758,6 +1760,63 @@ run_loop.Run(); } +#if defined(OS_MACOSX) +// This metric is a bit broken on Mac OS because CFRunLoop doesn't +// deterministically invoke MessageLoop::DoIdleWork(). This being a temporary +// diagnosis metric, we let this fly and simply not test it on Mac. +#define MAYBE_MetricsOnlyFromUILoops DISABLED_MetricsOnlyFromUILoops +#else +#define MAYBE_MetricsOnlyFromUILoops MetricsOnlyFromUILoops +#endif + +TEST_P(MessageLoopTypedTest, MAYBE_MetricsOnlyFromUILoops) { + MessageLoop loop(GetMessageLoopType()); + + const bool histograms_expected = GetMessageLoopType() == MessageLoop::TYPE_UI; + + HistogramTester histogram_tester; + + // A delay which is expected to give enough time for the MessageLoop to go + // idle after triaging it. + TimeDelta delay_that_leads_to_idle = TimeDelta::FromMilliseconds(1); + + // On some platforms testing under emulation, 1 ms is not enough. See how long + // it takes to resolve a 1ms delayed task and use 10X that for the real test. + { + TimeTicks begin_run_loop = TimeTicks::Now(); + + RunLoop run_loop; + loop.task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), + delay_that_leads_to_idle); + run_loop.Run(); + + delay_that_leads_to_idle = 10 * (TimeTicks::Now() - begin_run_loop); + } + + SCOPED_TRACE(delay_that_leads_to_idle); + + // Loop that goes idle with one pending task. + RunLoop run_loop; + loop.task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), + delay_that_leads_to_idle); + run_loop.Run(); + + const std::vector<Bucket> buckets = histogram_tester.GetAllSamples( + "MessageLoop.DelayedTaskQueueForUI.PendingTasksCountOnIdle"); + if (histograms_expected) { + // DoIdleWork() should have triggered at least once in the second RunLoop. + // It may also have triggered in the first one if the test environment is + // fast enough. It can sometimes also trigger additional times when a system + // message (e.g. system ping) interrupts the sleep. All cases should + // nonetheless report in the "1" bucket. + EXPECT_EQ(buckets.size(), 1U); + EXPECT_EQ(buckets[0].min, 1); + EXPECT_GE(buckets[0].count, 1); + } else { + EXPECT_TRUE(buckets.empty()); + } +} + INSTANTIATE_TEST_CASE_P( , MessageLoopTypedTest,
diff --git a/base/process/process_linux.cc b/base/process/process_linux.cc index faf39af..5f07012 100644 --- a/base/process/process_linux.cc +++ b/base/process/process_linux.cc
@@ -5,6 +5,7 @@ #include "base/process/process.h" #include <errno.h> +#include <limits.h> #include <sys/resource.h> #include "base/files/file_util.h" @@ -74,12 +75,25 @@ const int kBackgroundPriority = 5; #endif // defined(OS_CHROMEOS) +// NZERO should be defined in <limits.h> per POSIX, and should be at least +// 20. (NZERO-1) is the highest possible niceness value (i.e. lowest process +// priority). Most platforms use NZERO=20. +// +// RLIMIT_NICE tells us how much we can reduce niceness (increase priority) if +// we start at NZERO. +// +// e.g. if NZERO is 20 and the rlimit is 30, we can lower niceness anywhere +// within the [-10, 19] range (20 - 30 = -10). +// +// So, to re-raise priority to kForegroundPriority, we need at least this much: +constexpr int kMinNiceRLimitForReraising = NZERO - kForegroundPriority; + bool CanReraisePriority() { // We won't be able to raise the priority if we don't have the right rlimit. // The limit may be adjusted in /etc/security/limits.conf for PAM systems. struct rlimit rlim; return (getrlimit(RLIMIT_NICE, &rlim) == 0) && - (20 - kForegroundPriority) <= static_cast<int>(rlim.rlim_cur); + static_cast<int>(rlim.rlim_cur) >= kMinNiceRLimitForReraising; } } // namespace
diff --git a/base/task_scheduler/service_thread.cc b/base/task_scheduler/service_thread.cc index 12cd3282..7e7731f 100644 --- a/base/task_scheduler/service_thread.cc +++ b/base/task_scheduler/service_thread.cc
@@ -13,7 +13,6 @@ #include "base/task_scheduler/task_scheduler.h" #include "base/task_scheduler/task_tracker.h" #include "base/task_scheduler/task_traits.h" -#include "build/build_config.h" namespace base { namespace internal { @@ -37,9 +36,6 @@ // environment, do not perform the heartbeat report in that case since it // relies on such an environment. if (task_tracker_ && TaskScheduler::GetInstance()) { -// Seemingly causing power regression on Android, disable to see if truly at -// fault : https://crbug.com/848255 -#if !defined(OS_ANDROID) // Compute the histogram every hour (with a slight offset to drift if that // hour tick happens to line up with specific events). Once per hour per // user was deemed sufficient to gather a reliable metric. @@ -51,7 +47,6 @@ : g_heartbeat_for_testing, BindRepeating(&ServiceThread::PerformHeartbeatLatencyReport, Unretained(this))); -#endif } }
diff --git a/base/task_scheduler/service_thread_unittest.cc b/base/task_scheduler/service_thread_unittest.cc index 3c42762..0214a72 100644 --- a/base/task_scheduler/service_thread_unittest.cc +++ b/base/task_scheduler/service_thread_unittest.cc
@@ -52,18 +52,10 @@ service_thread.FlushForTesting(); } -#if defined(OS_ANDROID) -// The heartbeat latency report has been temporarily disabled on Android per -// https://crbug.com/848255. -#define MAYBE_HeartbeatLatencyReport DISABLED_HeartbeatLatencyReport -#else -#define MAYBE_HeartbeatLatencyReport HeartbeatLatencyReport -#endif - // Integration test verifying that a service thread running in a fully // integrated TaskScheduler environment results in reporting // HeartbeatLatencyMicroseconds metrics. -TEST(TaskSchedulerServiceThreadIntegrationTest, MAYBE_HeartbeatLatencyReport) { +TEST(TaskSchedulerServiceThreadIntegrationTest, HeartbeatLatencyReport) { ServiceThread::SetHeartbeatIntervalForTesting(TimeDelta::FromMilliseconds(1)); TaskScheduler::SetInstance(
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py index 65d37d1..9617b51 100644 --- a/build/android/PRESUBMIT.py +++ b/build/android/PRESUBMIT.py
@@ -74,6 +74,7 @@ J('pylib', 'results', 'json_results_test.py'), J('pylib', 'symbols', 'apk_native_libs_unittest.py'), J('pylib', 'symbols', 'elf_symbolizer_unittest.py'), + J('pylib', 'symbols', 'symbol_utils_unittest.py'), J('pylib', 'utils', 'decorators_test.py'), J('pylib', 'utils', 'device_dependencies_test.py'), J('pylib', 'utils', 'dexdump_test.py'),
diff --git a/build/android/asan_symbolize.py b/build/android/asan_symbolize.py index 19d71ca..9f2e88a 100755 --- a/build/android/asan_symbolize.py +++ b/build/android/asan_symbolize.py
@@ -14,6 +14,7 @@ from pylib import constants from pylib.constants import host_paths +# pylint: disable=wrong-import-order # Uses symbol.py from third_party/android_platform, not python's. with host_paths.SysPath( host_paths.ANDROID_PLATFORM_DEVELOPMENT_SCRIPTS_PATH,
diff --git a/build/android/devil_chromium.py b/build/android/devil_chromium.py index af2141a..2ae64367 100644 --- a/build/android/devil_chromium.py +++ b/build/android/devil_chromium.py
@@ -167,4 +167,3 @@ devil_env.config.Initialize( configs=[devil_dynamic_config], config_files=[_DEVIL_CONFIG]) -
diff --git a/build/android/gyp/generate_resource_rewriter.py b/build/android/gyp/generate_resource_rewriter.py index 82ddc21..ba635a29 100755 --- a/build/android/gyp/generate_resource_rewriter.py +++ b/build/android/gyp/generate_resource_rewriter.py
@@ -107,4 +107,3 @@ if __name__ == '__main__': sys.exit(main()) -
diff --git a/build/android/gyp/java_google_api_keys.py b/build/android/gyp/java_google_api_keys.py index f57e0b3..349821a8 100755 --- a/build/android/gyp/java_google_api_keys.py +++ b/build/android/gyp/java_google_api_keys.py
@@ -121,4 +121,3 @@ if __name__ == '__main__': _DoMain(sys.argv[1:]) -
diff --git a/build/android/gyp/main_dex_list.py b/build/android/gyp/main_dex_list.py index 9ccfea0..2435859 100755 --- a/build/android/gyp/main_dex_list.py +++ b/build/android/gyp/main_dex_list.py
@@ -172,4 +172,3 @@ if __name__ == '__main__': sys.exit(main(sys.argv[1:])) -
diff --git a/build/android/gyp/util/__init__.py b/build/android/gyp/util/__init__.py index 727e987e..96196cff 100644 --- a/build/android/gyp/util/__init__.py +++ b/build/android/gyp/util/__init__.py
@@ -1,4 +1,3 @@ # Copyright (c) 2012 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. -
diff --git a/build/android/gyp/write_ordered_libraries.py b/build/android/gyp/write_ordered_libraries.py index e3d87c1..3b9a3374 100755 --- a/build/android/gyp/write_ordered_libraries.py +++ b/build/android/gyp/write_ordered_libraries.py
@@ -114,5 +114,3 @@ if __name__ == '__main__': sys.exit(main()) - -
diff --git a/build/android/incremental_install/__init__.py b/build/android/incremental_install/__init__.py index 1aaf0e1..50b23df 100644 --- a/build/android/incremental_install/__init__.py +++ b/build/android/incremental_install/__init__.py
@@ -1,4 +1,3 @@ # 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. -
diff --git a/build/android/lighttpd_server.py b/build/android/lighttpd_server.py index 89a828a..c77d740 100755 --- a/build/android/lighttpd_server.py +++ b/build/android/lighttpd_server.py
@@ -104,7 +104,7 @@ break self.process.close() - if self.fixed_port or not 'in use' in server_error: + if self.fixed_port or 'in use' not in server_error: print 'Client error:', client_error print 'Server error:', server_error return False
diff --git a/build/android/method_count.py b/build/android/method_count.py index 68823e1..490887a 100755 --- a/build/android/method_count.py +++ b/build/android/method_count.py
@@ -114,4 +114,3 @@ if __name__ == '__main__': sys.exit(main()) -
diff --git a/build/android/pylib/android/__init__.py b/build/android/pylib/android/__init__.py index 7a90b53..a67c3501 100644 --- a/build/android/pylib/android/__init__.py +++ b/build/android/pylib/android/__init__.py
@@ -1,4 +1,3 @@ # Copyright (c) 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. -
diff --git a/build/android/pylib/base/__init__.py b/build/android/pylib/base/__init__.py index 727e987e..96196cff 100644 --- a/build/android/pylib/base/__init__.py +++ b/build/android/pylib/base/__init__.py
@@ -1,4 +1,3 @@ # Copyright (c) 2012 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. -
diff --git a/build/android/pylib/base/base_test_result.py b/build/android/pylib/base/base_test_result.py index af9f68f8..a553532 100644 --- a/build/android/pylib/base/base_test_result.py +++ b/build/android/pylib/base/base_test_result.py
@@ -260,4 +260,3 @@ def DidRunPass(self): """Return whether the test run was successful.""" return not self.GetNotPass() - self.GetSkip() -
diff --git a/build/android/pylib/base/test_exception.py b/build/android/pylib/base/test_exception.py index f00f0d0e..c98d2cb 100644 --- a/build/android/pylib/base/test_exception.py +++ b/build/android/pylib/base/test_exception.py
@@ -6,4 +6,3 @@ class TestException(Exception): """Base class for exceptions thrown by the test runner.""" pass -
diff --git a/build/android/pylib/base/test_instance.py b/build/android/pylib/base/test_instance.py index cdf678f2..f0ff830 100644 --- a/build/android/pylib/base/test_instance.py +++ b/build/android/pylib/base/test_instance.py
@@ -32,4 +32,3 @@ def __exit__(self, _exc_type, _exc_val, _exc_tb): self.TearDown() -
diff --git a/build/android/pylib/base/test_run.py b/build/android/pylib/base/test_run.py index 9b16f89..59e595d 100644 --- a/build/android/pylib/base/test_run.py +++ b/build/android/pylib/base/test_run.py
@@ -41,4 +41,3 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.TearDown() -
diff --git a/build/android/pylib/base/test_run_factory.py b/build/android/pylib/base/test_run_factory.py index 1a28728..1f63a059 100644 --- a/build/android/pylib/base/test_run_factory.py +++ b/build/android/pylib/base/test_run_factory.py
@@ -54,4 +54,3 @@ error_func('Unable to create test run for %s tests in %s environment' % (str(test_instance), str(env))) -
diff --git a/build/android/pylib/base/test_server.py b/build/android/pylib/base/test_server.py index 085a51e9..763e1212 100644 --- a/build/android/pylib/base/test_server.py +++ b/build/android/pylib/base/test_server.py
@@ -16,4 +16,3 @@ def TearDown(self): raise NotImplementedError -
diff --git a/build/android/pylib/gtest/__init__.py b/build/android/pylib/gtest/__init__.py index 727e987e..96196cff 100644 --- a/build/android/pylib/gtest/__init__.py +++ b/build/android/pylib/gtest/__init__.py
@@ -1,4 +1,3 @@ # Copyright (c) 2012 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. -
diff --git a/build/android/pylib/gtest/gtest_test_instance.py b/build/android/pylib/gtest/gtest_test_instance.py index d93edc6..7e0923a 100644 --- a/build/android/pylib/gtest/gtest_test_instance.py +++ b/build/android/pylib/gtest/gtest_test_instance.py
@@ -555,4 +555,3 @@ def TearDown(self): """Do nothing.""" pass -
diff --git a/build/android/pylib/gtest/gtest_test_instance_test.py b/build/android/pylib/gtest/gtest_test_instance_test.py index 3466924..a34ab84 100755 --- a/build/android/pylib/gtest/gtest_test_instance_test.py +++ b/build/android/pylib/gtest/gtest_test_instance_test.py
@@ -260,4 +260,3 @@ if __name__ == '__main__': unittest.main(verbosity=2) -
diff --git a/build/android/pylib/instrumentation/__init__.py b/build/android/pylib/instrumentation/__init__.py index 727e987e..96196cff 100644 --- a/build/android/pylib/instrumentation/__init__.py +++ b/build/android/pylib/instrumentation/__init__.py
@@ -1,4 +1,3 @@ # Copyright (c) 2012 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. -
diff --git a/build/android/pylib/junit/__init__.py b/build/android/pylib/junit/__init__.py index 5cac0261..4d6aabb9 100644 --- a/build/android/pylib/junit/__init__.py +++ b/build/android/pylib/junit/__init__.py
@@ -1,4 +1,3 @@ # 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. -
diff --git a/build/android/pylib/linker/__init__.py b/build/android/pylib/linker/__init__.py index af99437..9228df89 100644 --- a/build/android/pylib/linker/__init__.py +++ b/build/android/pylib/linker/__init__.py
@@ -1,4 +1,3 @@ # Copyright 2013 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. -
diff --git a/build/android/pylib/linker/linker_test_instance.py b/build/android/pylib/linker/linker_test_instance.py index 1de3e17..6ace7a36 100644 --- a/build/android/pylib/linker/linker_test_instance.py +++ b/build/android/pylib/linker/linker_test_instance.py
@@ -48,4 +48,3 @@ def TestType(self): return 'linker' -
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py index 21e9fe85..4734883 100644 --- a/build/android/pylib/local/device/local_device_gtest_run.py +++ b/build/android/pylib/local/device/local_device_gtest_run.py
@@ -152,6 +152,7 @@ extras[gtest_test_instance.EXTRA_SHARD_NANO_TIMEOUT] = int( kwargs['timeout'] * _SECONDS_TO_NANOS) + # pylint: disable=redefined-variable-type command_line_file = _NullContextManager() if flags: if len(flags) > _MAX_INLINE_FLAGS_LENGTH: @@ -169,6 +170,7 @@ extras[_EXTRA_TEST_LIST] = test_list_file.name else: extras[_EXTRA_TEST] = test[0] + # pylint: enable=redefined-variable-type stdout_file = device_temp_file.DeviceTempFile( device.adb, dir=device.GetExternalStoragePath(), suffix='.gtest_out') @@ -283,11 +285,13 @@ assert isinstance(test_instance, gtest_test_instance.GtestTestInstance) super(LocalDeviceGtestRun, self).__init__(env, test_instance) + # pylint: disable=redefined-variable-type if self._test_instance.apk: self._delegate = _ApkDelegate(self._test_instance, env.tool) elif self._test_instance.exe_dist_dir: self._delegate = _ExeDelegate(self, self._test_instance.exe_dist_dir, self._env.tool) + # pylint: enable=redefined-variable-type self._crashes = set() self._servers = collections.defaultdict(list)
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py index 40b857d..de7ed93 100644 --- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py +++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -153,7 +153,11 @@ self._replace_package_contextmanager = system_app.ReplaceSystemApp( dev, self._test_instance.replace_system_package.package, self._test_instance.replace_system_package.replacement_apk) + # Pylint is not smart enough to realize that this field has + # an __enter__ method, and will complain loudly. + # pylint: disable=no-member self._replace_package_contextmanager.__enter__() + # pylint: enable=no-member steps.append(replace_package) @@ -308,12 +312,15 @@ valgrind_tools.SetChromeTimeoutScale(dev, None) if self._replace_package_contextmanager: + # See pylint-related commend above with __enter__() + # pylint: disable=no-member self._replace_package_contextmanager.__exit__(*sys.exc_info()) + # pylint: enable=no-member self._env.parallel_devices.pMap(individual_device_tear_down) def _CreateFlagChangerIfNeeded(self, device): - if not str(device) in self._flag_changers: + if str(device) not in self._flag_changers: self._flag_changers[str(device)] = flag_changer.FlagChanger( device, "test-cmdline-file")
diff --git a/build/android/pylib/local/device/local_device_test_run.py b/build/android/pylib/local/device/local_device_test_run.py index 90e6b67..00d715b 100644 --- a/build/android/pylib/local/device/local_device_test_run.py +++ b/build/android/pylib/local/device/local_device_test_run.py
@@ -220,7 +220,7 @@ if hash(self._GetUniqueTestName(t)) % total_shards == shard_index] def GetTool(self, device): - if not str(device) in self._tools: + if str(device) not in self._tools: self._tools[str(device)] = valgrind_tools.CreateTool( self._env.tool, device) return self._tools[str(device)]
diff --git a/build/android/pylib/local/local_test_server_spawner.py b/build/android/pylib/local/local_test_server_spawner.py index 8e416fac..6cd282e 100644 --- a/build/android/pylib/local/local_test_server_spawner.py +++ b/build/android/pylib/local/local_test_server_spawner.py
@@ -98,4 +98,3 @@ self.Reset() self._spawning_server.Stop() forwarder.Forwarder.UnmapDevicePort(self.port, self._device) -
diff --git a/build/android/pylib/results/flakiness_dashboard/json_results_generator.py b/build/android/pylib/results/flakiness_dashboard/json_results_generator.py index 9693977..5e5f83f 100644 --- a/build/android/pylib/results/flakiness_dashboard/json_results_generator.py +++ b/build/android/pylib/results/flakiness_dashboard/json_results_generator.py
@@ -380,6 +380,7 @@ urllib2.quote(self._test_type), urllib2.quote(self._master_name))) + # pylint: disable=redefined-variable-type try: # FIXME: We should talk to the network via a Host object. results_file = urllib2.urlopen(results_file_url) @@ -391,6 +392,7 @@ error = http_error except urllib2.URLError, url_error: error = url_error + # pylint: enable=redefined-variable-type if old_results: # Strip the prefix and suffix so we can get the actual JSON object.
diff --git a/build/android/pylib/results/json_results.py b/build/android/pylib/results/json_results.py index 1243691..3f87b46 100644 --- a/build/android/pylib/results/json_results.py +++ b/build/android/pylib/results/json_results.py
@@ -175,4 +175,3 @@ duration=tr['elapsed_time_ms']) for tr in test_runs]) return results_list -
diff --git a/build/android/pylib/results/json_results_test.py b/build/android/pylib/results/json_results_test.py index 27617135..e8b983b5 100755 --- a/build/android/pylib/results/json_results_test.py +++ b/build/android/pylib/results/json_results_test.py
@@ -178,4 +178,3 @@ if __name__ == '__main__': unittest.main(verbosity=2) -
diff --git a/build/android/pylib/results/presentation/test_results_presentation.py b/build/android/pylib/results/presentation/test_results_presentation.py index eaae68f85..82d6c88 100755 --- a/build/android/pylib/results/presentation/test_results_presentation.py +++ b/build/android/pylib/results/presentation/test_results_presentation.py
@@ -268,6 +268,7 @@ def feedback_url(result_details_link): + # pylint: disable=redefined-variable-type url_args = [ ('labels', 'Pri-2,Type-Bug,Restrict-View-Google'), ('summary', 'Result Details Feedback:'), @@ -276,6 +277,7 @@ if result_details_link: url_args.append(('comment', 'Please check out: %s' % result_details_link)) url_args = urllib.urlencode(url_args) + # pylint: enable=redefined-variable-type return 'https://bugs.chromium.org/p/chromium/issues/entry?%s' % url_args @@ -370,6 +372,7 @@ # This will be reported as an error by result_details, no need to duplicate. return None ui_screenshots = [] + # pylint: disable=too-many-nested-blocks for testsuite_run in json_object['per_iteration_data']: for _, test_runs in testsuite_run.iteritems(): for test_run in test_runs: @@ -388,6 +391,7 @@ test_screenshots = json.loads( screenshot_string) ui_screenshots.extend(test_screenshots) + # pylint: enable=too-many-nested-blocks if ui_screenshots: return json.dumps(ui_screenshots)
diff --git a/build/android/pylib/symbols/symbol_utils.py b/build/android/pylib/symbols/symbol_utils.py new file mode 100644 index 0000000..e4e3faa --- /dev/null +++ b/build/android/pylib/symbols/symbol_utils.py
@@ -0,0 +1,812 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import bisect +import collections +import logging +import os +import re + +from pylib.constants import host_paths +from pylib.symbols import elf_symbolizer + + +def _AndroidAbiToCpuArch(android_abi): + """Return the Chromium CPU architecture name for a given Android ABI.""" + _ARCH_MAP = { + 'armeabi': 'arm', + 'armeabi-v7a': 'arm', + 'arm64-v8a': 'arm64', + 'x86_64': 'x64', + } + return _ARCH_MAP.get(android_abi, android_abi) + + +def _HexAddressRegexpFor(android_abi): + """Return a regexp matching hexadecimal addresses for a given Android ABI.""" + if android_abi in ['x86_64', 'arm64-v8a', 'mips64']: + width = 16 + else: + width = 8 + return '[0-9a-f]{%d}' % width + + +class HostLibraryFinder(object): + """Translate device library path to matching host unstripped library path. + + Usage is the following: + 1) Create instance. + 2) Call AddSearchDir() once or more times to add host directory path to + look for unstripped native libraries. + 3) Call Find(device_libpath) repeatedly to translate a device-specific + library path into the corresponding host path to the unstripped + version. + """ + def __init__(self): + """Initialize instance.""" + self._search_dirs = [] + self._lib_map = {} # Map of library name to host file paths. + + def AddSearchDir(self, lib_dir): + """Add a directory to the search path for host native shared libraries. + + Args: + lib_dir: host path containing native libraries. + """ + if not os.path.exists(lib_dir): + logging.warning('Ignoring missing host library directory: %s', lib_dir) + return + if not os.path.isdir(lib_dir): + logging.warning('Ignoring invalid host library directory: %s', lib_dir) + return + self._search_dirs.append(lib_dir) + self._lib_map = {} # Reset the map. + + def Find(self, device_libpath): + """Find the host file path matching a specific device library path. + + Args: + device_libpath: device-specific file path to library or executable. + Returns: + host file path to the unstripped version of the library, or None. + """ + host_lib_path = None + lib_name = os.path.basename(device_libpath) + host_lib_path = self._lib_map.get(lib_name) + if not host_lib_path: + for search_dir in self._search_dirs: + lib_path = os.path.join(search_dir, lib_name) + if os.path.exists(lib_path): + host_lib_path = lib_path + break + + if not host_lib_path: + logging.debug('Could not find host library for: %s', lib_name) + self._lib_map[lib_name] = host_lib_path + + return host_lib_path + + + +class SymbolResolver(object): + """A base class for objets that can symbolize library (path, offset) + pairs into symbol information strings. Usage is the following: + + 1) Create new instance (by calling the constructor of a derived + class, since this is only the base one). + + 2) Call SetAndroidAbi() before any call to FindSymbolInfo() in order + to set the Android CPU ABI used for symbolization. + + 3) Before the first call to FindSymbolInfo(), one can call + AddLibraryOffset(), or AddLibraryOffsets() to record a set of offsets + that you will want to symbolize later through FindSymbolInfo(). Doing + so allows some SymbolResolver derived classes to work faster (e.g. the + one that invokes the 'addr2line' program, since the latter works faster + if the offsets provided as inputs are sorted in increasing order). + + 3) Call FindSymbolInfo(path, offset) to return the corresponding + symbol information string, or None if this doesn't correspond + to anything the instance can handle. + + Note that whether the path is specific to the device or to the + host depends on the derived class implementation. + """ + def __init__(self): + self._android_abi = None + self._lib_offsets_map = collections.defaultdict(set) + + def SetAndroidAbi(self, android_abi): + """Set the Android ABI value for this instance. + + Calling this function before FindSymbolInfo() is required by some + derived class implementations. + + Args: + android_abi: Native Android CPU ABI name (e.g. 'armeabi-v7a'). + Raises: + Exception if the ABI was already set with a different value. + """ + if self._android_abi and self._android_abi != android_abi: + raise Exception('Cannot reset Android ABI to new value %s, already set ' + 'to %s' % (android_abi, self._android_abi)) + + self._android_abi = android_abi + + def AddLibraryOffset(self, lib_path, offset): + """Associate a single offset to a given device library. + + This must be called before FindSymbolInfo(), otherwise its input arguments + will be ignored. + + Args: + lib_path: A library path. + offset: An integer offset within the corresponding library that will be + symbolized by future calls to FindSymbolInfo. + """ + self._lib_offsets_map[lib_path].add(offset) + + def AddLibraryOffsets(self, lib_path, lib_offsets): + """Associate a set of wanted offsets to a given device library. + + This must be called before FindSymbolInfo(), otherwise its input arguments + will be ignored. + + Args: + lib_path: A library path. + lib_offsets: An iterable of integer offsets within the corresponding + library that will be symbolized by future calls to FindSymbolInfo. + """ + self._lib_offsets_map[lib_path].update(lib_offsets) + + # pylint: disable=unused-argument,no-self-use + def FindSymbolInfo(self, lib_path, lib_offset): + """Symbolize a device library path and offset. + + Args: + lib_path: Library path (device or host specific, depending on the + derived class implementation). + lib_offset: Integer offset within the library. + Returns: + Corresponding symbol information string, or None. + """ + # The base implementation cannot symbolize anything. + return None + # pylint: enable=unused-argument,no-self-use + + +class ElfSymbolResolver(SymbolResolver): + """A SymbolResolver that can symbolize host path + offset values using + an elf_symbolizer.ELFSymbolizer instance. + """ + def __init__(self, addr2line_path_for_tests=None): + super(ElfSymbolResolver, self).__init__() + self._addr2line_path = addr2line_path_for_tests + + # Used to cache one ELFSymbolizer instance per library path. + self._elf_symbolizer_cache = {} + + # Used to cache FindSymbolInfo() results. Maps host library paths + # to (offset -> symbol info string) dictionaries. + self._symbol_info_cache = collections.defaultdict(dict) + self._allow_symbolizer = True + + def _CreateSymbolizerFor(self, host_path): + """Create the ELFSymbolizer instance associated with a given lib path.""" + addr2line_path = self._addr2line_path + if not addr2line_path: + if not self._android_abi: + raise Exception( + 'Android CPU ABI must be set before calling FindSymbolInfo!') + + cpu_arch = _AndroidAbiToCpuArch(self._android_abi) + self._addr2line_path = host_paths.ToolPath('addr2line', cpu_arch) + + return elf_symbolizer.ELFSymbolizer( + elf_file_path=host_path, addr2line_path=self._addr2line_path, + callback=ElfSymbolResolver._Callback, inlines=True) + + def DisallowSymbolizerForTesting(self): + """Disallow FindSymbolInfo() from using a symbolizer. + + This is used during unit-testing to ensure that the offsets that were + recorded via AddLibraryOffset()/AddLibraryOffsets() are properly + symbolized, but not anything else. + """ + self._allow_symbolizer = False + + def FindSymbolInfo(self, host_path, offset): + """Override SymbolResolver.FindSymbolInfo. + + Args: + host_path: Host-specific path to the native shared library. + offset: Integer offset within the native library. + Returns: + A symbol info string, or None. + """ + offset_map = self._symbol_info_cache[host_path] + symbol_info = offset_map.get(offset) + if symbol_info: + return symbol_info + + # Create symbolizer on demand. + symbolizer = self._elf_symbolizer_cache.get(host_path) + if not symbolizer: + symbolizer = self._CreateSymbolizerFor(host_path) + self._elf_symbolizer_cache[host_path] = symbolizer + + # If there are pre-recorded offsets for this path, symbolize them now. + offsets = self._lib_offsets_map.get(host_path) + if offsets: + offset_map = {} + for pre_offset in offsets: + symbolizer.SymbolizeAsync( + pre_offset, callback_arg=(offset_map, pre_offset)) + symbolizer.WaitForIdle() + self._symbol_info_cache[host_path] = offset_map + + symbol_info = offset_map.get(offset) + if symbol_info: + return symbol_info + + if not self._allow_symbolizer: + return None + + # Symbolize single offset. Slower if addresses are not provided in + # increasing order to addr2line. + symbolizer.SymbolizeAsync(offset, + callback_arg=(offset_map, offset)) + symbolizer.WaitForIdle() + return offset_map.get(offset) + + @staticmethod + def _Callback(sym_info, callback_arg): + offset_map, offset = callback_arg + offset_map[offset] = str(sym_info) + + +class DeviceSymbolResolver(SymbolResolver): + """A SymbolResolver instance that accepts device-specific path. + + Usage is the following: + 1) Create new instance, passing a parent SymbolResolver instance that + accepts host-specific paths, and a HostLibraryFinder instance. + + 2) Optional: call AddApkOffsets() to add offsets from within an APK + that contains uncompressed native shared libraries. + + 3) Use it as any SymbolResolver instance. + """ + def __init__(self, host_resolver, host_lib_finder): + """Initialize instance. + + Args: + host_resolver: A parent SymbolResolver instance that will be used + to resolve symbols from host library paths. + host_lib_finder: A HostLibraryFinder instance used to locate + unstripped libraries on the host. + """ + super(DeviceSymbolResolver, self).__init__() + self._host_lib_finder = host_lib_finder + self._bad_device_lib_paths = set() + self._host_resolver = host_resolver + + def SetAndroidAbi(self, android_abi): + super(DeviceSymbolResolver, self).SetAndroidAbi(android_abi) + self._host_resolver.SetAndroidAbi(android_abi) + + def AddLibraryOffsets(self, device_lib_path, lib_offsets): + """Associate a set of wanted offsets to a given device library. + + This must be called before FindSymbolInfo(), otherwise its input arguments + will be ignored. + + Args: + device_lib_path: A device-specific library path. + lib_offsets: An iterable of integer offsets within the corresponding + library that will be symbolized by future calls to FindSymbolInfo. + want to symbolize. + """ + if device_lib_path in self._bad_device_lib_paths: + return + + host_lib_path = self._host_lib_finder.Find(device_lib_path) + if not host_lib_path: + # NOTE: self._bad_device_lib_paths is only used to only print this + # warning once per bad library. + logging.warning('Could not find host library matching device path: %s', + device_lib_path) + self._bad_device_lib_paths.add(device_lib_path) + return + + self._host_resolver.AddLibraryOffsets(host_lib_path, lib_offsets) + + def AddApkOffsets(self, device_apk_path, apk_offsets, apk_translator): + """Associate a set of wanted offsets to a given device APK path. + + This converts the APK-relative offsets into offsets relative to the + uncompressed libraries it contains, then calls AddLibraryOffsets() + for each one of the libraries. + + Must be called before FindSymbolInfo() as well, otherwise input arguments + will be ignored. + + Args: + device_apk_path: Device-specific APK path. + apk_offsets: Iterable of offsets within the APK file. + apk_translator: An ApkLibraryPathTranslator instance used to extract + library paths from the APK. + """ + libraries_map = collections.defaultdict(set) + for offset in apk_offsets: + lib_path, lib_offset = apk_translator.TranslatePath(device_apk_path, + offset) + libraries_map[lib_path].add(lib_offset) + + for lib_path, lib_offsets in libraries_map.iteritems(): + self.AddLibraryOffsets(lib_path, lib_offsets) + + def FindSymbolInfo(self, device_path, offset): + """Overrides SymbolResolver.FindSymbolInfo. + + Args: + device_path: Device-specific library path (e.g. + '/data/app/com.example.app-1/lib/x86/libfoo.so') + offset: Offset in device library path. + Returns: + Corresponding symbol information string, or None. + """ + host_path = self._host_lib_finder.Find(device_path) + if not host_path: + return None + + return self._host_resolver.FindSymbolInfo(host_path, offset) + + +class MemoryMap(object): + """Models the memory map of a given process. Usage is: + + 1) Create new instance, passing the Android ABI. + + 2) Call TranslateLine() whenever you want to detect and translate any + memory map input line. + + 3) Otherwise, it is possible to parse the whole memory map input with + ParseLines(), then call FindSectionForAddress() repeatedly in order + to translate a memory address into the corresponding mapping and + file information tuple (e.g. to symbolize stack entries). + """ + + # A named tuple describing interesting memory map line items. + # Fields: + # addr_start: Mapping start address in memory. + # file_offset: Corresponding file offset. + # file_size: Corresponding mapping size in bytes. + # file_path: Input file path. + # match: Corresponding regular expression match object. + LineTuple = collections.namedtuple('MemoryMapLineTuple', + 'addr_start,file_offset,file_size,' + 'file_path, match') + + # A name tuple describing a memory map section. + # Fields: + # address: Memory address. + # size: Size in bytes in memory + # offset: Starting file offset. + # path: Input file path. + SectionTuple = collections.namedtuple('MemoryMapSection', + 'address,size,offset,path') + + def __init__(self, android_abi): + """Initializes instance. + + Args: + android_abi: Android CPU ABI name (e.g. 'armeabi-v7a') + """ + hex_addr = _HexAddressRegexpFor(android_abi) + + # pylint: disable=line-too-long + # A regular expression used to match memory map entries which look like: + # b278c000-b2790fff r-- 4fda000 5000 /data/app/com.google.android.apps.chrome-2/base.apk + # pylint: enable=line-too-long + self._re_map_section = re.compile( + r'\s*(?P<addr_start>' + hex_addr + r')-(?P<addr_end>' + hex_addr + ')' + + r'\s+' + + r'(?P<perm>...)\s+' + + r'(?P<file_offset>[0-9a-f]+)\s+' + + r'(?P<file_size>[0-9a-f]+)\s*' + + r'(?P<file_path>[^ \t]+)?') + + self._addr_map = [] # Sorted list of (address, size, path, offset) tuples. + self._sorted_addresses = [] # Sorted list of address fields in _addr_map. + self._in_section = False + + def TranslateLine(self, line, apk_path_translator): + """Try to translate a memory map input line, if detected. + + This only takes care of converting mapped APK file path and offsets + into a corresponding uncompressed native library file path + new offsets, + e.g. '..... <offset> <size> /data/.../base.apk' gets + translated into '.... <new-offset> <size> /data/.../base.apk!lib/libfoo.so' + + This function should always work, even if ParseLines() was not called + previously. + + Args: + line: Input memory map / tombstone line. + apk_translator: An ApkLibraryPathTranslator instance, used to map + APK offsets into uncompressed native libraries + new offsets. + Returns: + Translated memory map line, if relevant, or unchanged input line + otherwise. + """ + t = self._ParseLine(line.rstrip()) + if not t: + return line + + new_path, new_offset = apk_path_translator.TranslatePath( + t.file_path, t.file_offset) + + if new_path == t.file_path: + return line + + pos = t.match.start('file_path') + return '%s%s (offset 0x%x)%s' % (line[0:pos], new_path, new_offset, + line[t.match.end('file_path'):]) + + def ParseLines(self, input_lines, in_section=False): + """Parse a list of input lines and extract the APK memory map out of it. + + Args: + input_lines: list, or iterable, of input lines. + in_section: Optional. If true, considers that the input lines are + already part of the memory map. Otherwise, wait until the start of + the section appears in the input before trying to record data. + Returns: + True iff APK-related memory map entries were found. False otherwise. + """ + addr_list = [] # list of (address, size, file_path, file_offset) tuples. + self._in_section = in_section + for line in input_lines: + t = self._ParseLine(line.rstrip()) + if not t: + continue + + addr_list.append(t) + + self._addr_map = sorted(addr_list, + lambda x, y: cmp(x.addr_start, y.addr_start)) + self._sorted_addresses = [e.addr_start for e in self._addr_map] + return bool(self._addr_map) + + def _ParseLine(self, line): + """Used internally to recognized memory map input lines. + + Args: + line: Input logcat or tomstone line. + Returns: + A LineTuple instance on success, or None on failure. + """ + if not self._in_section: + self._in_section = line.startswith('memory map:') + return None + + m = self._re_map_section.match(line) + if not m: + self._in_section = False # End of memory map section + return None + + # Only accept .apk and .so files that are not from the system partitions. + file_path = m.group('file_path') + if not file_path: + return None + + if file_path.startswith('/system') or file_path.startswith('/vendor'): + return None + + if not (file_path.endswith('.apk') or file_path.endswith('.so')): + return None + + addr_start = int(m.group('addr_start'), 16) + file_offset = int(m.group('file_offset'), 16) + file_size = int(m.group('file_size'), 16) + + return self.LineTuple(addr_start, file_offset, file_size, file_path, m) + + def Dump(self): + """Print memory map for debugging.""" + print 'MEMORY MAP [' + for t in self._addr_map: + print '[%08x-%08x %08x %08x %s]' % ( + t.addr_start, t.addr_start + t.file_size, t.file_size, t.file_offset, + t.file_path) + print '] MEMORY MAP' + + def FindSectionForAddress(self, addr): + """Find the map section corresponding to a specific memory address. + + Call this method only after using ParseLines() was called to extract + relevant information from the memory map. + + Args: + addr: Memory address + Returns: + A SectionTuple instance on success, or None on failure. + """ + pos = bisect.bisect_right(self._sorted_addresses, addr) + if pos > 0: + # All values in [0,pos) are <= addr, just ensure that the last + # one contains the address as well. + entry = self._addr_map[pos - 1] + if entry.addr_start + entry.file_size > addr: + return self.SectionTuple(entry.addr_start, entry.file_size, + entry.file_offset, entry.file_path) + return None + + +class BacktraceTranslator(object): + """Translates backtrace-related lines in a tombstone or crash report. + + Usage is the following: + 1) Create new instance with appropriate arguments. + 2) If the tombstone / logcat input is available, one can call + FindLibraryOffsets() in order to detect which library offsets + will need to be symbolized during a future parse. Doing so helps + speed up the ELF symbolizer. + 3) For each tombstone/logcat input line, call TranslateLine() to + try to detect and symbolize backtrace lines. + """ + + # A named tuple for relevant input backtrace lines. + # Fields: + # rel_pc: Instruction pointer, relative to offset in library start. + # location: Library or APK file path. + # offset: Load base of executable code in library or apk file path. + # match: The corresponding regular expression match object. + # Note: + # The actual instruction pointer always matches the position at + # |offset + rel_pc| in |location|. + LineTuple = collections.namedtuple('BacktraceLineTuple', + 'rel_pc,location,offset,match') + + def __init__(self, android_abi, apk_translator): + """Initialize instance. + + Args: + android_abi: Android CPU ABI name (e.g. 'armeabi-v7a'). + apk_translator: ApkLibraryPathTranslator instance used to convert + mapped APK file offsets into uncompressed library file paths with + new offsets. + """ + hex_addr = _HexAddressRegexpFor(android_abi) + + # A regular expression used to match backtrace lines. + self._re_backtrace = re.compile( + r'.*#(?P<frame>[0-9]{2})\s+' + + r'(..)\s+' + + r'(?P<rel_pc>' + hex_addr + r')\s+' + + r'(?P<location>[^ \t]+)' + + r'(\s+\(offset 0x(?P<offset>[0-9a-f]+)\))?') + + # In certain cases, offset will be provided as <location>+0x<offset> + # instead of <location> (offset 0x<offset>). This is a regexp to detect + # this. + self._re_location_offset = re.compile( + r'.*\+0x(?P<offset>[0-9a-f]+)$') + + self._apk_translator = apk_translator + self._in_section = False + + def _ParseLine(self, line): + """Used internally to detect and decompose backtrace input lines. + + Args: + line: input tombstone line. + Returns: + A LineTuple instance on success, None on failure. + """ + if not self._in_section: + self._in_section = line.startswith('backtrace:') + return None + + line = line.rstrip() + m = self._re_backtrace.match(line) + if not m: + self._in_section = False + return None + + location = m.group('location') + offset = m.group('offset') + if not offset: + m2 = self._re_location_offset.match(location) + if m2: + offset = m2.group('offset') + location = location[0:m2.start('offset') - 3] + + if not offset: + return None + + offset = int(offset, 16) + rel_pc = int(m.group('rel_pc'), 16) + + # Two cases to consider here: + # + # * If this is a library file directly mapped in memory, then |rel_pc| + # if the direct offset within the library, and doesn't need any kind + # of adjustement. + # + # * If this is a library mapped directly from an .apk file, then + # |rel_pc| is the offset in the APK, and |offset| happens to be the + # load base of the corresponding library. + # + if location.endswith('.so'): + # For a native library directly mapped from the file system, + return self.LineTuple(rel_pc, location, offset, m) + + if location.endswith('.apk'): + # For a native library inside an memory-mapped APK file, + new_location, new_offset = self._apk_translator.TranslatePath( + location, offset) + + return self.LineTuple(rel_pc, new_location, new_offset, m) + + # Ignore anything else (e.g. .oat or .odex files). + return None + + def FindLibraryOffsets(self, input_lines, in_section=False): + """Parse a tombstone's backtrace section and find all library offsets in it. + + Args: + input_lines: List or iterables of intput tombstone lines. + in_section: Optional. If True, considers that the stack section has + already started. + Returns: + A dictionary mapping device library paths to sets of offsets within + then. + """ + self._in_section = in_section + result = collections.defaultdict(set) + for line in input_lines: + t = self._ParseLine(line) + if not t: + continue + + result[t.location].add(t.offset + t.rel_pc) + return result + + def TranslateLine(self, line, symbol_resolver): + """Symbolize backtrace line if recognized. + + Args: + line: input backtrace line. + symbol_resolver: symbol resolver instance to use. This method will + call its FindSymbolInfo(device_lib_path, lib_offset) method to + convert offsets into symbol informations strings. + Returns: + Translated line (unchanged if not recognized as a back trace). + """ + t = self._ParseLine(line) + if not t: + return line + + symbol_info = symbol_resolver.FindSymbolInfo(t.location, + t.offset + t.rel_pc) + if not symbol_info: + symbol_info = 'offset 0x%x' % t.offset + + pos = t.match.start('location') + pos2 = t.match.end('offset') + 1 + if pos2 <= 0: + pos2 = t.match.end('location') + return '%s%s (%s)%s' % (line[:pos], t.location, symbol_info, line[pos2:]) + + +class StackTranslator(object): + """Translates stack-related lines in a tombstone or crash report.""" + + # A named tuple describing relevant stack input lines. + # Fields: + # address: Address as it appears in the stack. + # lib_path: Library path where |address| is mapped. + # lib_offset: Library load base offset. for |lib_path|. + # match: Corresponding regular expression match object. + LineTuple = collections.namedtuple('StackLineTuple', + 'address, lib_path, lib_offset, match') + + def __init__(self, android_abi, memory_map, apk_translator): + """Initialize instance.""" + hex_addr = _HexAddressRegexpFor(android_abi) + + # pylint: disable=line-too-long + # A regular expression used to recognize stack entries like: + # + # #05 bf89a180 bf89a1e4 [stack] + # bf89a1c8 a0c01c51 /data/app/com.google.android.apps.chrome-2/base.apk + # bf89a080 00000000 + # ........ ........ + # pylint: enable=line-too-long + self._re_stack_line = re.compile( + r'\s+(?P<frame_number>#[0-9]+)?\s*' + + r'(?P<stack_addr>' + hex_addr + r')\s+' + + r'(?P<stack_value>' + hex_addr + r')' + + r'(\s+(?P<location>[^ \t]+))?') + + self._re_stack_abbrev = re.compile(r'\s+[.]+\s+[.]+') + + self._memory_map = memory_map + self._apk_translator = apk_translator + self._in_section = False + + def _ParseLine(self, line): + """Check a given input line for a relevant _re_stack_line match. + + Args: + line: input tombstone line. + Returns: + A LineTuple instance on success, None on failure. + """ + line = line.rstrip() + if not self._in_section: + self._in_section = line.startswith('stack:') + return None + + m = self._re_stack_line.match(line) + if not m: + if not self._re_stack_abbrev.match(line): + self._in_section = False + return None + + location = m.group('location') + if not location: + return None + + if not location.endswith('.apk') and not location.endswith('.so'): + return None + + addr = int(m.group('stack_value'), 16) + t = self._memory_map.FindSectionForAddress(addr) + if t is None: + return None + + lib_path = t.path + lib_offset = t.offset + (addr - t.address) + + if lib_path.endswith('.apk'): + lib_path, lib_offset = self._apk_translator.TranslatePath( + lib_path, lib_offset) + + return self.LineTuple(addr, lib_path, lib_offset, m) + + def FindLibraryOffsets(self, input_lines, in_section=False): + """Parse a tombstone's stack section and find all library offsets in it. + + Args: + input_lines: List or iterables of intput tombstone lines. + in_section: Optional. If True, considers that the stack section has + already started. + Returns: + A dictionary mapping device library paths to sets of offsets within + then. + """ + result = collections.defaultdict(set) + self._in_section = in_section + for line in input_lines: + t = self._ParseLine(line) + if t: + result[t.lib_path].add(t.lib_offset) + return result + + def TranslateLine(self, line, symbol_resolver=None): + """Try to translate a line of the stack dump.""" + t = self._ParseLine(line) + if not t: + return line + + symbol_info = symbol_resolver.FindSymbolInfo(t.lib_path, t.lib_offset) + if not symbol_info: + return line + + pos = t.match.start('location') + pos2 = t.match.end('location') + return '%s%s (%s)%s' % (line[:pos], t.lib_path, symbol_info, line[pos2:])
diff --git a/build/android/pylib/symbols/symbol_utils_unittest.py b/build/android/pylib/symbols/symbol_utils_unittest.py new file mode 100644 index 0000000..d350c17 --- /dev/null +++ b/build/android/pylib/symbols/symbol_utils_unittest.py
@@ -0,0 +1,944 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import collections +import contextlib +import logging +import os +import re +import shutil +import tempfile +import unittest + +from pylib.symbols import apk_native_libs_unittest +from pylib.symbols import mock_addr2line +from pylib.symbols import symbol_utils + +_MOCK_ELF_DATA = apk_native_libs_unittest.MOCK_ELF_DATA + +_MOCK_A2L_PATH = os.path.join(os.path.dirname(mock_addr2line.__file__), + 'mock_addr2line') + + +# pylint: disable=line-too-long + +# list of (start_offset, end_offset, size, libpath) tuples corresponding +# to the content of base.apk. This was taken from an x86 ChromeModern.apk +# component build. +_TEST_APK_LIBS = [ + (0x01331000, 0x013696bc, 0x000386bc, 'libaccessibility.cr.so'), + (0x0136a000, 0x013779c4, 0x0000d9c4, 'libanimation.cr.so'), + (0x01378000, 0x0137f7e8, 0x000077e8, 'libapdu.cr.so'), + (0x01380000, 0x0155ccc8, 0x001dccc8, 'libbase.cr.so'), + (0x0155d000, 0x015ab98c, 0x0004e98c, 'libbase_i18n.cr.so'), + (0x015ac000, 0x015dff4c, 0x00033f4c, 'libbindings.cr.so'), + (0x015e0000, 0x015f5a54, 0x00015a54, 'libbindings_base.cr.so'), + (0x015f6000, 0x0160d770, 0x00017770, 'libblink_android_mojo_bindings_shared.cr.so'), + (0x0160e000, 0x01731960, 0x00123960, 'libblink_common.cr.so'), + (0x01732000, 0x0174ce54, 0x0001ae54, 'libblink_controller.cr.so'), + (0x0174d000, 0x0318c528, 0x01a3f528, 'libblink_core.cr.so'), + (0x0318d000, 0x03191700, 0x00004700, 'libblink_core_mojo_bindings_shared.cr.so'), + (0x03192000, 0x03cd7918, 0x00b45918, 'libblink_modules.cr.so'), + (0x03cd8000, 0x03d137d0, 0x0003b7d0, 'libblink_mojo_bindings_shared.cr.so'), + (0x03d14000, 0x03d2670c, 0x0001270c, 'libblink_offscreen_canvas_mojo_bindings_shared.cr.so'), + (0x03d27000, 0x046c7054, 0x009a0054, 'libblink_platform.cr.so'), + (0x046c8000, 0x0473fbfc, 0x00077bfc, 'libbluetooth.cr.so'), + (0x04740000, 0x04878f40, 0x00138f40, 'libboringssl.cr.so'), + (0x04879000, 0x0498466c, 0x0010b66c, 'libc++_shared.so'), + (0x04985000, 0x0498d93c, 0x0000893c, 'libcaptive_portal.cr.so'), + (0x0498e000, 0x049947cc, 0x000067cc, 'libcapture_base.cr.so'), + (0x04995000, 0x04b39f18, 0x001a4f18, 'libcapture_lib.cr.so'), + (0x04b3a000, 0x04b488ec, 0x0000e8ec, 'libcbor.cr.so'), + (0x04b49000, 0x04e9ea5c, 0x00355a5c, 'libcc.cr.so'), + (0x04e9f000, 0x04ed6404, 0x00037404, 'libcc_animation.cr.so'), + (0x04ed7000, 0x04ef5ab4, 0x0001eab4, 'libcc_base.cr.so'), + (0x04ef6000, 0x04fd9364, 0x000e3364, 'libcc_blink.cr.so'), + (0x04fda000, 0x04fe2758, 0x00008758, 'libcc_debug.cr.so'), + (0x04fe3000, 0x0500ae0c, 0x00027e0c, 'libcc_ipc.cr.so'), + (0x0500b000, 0x05078f38, 0x0006df38, 'libcc_paint.cr.so'), + (0x05079000, 0x0507e734, 0x00005734, 'libcdm_manager.cr.so'), + (0x0507f000, 0x06f4d744, 0x01ece744, 'libchrome.cr.so'), + (0x06f54000, 0x06feb830, 0x00097830, 'libchromium_sqlite3.cr.so'), + (0x06fec000, 0x0706f554, 0x00083554, 'libclient.cr.so'), + (0x07070000, 0x0708da60, 0x0001da60, 'libcloud_policy_proto_generated_compile.cr.so'), + (0x0708e000, 0x07121f28, 0x00093f28, 'libcodec.cr.so'), + (0x07122000, 0x07134ab8, 0x00012ab8, 'libcolor_space.cr.so'), + (0x07135000, 0x07138614, 0x00003614, 'libcommon.cr.so'), + (0x07139000, 0x0717c938, 0x00043938, 'libcompositor.cr.so'), + (0x0717d000, 0x0923d78c, 0x020c078c, 'libcontent.cr.so'), + (0x0923e000, 0x092ae87c, 0x0007087c, 'libcontent_common_mojo_bindings_shared.cr.so'), + (0x092af000, 0x092be718, 0x0000f718, 'libcontent_public_common_mojo_bindings_shared.cr.so'), + (0x092bf000, 0x092d9a20, 0x0001aa20, 'libcrash_key.cr.so'), + (0x092da000, 0x092eda58, 0x00013a58, 'libcrcrypto.cr.so'), + (0x092ee000, 0x092f16e0, 0x000036e0, 'libdevice_base.cr.so'), + (0x092f2000, 0x092fe8d8, 0x0000c8d8, 'libdevice_event_log.cr.so'), + (0x092ff000, 0x093026a4, 0x000036a4, 'libdevice_features.cr.so'), + (0x09303000, 0x093f1220, 0x000ee220, 'libdevice_gamepad.cr.so'), + (0x093f2000, 0x09437f54, 0x00045f54, 'libdevice_vr_mojo_bindings.cr.so'), + (0x09438000, 0x0954c168, 0x00114168, 'libdevice_vr_mojo_bindings_blink.cr.so'), + (0x0954d000, 0x0955d720, 0x00010720, 'libdevice_vr_mojo_bindings_shared.cr.so'), + (0x0955e000, 0x0956b9c0, 0x0000d9c0, 'libdevices.cr.so'), + (0x0956c000, 0x0957cae8, 0x00010ae8, 'libdiscardable_memory_client.cr.so'), + (0x0957d000, 0x09588854, 0x0000b854, 'libdiscardable_memory_common.cr.so'), + (0x09589000, 0x0959cbb4, 0x00013bb4, 'libdiscardable_memory_service.cr.so'), + (0x0959d000, 0x095b6b90, 0x00019b90, 'libdisplay.cr.so'), + (0x095b7000, 0x095be930, 0x00007930, 'libdisplay_types.cr.so'), + (0x095bf000, 0x095c46c4, 0x000056c4, 'libdisplay_util.cr.so'), + (0x095c5000, 0x095f54a4, 0x000304a4, 'libdomain_reliability.cr.so'), + (0x095f6000, 0x0966fe08, 0x00079e08, 'libembedder.cr.so'), + (0x09670000, 0x096735f8, 0x000035f8, 'libembedder_switches.cr.so'), + (0x09674000, 0x096a3460, 0x0002f460, 'libevents.cr.so'), + (0x096a4000, 0x096b6d40, 0x00012d40, 'libevents_base.cr.so'), + (0x096b7000, 0x0981a778, 0x00163778, 'libffmpeg.cr.so'), + (0x0981b000, 0x09945c94, 0x0012ac94, 'libfido.cr.so'), + (0x09946000, 0x09a330dc, 0x000ed0dc, 'libfingerprint.cr.so'), + (0x09a34000, 0x09b53170, 0x0011f170, 'libfreetype_harfbuzz.cr.so'), + (0x09b54000, 0x09bc5c5c, 0x00071c5c, 'libgcm.cr.so'), + (0x09bc6000, 0x09cc8584, 0x00102584, 'libgeolocation.cr.so'), + (0x09cc9000, 0x09cdc8d4, 0x000138d4, 'libgeometry.cr.so'), + (0x09cdd000, 0x09cec8b4, 0x0000f8b4, 'libgeometry_skia.cr.so'), + (0x09ced000, 0x09d10e14, 0x00023e14, 'libgesture_detection.cr.so'), + (0x09d11000, 0x09d7595c, 0x0006495c, 'libgfx.cr.so'), + (0x09d76000, 0x09d7d7cc, 0x000077cc, 'libgfx_ipc.cr.so'), + (0x09d7e000, 0x09d82708, 0x00004708, 'libgfx_ipc_buffer_types.cr.so'), + (0x09d83000, 0x09d89748, 0x00006748, 'libgfx_ipc_color.cr.so'), + (0x09d8a000, 0x09d8f6f4, 0x000056f4, 'libgfx_ipc_geometry.cr.so'), + (0x09d90000, 0x09d94754, 0x00004754, 'libgfx_ipc_skia.cr.so'), + (0x09d95000, 0x09d9869c, 0x0000369c, 'libgfx_switches.cr.so'), + (0x09d99000, 0x09dba0ac, 0x000210ac, 'libgin.cr.so'), + (0x09dbb000, 0x09e0a8cc, 0x0004f8cc, 'libgl_in_process_context.cr.so'), + (0x09e0b000, 0x09e17a18, 0x0000ca18, 'libgl_init.cr.so'), + (0x09e18000, 0x09ee34e4, 0x000cb4e4, 'libgl_wrapper.cr.so'), + (0x09ee4000, 0x0a1a2e00, 0x002bee00, 'libgles2.cr.so'), + (0x0a1a3000, 0x0a24556c, 0x000a256c, 'libgles2_implementation.cr.so'), + (0x0a246000, 0x0a267038, 0x00021038, 'libgles2_utils.cr.so'), + (0x0a268000, 0x0a3288e4, 0x000c08e4, 'libgpu.cr.so'), + (0x0a329000, 0x0a3627ec, 0x000397ec, 'libgpu_ipc_service.cr.so'), + (0x0a363000, 0x0a388a18, 0x00025a18, 'libgpu_util.cr.so'), + (0x0a389000, 0x0a506d8c, 0x0017dd8c, 'libhost.cr.so'), + (0x0a507000, 0x0a6f0ec0, 0x001e9ec0, 'libicui18n.cr.so'), + (0x0a6f1000, 0x0a83b4c8, 0x0014a4c8, 'libicuuc.cr.so'), + (0x0a83c000, 0x0a8416e4, 0x000056e4, 'libinterfaces_shared.cr.so'), + (0x0a842000, 0x0a87e2a0, 0x0003c2a0, 'libipc.cr.so'), + (0x0a87f000, 0x0a88c98c, 0x0000d98c, 'libipc_mojom.cr.so'), + (0x0a88d000, 0x0a8926e4, 0x000056e4, 'libipc_mojom_shared.cr.so'), + (0x0a893000, 0x0a8a1e18, 0x0000ee18, 'libkeyed_service_content.cr.so'), + (0x0a8a2000, 0x0a8b4a30, 0x00012a30, 'libkeyed_service_core.cr.so'), + (0x0a8b5000, 0x0a930a80, 0x0007ba80, 'libleveldatabase.cr.so'), + (0x0a931000, 0x0a9b3908, 0x00082908, 'libmanager.cr.so'), + (0x0a9b4000, 0x0aea9bb4, 0x004f5bb4, 'libmedia.cr.so'), + (0x0aeaa000, 0x0b08cb88, 0x001e2b88, 'libmedia_blink.cr.so'), + (0x0b08d000, 0x0b0a4728, 0x00017728, 'libmedia_devices_mojo_bindings_shared.cr.so'), + (0x0b0a5000, 0x0b1943ec, 0x000ef3ec, 'libmedia_gpu.cr.so'), + (0x0b195000, 0x0b2d07d4, 0x0013b7d4, 'libmedia_mojo_services.cr.so'), + (0x0b2d1000, 0x0b2d4760, 0x00003760, 'libmessage_center.cr.so'), + (0x0b2d5000, 0x0b2e0938, 0x0000b938, 'libmessage_support.cr.so'), + (0x0b2e1000, 0x0b2f3ad0, 0x00012ad0, 'libmetrics_cpp.cr.so'), + (0x0b2f4000, 0x0b313bb8, 0x0001fbb8, 'libmidi.cr.so'), + (0x0b314000, 0x0b31b848, 0x00007848, 'libmojo_base_lib.cr.so'), + (0x0b31c000, 0x0b3329f8, 0x000169f8, 'libmojo_base_mojom.cr.so'), + (0x0b333000, 0x0b34b98c, 0x0001898c, 'libmojo_base_mojom_blink.cr.so'), + (0x0b34c000, 0x0b354700, 0x00008700, 'libmojo_base_mojom_shared.cr.so'), + (0x0b355000, 0x0b3608b0, 0x0000b8b0, 'libmojo_base_shared_typemap_traits.cr.so'), + (0x0b361000, 0x0b3ad454, 0x0004c454, 'libmojo_edk.cr.so'), + (0x0b3ae000, 0x0b3c4a20, 0x00016a20, 'libmojo_edk_ports.cr.so'), + (0x0b3c5000, 0x0b3d38a0, 0x0000e8a0, 'libmojo_mojom_bindings.cr.so'), + (0x0b3d4000, 0x0b3da6e8, 0x000066e8, 'libmojo_mojom_bindings_shared.cr.so'), + (0x0b3db000, 0x0b3e27f0, 0x000077f0, 'libmojo_public_system.cr.so'), + (0x0b3e3000, 0x0b3fa9fc, 0x000179fc, 'libmojo_public_system_cpp.cr.so'), + (0x0b3fb000, 0x0b407728, 0x0000c728, 'libmojom_core_shared.cr.so'), + (0x0b408000, 0x0b421744, 0x00019744, 'libmojom_platform_shared.cr.so'), + (0x0b422000, 0x0b43451c, 0x0001251c, 'libnative_theme.cr.so'), + (0x0b435000, 0x0baaa1bc, 0x006751bc, 'libnet.cr.so'), + (0x0baab000, 0x0bac3c08, 0x00018c08, 'libnet_with_v8.cr.so'), + (0x0bac4000, 0x0bb74670, 0x000b0670, 'libnetwork_cpp.cr.so'), + (0x0bb75000, 0x0bbaee8c, 0x00039e8c, 'libnetwork_cpp_base.cr.so'), + (0x0bbaf000, 0x0bd21844, 0x00172844, 'libnetwork_service.cr.so'), + (0x0bd22000, 0x0bd256e4, 0x000036e4, 'libnetwork_session_configurator.cr.so'), + (0x0bd26000, 0x0bd33734, 0x0000d734, 'libonc.cr.so'), + (0x0bd34000, 0x0bd9ce18, 0x00068e18, 'libperfetto.cr.so'), + (0x0bd9d000, 0x0bda4854, 0x00007854, 'libplatform.cr.so'), + (0x0bda5000, 0x0bec5ce4, 0x00120ce4, 'libpolicy_component.cr.so'), + (0x0bec6000, 0x0bf5ab58, 0x00094b58, 'libpolicy_proto.cr.so'), + (0x0bf5b000, 0x0bf86fbc, 0x0002bfbc, 'libprefs.cr.so'), + (0x0bf87000, 0x0bfa5d74, 0x0001ed74, 'libprinting.cr.so'), + (0x0bfa6000, 0x0bfe0e80, 0x0003ae80, 'libprotobuf_lite.cr.so'), + (0x0bfe1000, 0x0bff0a18, 0x0000fa18, 'libproxy_config.cr.so'), + (0x0bff1000, 0x0c0f6654, 0x00105654, 'libpublic.cr.so'), + (0x0c0f7000, 0x0c0fa6a4, 0x000036a4, 'librange.cr.so'), + (0x0c0fb000, 0x0c118058, 0x0001d058, 'libraster.cr.so'), + (0x0c119000, 0x0c133d00, 0x0001ad00, 'libresource_coordinator_cpp.cr.so'), + (0x0c134000, 0x0c1396a0, 0x000056a0, 'libresource_coordinator_cpp_base.cr.so'), + (0x0c13a000, 0x0c1973b8, 0x0005d3b8, 'libresource_coordinator_public_mojom.cr.so'), + (0x0c198000, 0x0c2033e8, 0x0006b3e8, 'libresource_coordinator_public_mojom_blink.cr.so'), + (0x0c204000, 0x0c219744, 0x00015744, 'libresource_coordinator_public_mojom_shared.cr.so'), + (0x0c21a000, 0x0c21e700, 0x00004700, 'libsandbox.cr.so'), + (0x0c21f000, 0x0c22f96c, 0x0001096c, 'libsandbox_services.cr.so'), + (0x0c230000, 0x0c249d58, 0x00019d58, 'libseccomp_bpf.cr.so'), + (0x0c24a000, 0x0c24e714, 0x00004714, 'libseccomp_starter_android.cr.so'), + (0x0c24f000, 0x0c4ae9f0, 0x0025f9f0, 'libservice.cr.so'), + (0x0c4af000, 0x0c4c3ae4, 0x00014ae4, 'libservice_manager_cpp.cr.so'), + (0x0c4c4000, 0x0c4cb708, 0x00007708, 'libservice_manager_cpp_types.cr.so'), + (0x0c4cc000, 0x0c4fbe30, 0x0002fe30, 'libservice_manager_mojom.cr.so'), + (0x0c4fc000, 0x0c532e78, 0x00036e78, 'libservice_manager_mojom_blink.cr.so'), + (0x0c533000, 0x0c53669c, 0x0000369c, 'libservice_manager_mojom_constants.cr.so'), + (0x0c537000, 0x0c53e85c, 0x0000785c, 'libservice_manager_mojom_constants_blink.cr.so'), + (0x0c53f000, 0x0c542668, 0x00003668, 'libservice_manager_mojom_constants_shared.cr.so'), + (0x0c543000, 0x0c54d700, 0x0000a700, 'libservice_manager_mojom_shared.cr.so'), + (0x0c54e000, 0x0c8fc6ec, 0x003ae6ec, 'libsessions.cr.so'), + (0x0c8fd000, 0x0c90a924, 0x0000d924, 'libshared_memory_support.cr.so'), + (0x0c90b000, 0x0c9148ec, 0x000098ec, 'libshell_dialogs.cr.so'), + (0x0c915000, 0x0cf8de70, 0x00678e70, 'libskia.cr.so'), + (0x0cf8e000, 0x0cf978bc, 0x000098bc, 'libsnapshot.cr.so'), + (0x0cf98000, 0x0cfb7d9c, 0x0001fd9c, 'libsql.cr.so'), + (0x0cfb8000, 0x0cfbe744, 0x00006744, 'libstartup_tracing.cr.so'), + (0x0cfbf000, 0x0d19b4e4, 0x001dc4e4, 'libstorage_browser.cr.so'), + (0x0d19c000, 0x0d2a773c, 0x0010b73c, 'libstorage_common.cr.so'), + (0x0d2a8000, 0x0d2ac6fc, 0x000046fc, 'libsurface.cr.so'), + (0x0d2ad000, 0x0d2baa98, 0x0000da98, 'libtracing.cr.so'), + (0x0d2bb000, 0x0d2f36b0, 0x000386b0, 'libtracing_cpp.cr.so'), + (0x0d2f4000, 0x0d326e70, 0x00032e70, 'libtracing_mojom.cr.so'), + (0x0d327000, 0x0d33270c, 0x0000b70c, 'libtracing_mojom_shared.cr.so'), + (0x0d333000, 0x0d46d804, 0x0013a804, 'libui_android.cr.so'), + (0x0d46e000, 0x0d4cb3f8, 0x0005d3f8, 'libui_base.cr.so'), + (0x0d4cc000, 0x0d4dbc40, 0x0000fc40, 'libui_base_ime.cr.so'), + (0x0d4dc000, 0x0d4e58d4, 0x000098d4, 'libui_data_pack.cr.so'), + (0x0d4e6000, 0x0d51d1e0, 0x000371e0, 'libui_devtools.cr.so'), + (0x0d51e000, 0x0d52b984, 0x0000d984, 'libui_message_center_cpp.cr.so'), + (0x0d52c000, 0x0d539a48, 0x0000da48, 'libui_touch_selection.cr.so'), + (0x0d53a000, 0x0d55bc60, 0x00021c60, 'liburl.cr.so'), + (0x0d55c000, 0x0d55f6b4, 0x000036b4, 'liburl_ipc.cr.so'), + (0x0d560000, 0x0d5af110, 0x0004f110, 'liburl_matcher.cr.so'), + (0x0d5b0000, 0x0d5e2fac, 0x00032fac, 'libuser_manager.cr.so'), + (0x0d5e3000, 0x0d5e66e4, 0x000036e4, 'libuser_prefs.cr.so'), + (0x0d5e7000, 0x0e3e1cc8, 0x00dfacc8, 'libv8.cr.so'), + (0x0e3e2000, 0x0e400ae0, 0x0001eae0, 'libv8_libbase.cr.so'), + (0x0e401000, 0x0e4d91d4, 0x000d81d4, 'libviz_common.cr.so'), + (0x0e4da000, 0x0e4df7e4, 0x000057e4, 'libviz_resource_format.cr.so'), + (0x0e4e0000, 0x0e5b7120, 0x000d7120, 'libweb_dialogs.cr.so'), + (0x0e5b8000, 0x0e5c7a18, 0x0000fa18, 'libwebdata_common.cr.so'), + (0x0e5c8000, 0x0e61bfe4, 0x00053fe4, 'libwtf.cr.so'), +] + + +# A small memory map fragment extracted from a tombstone for a process that +# had loaded the APK corresponding to _TEST_APK_LIBS above. +_TEST_MEMORY_MAP = r'''memory map: +12c00000-12ccafff rw- 0 cb000 /dev/ashmem/dalvik-main space (deleted) +12ccb000-130cafff rw- cb000 400000 /dev/ashmem/dalvik-main space (deleted) +130cb000-32bfffff --- 4cb000 1fb35000 /dev/ashmem/dalvik-main space (deleted) +32c00000-32c00fff rw- 0 1000 /dev/ashmem/dalvik-main space 1 (deleted) +32c01000-52bfffff --- 1000 1ffff000 /dev/ashmem/dalvik-main space 1 (deleted) +6f3b8000-6fd90fff rw- 0 9d9000 /data/dalvik-cache/x86/system@framework@boot.art +6fd91000-71c42fff r-- 0 1eb2000 /data/dalvik-cache/x86/system@framework@boot.oat +71c43000-7393efff r-x 1eb2000 1cfc000 /data/dalvik-cache/x86/system@framework@boot.oat (load base 0x71c43000) +7393f000-7393ffff rw- 3bae000 1000 /data/dalvik-cache/x86/system@framework@boot.oat +73940000-73a1bfff rw- 0 dc000 /dev/ashmem/dalvik-zygote space (deleted) +73a1c000-73a1cfff rw- 0 1000 /dev/ashmem/dalvik-non moving space (deleted) +73a1d000-73a2dfff rw- 1000 11000 /dev/ashmem/dalvik-non moving space (deleted) +73a2e000-77540fff --- 12000 3b13000 /dev/ashmem/dalvik-non moving space (deleted) +77541000-7793ffff rw- 3b25000 3ff000 /dev/ashmem/dalvik-non moving space (deleted) +923aa000-92538fff r-- 8a9000 18f000 /data/app/com.example.app-2/base.apk +92539000-9255bfff r-- 0 23000 /data/data/com.example.app/app_data/paks/es.pak@162db1c6689 +9255c000-92593fff r-- 213000 38000 /data/app/com.example.app-2/base.apk +92594000-925c0fff r-- 87d000 2d000 /data/app/com.example.app-2/base.apk +925c1000-927d3fff r-- a37000 213000 /data/app/com.example.app-2/base.apk +927d4000-92e07fff r-- 24a000 634000 /data/app/com.example.app-2/base.apk +92e08000-92e37fff r-- a931000 30000 /data/app/com.example.app-2/base.apk +92e38000-92e86fff r-x a961000 4f000 /data/app/com.example.app-2/base.apk +92e87000-92e8afff rw- a9b0000 4000 /data/app/com.example.app-2/base.apk +92e8b000-92e8bfff rw- 0 1000 +92e8c000-92e9dfff r-- d5b0000 12000 /data/app/com.example.app-2/base.apk +92e9e000-92ebcfff r-x d5c2000 1f000 /data/app/com.example.app-2/base.apk +92ebd000-92ebefff rw- d5e1000 2000 /data/app/com.example.app-2/base.apk +92ebf000-92ebffff rw- 0 1000 +''' + +# list of (address, size, path, offset) tuples that must appear in +# _TEST_MEMORY_MAP. Not all sections need to be listed. +_TEST_MEMORY_MAP_SECTIONS = [ + (0x923aa000, 0x18f000, '/data/app/com.example.app-2/base.apk', 0x8a9000), + (0x9255c000, 0x038000, '/data/app/com.example.app-2/base.apk', 0x213000), + (0x92594000, 0x02d000, '/data/app/com.example.app-2/base.apk', 0x87d000), + (0x925c1000, 0x213000, '/data/app/com.example.app-2/base.apk', 0xa37000), +] + +_EXPECTED_TEST_MEMORY_MAP = r'''memory map: +12c00000-12ccafff rw- 0 cb000 /dev/ashmem/dalvik-main space (deleted) +12ccb000-130cafff rw- cb000 400000 /dev/ashmem/dalvik-main space (deleted) +130cb000-32bfffff --- 4cb000 1fb35000 /dev/ashmem/dalvik-main space (deleted) +32c00000-32c00fff rw- 0 1000 /dev/ashmem/dalvik-main space 1 (deleted) +32c01000-52bfffff --- 1000 1ffff000 /dev/ashmem/dalvik-main space 1 (deleted) +6f3b8000-6fd90fff rw- 0 9d9000 /data/dalvik-cache/x86/system@framework@boot.art +6fd91000-71c42fff r-- 0 1eb2000 /data/dalvik-cache/x86/system@framework@boot.oat +71c43000-7393efff r-x 1eb2000 1cfc000 /data/dalvik-cache/x86/system@framework@boot.oat (load base 0x71c43000) +7393f000-7393ffff rw- 3bae000 1000 /data/dalvik-cache/x86/system@framework@boot.oat +73940000-73a1bfff rw- 0 dc000 /dev/ashmem/dalvik-zygote space (deleted) +73a1c000-73a1cfff rw- 0 1000 /dev/ashmem/dalvik-non moving space (deleted) +73a1d000-73a2dfff rw- 1000 11000 /dev/ashmem/dalvik-non moving space (deleted) +73a2e000-77540fff --- 12000 3b13000 /dev/ashmem/dalvik-non moving space (deleted) +77541000-7793ffff rw- 3b25000 3ff000 /dev/ashmem/dalvik-non moving space (deleted) +923aa000-92538fff r-- 8a9000 18f000 /data/app/com.example.app-2/base.apk +92539000-9255bfff r-- 0 23000 /data/data/com.example.app/app_data/paks/es.pak@162db1c6689 +9255c000-92593fff r-- 213000 38000 /data/app/com.example.app-2/base.apk +92594000-925c0fff r-- 87d000 2d000 /data/app/com.example.app-2/base.apk +925c1000-927d3fff r-- a37000 213000 /data/app/com.example.app-2/base.apk +927d4000-92e07fff r-- 24a000 634000 /data/app/com.example.app-2/base.apk +92e08000-92e37fff r-- a931000 30000 /data/app/com.example.app-2/base.apk!lib/libmanager.cr.so (offset 0x0) +92e38000-92e86fff r-x a961000 4f000 /data/app/com.example.app-2/base.apk!lib/libmanager.cr.so (offset 0x30000) +92e87000-92e8afff rw- a9b0000 4000 /data/app/com.example.app-2/base.apk!lib/libmanager.cr.so (offset 0x7f000) +92e8b000-92e8bfff rw- 0 1000 +92e8c000-92e9dfff r-- d5b0000 12000 /data/app/com.example.app-2/base.apk!lib/libuser_manager.cr.so (offset 0x0) +92e9e000-92ebcfff r-x d5c2000 1f000 /data/app/com.example.app-2/base.apk!lib/libuser_manager.cr.so (offset 0x12000) +92ebd000-92ebefff rw- d5e1000 2000 /data/app/com.example.app-2/base.apk!lib/libuser_manager.cr.so (offset 0x31000) +92ebf000-92ebffff rw- 0 1000 +''' + +# Example stack section, taken from the same tombstone that _TEST_MEMORY_MAP +# was extracted from. +_TEST_STACK = r'''stack: + bf89a070 b7439468 /system/lib/libc.so + bf89a074 bf89a1e4 [stack] + bf89a078 932d4000 /data/app/com.example.app-2/base.apk + bf89a07c b73bfbc9 /system/lib/libc.so (pthread_mutex_lock+65) + bf89a080 00000000 + bf89a084 4000671c /dev/ashmem/dalvik-main space 1 (deleted) + bf89a088 932d1d86 /data/app/com.example.app-2/base.apk + bf89a08c b743671c /system/lib/libc.so + bf89a090 b77f8c00 /system/bin/linker + bf89a094 b743cc90 + bf89a098 932d1d4a /data/app/com.example.app-2/base.apk + bf89a09c b73bf271 /system/lib/libc.so (__pthread_internal_find(long)+65) + bf89a0a0 b743cc90 + bf89a0a4 bf89a0b0 [stack] + bf89a0a8 bf89a0b8 [stack] + bf89a0ac 00000008 + ........ ........ + #00 bf89a0b0 00000006 + bf89a0b4 00000002 + bf89a0b8 b743671c /system/lib/libc.so + bf89a0bc b73bf5d9 /system/lib/libc.so (pthread_kill+71) + #01 bf89a0c0 00006937 + bf89a0c4 00006937 + bf89a0c8 00000006 + bf89a0cc b77fd3a9 /system/bin/app_process32 (sigprocmask+141) + bf89a0d0 00000002 + bf89a0d4 bf89a0ec [stack] + bf89a0d8 00000000 + bf89a0dc b743671c /system/lib/libc.so + bf89a0e0 bf89a12c [stack] + bf89a0e4 bf89a1e4 [stack] + bf89a0e8 932d1d4a /data/app/com.example.app-2/base.apk + bf89a0ec b7365206 /system/lib/libc.so (raise+37) + #02 bf89a0f0 b77f8c00 /system/bin/linker + bf89a0f4 00000006 + bf89a0f8 b7439468 /system/lib/libc.so + bf89a0fc b743671c /system/lib/libc.so + bf89a100 bf89a12c [stack] + bf89a104 b743671c /system/lib/libc.so + bf89a108 bf89a12c [stack] + bf89a10c b735e9e5 /system/lib/libc.so (abort+81) + #03 bf89a110 00000006 + bf89a114 bf89a12c [stack] + bf89a118 00000000 + bf89a11c b55a3d3b /system/lib/libprotobuf-cpp-lite.so (google::protobuf::internal::DefaultLogHandler(google::protobuf::LogLevel, char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)+99) + bf89a120 b7439468 /system/lib/libc.so + bf89a124 b55ba38d /system/lib/libprotobuf-cpp-lite.so + bf89a128 b55ba408 /system/lib/libprotobuf-cpp-lite.so + bf89a12c ffffffdf + bf89a130 0000003d + bf89a134 adfedf00 [anon:libc_malloc] + bf89a138 bf89a158 [stack] + #04 bf89a13c a0cee7f0 /data/app/com.example.app-2/base.apk + bf89a140 b55c1cb0 /system/lib/libprotobuf-cpp-lite.so + bf89a144 bf89a1e4 [stack] +''' + +# Expected value of _TEST_STACK after translation of addresses in the APK +# into offsets into libraries. +_EXPECTED_STACK = r'''stack: + bf89a070 b7439468 /system/lib/libc.so + bf89a074 bf89a1e4 [stack] + bf89a078 932d4000 /data/app/com.example.app-2/base.apk + bf89a07c b73bfbc9 /system/lib/libc.so (pthread_mutex_lock+65) + bf89a080 00000000 + bf89a084 4000671c /dev/ashmem/dalvik-main space 1 (deleted) + bf89a088 932d1d86 /data/app/com.example.app-2/base.apk + bf89a08c b743671c /system/lib/libc.so + bf89a090 b77f8c00 /system/bin/linker + bf89a094 b743cc90 + bf89a098 932d1d4a /data/app/com.example.app-2/base.apk + bf89a09c b73bf271 /system/lib/libc.so (__pthread_internal_find(long)+65) + bf89a0a0 b743cc90 + bf89a0a4 bf89a0b0 [stack] + bf89a0a8 bf89a0b8 [stack] + bf89a0ac 00000008 + ........ ........ + #00 bf89a0b0 00000006 + bf89a0b4 00000002 + bf89a0b8 b743671c /system/lib/libc.so + bf89a0bc b73bf5d9 /system/lib/libc.so (pthread_kill+71) + #01 bf89a0c0 00006937 + bf89a0c4 00006937 + bf89a0c8 00000006 + bf89a0cc b77fd3a9 /system/bin/app_process32 (sigprocmask+141) + bf89a0d0 00000002 + bf89a0d4 bf89a0ec [stack] + bf89a0d8 00000000 + bf89a0dc b743671c /system/lib/libc.so + bf89a0e0 bf89a12c [stack] + bf89a0e4 bf89a1e4 [stack] + bf89a0e8 932d1d4a /data/app/com.example.app-2/base.apk + bf89a0ec b7365206 /system/lib/libc.so (raise+37) + #02 bf89a0f0 b77f8c00 /system/bin/linker + bf89a0f4 00000006 + bf89a0f8 b7439468 /system/lib/libc.so + bf89a0fc b743671c /system/lib/libc.so + bf89a100 bf89a12c [stack] + bf89a104 b743671c /system/lib/libc.so + bf89a108 bf89a12c [stack] + bf89a10c b735e9e5 /system/lib/libc.so (abort+81) + #03 bf89a110 00000006 + bf89a114 bf89a12c [stack] + bf89a118 00000000 + bf89a11c b55a3d3b /system/lib/libprotobuf-cpp-lite.so (google::protobuf::internal::DefaultLogHandler(google::protobuf::LogLevel, char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)+99) + bf89a120 b7439468 /system/lib/libc.so + bf89a124 b55ba38d /system/lib/libprotobuf-cpp-lite.so + bf89a128 b55ba408 /system/lib/libprotobuf-cpp-lite.so + bf89a12c ffffffdf + bf89a130 0000003d + bf89a134 adfedf00 [anon:libc_malloc] + bf89a138 bf89a158 [stack] + #04 bf89a13c a0cee7f0 /data/app/com.example.app-2/base.apk + bf89a140 b55c1cb0 /system/lib/libprotobuf-cpp-lite.so + bf89a144 bf89a1e4 [stack] +''' + +_TEST_BACKTRACE = r'''backtrace: + #00 pc 00084126 /system/lib/libc.so (tgkill+22) + #01 pc 000815d8 /system/lib/libc.so (pthread_kill+70) + #02 pc 00027205 /system/lib/libc.so (raise+36) + #03 pc 000209e4 /system/lib/libc.so (abort+80) + #04 pc 0000cf73 /system/lib/libprotobuf-cpp-lite.so (google::protobuf::internal::LogMessage::Finish()+117) + #05 pc 0000cf8e /system/lib/libprotobuf-cpp-lite.so (google::protobuf::internal::LogFinisher::operator=(google::protobuf::internal::LogMessage&)+26) + #06 pc 0000d27f /system/lib/libprotobuf-cpp-lite.so (google::protobuf::internal::VerifyVersion(int, int, char const*)+574) + #07 pc 007cd236 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #08 pc 000111a9 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0xbfc2000) + #09 pc 00013228 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0xbfc2000) + #10 pc 000131de /data/app/com.google.android.apps.chrome-2/base.apk (offset 0xbfc2000) + #11 pc 007cd2d8 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #12 pc 007cd956 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #13 pc 007c2d4a /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #14 pc 009fc9f1 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #15 pc 009fc8ea /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #16 pc 00561c63 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #17 pc 0106fbdb /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #18 pc 004d7371 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #19 pc 004d8159 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #20 pc 004d7b96 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #21 pc 004da4b6 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #22 pc 005ab66c /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x7daa000) + #23 pc 005afca2 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x7daa000) + #24 pc 0000cae8 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x598d000) + #25 pc 00ce864f /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x7daa000) + #26 pc 00ce8dfa /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x7daa000) + #27 pc 00ce74c6 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x7daa000) + #28 pc 00004616 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x961e000) + #29 pc 00ce8215 /data/app/com.google.android.apps.chrome-2/base.apk (offset 0x7daa000) + #30 pc 0013d8c7 /system/lib/libart.so (art_quick_generic_jni_trampoline+71) + #31 pc 00137c52 /system/lib/libart.so (art_quick_invoke_static_stub+418) + #32 pc 00143651 /system/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+353) + #33 pc 005e06ae /system/lib/libart.so (artInterpreterToCompiledCodeBridge+190) + #34 pc 00328b5d /system/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+445) + #35 pc 0032cfc0 /system/lib/libart.so (bool art::interpreter::DoInvoke<(art::InvokeType)0, false, false>(art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+160) + #36 pc 000fc703 /system/lib/libart.so (art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+29891) + #37 pc 00300af7 /system/lib/libart.so (artInterpreterToInterpreterBridge+188) + #38 pc 00328b5d /system/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+445) + #39 pc 0032cfc0 /system/lib/libart.so (bool art::interpreter::DoInvoke<(art::InvokeType)0, false, false>(art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+160) + #40 pc 000fc703 /system/lib/libart.so (art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+29891) + #41 pc 00300af7 /system/lib/libart.so (artInterpreterToInterpreterBridge+188) + #42 pc 00328b5d /system/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+445) + #43 pc 0032ebf9 /system/lib/libart.so (bool art::interpreter::DoInvoke<(art::InvokeType)2, false, false>(art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+297) + #44 pc 000fc955 /system/lib/libart.so (art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+30485) + #45 pc 00300af7 /system/lib/libart.so (artInterpreterToInterpreterBridge+188) + #46 pc 00328b5d /system/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+445) + #47 pc 0033090c /system/lib/libart.so (bool art::interpreter::DoInvoke<(art::InvokeType)4, false, false>(art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+636) + #48 pc 000fc67f /system/lib/libart.so (art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+29759) + #49 pc 00300700 /system/lib/libart.so (art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame*)+128) + #50 pc 00667c73 /system/lib/libart.so (artQuickToInterpreterBridge+808) + #51 pc 0013d98d /system/lib/libart.so (art_quick_to_interpreter_bridge+77) + #52 pc 7264bc5b /data/dalvik-cache/x86/system@framework@boot.oat (offset 0x1eb2000) +''' + +_EXPECTED_BACKTRACE = r'''backtrace: + #00 pc 00084126 /system/lib/libc.so (tgkill+22) + #01 pc 000815d8 /system/lib/libc.so (pthread_kill+70) + #02 pc 00027205 /system/lib/libc.so (raise+36) + #03 pc 000209e4 /system/lib/libc.so (abort+80) + #04 pc 0000cf73 /system/lib/libprotobuf-cpp-lite.so (google::protobuf::internal::LogMessage::Finish()+117) + #05 pc 0000cf8e /system/lib/libprotobuf-cpp-lite.so (google::protobuf::internal::LogFinisher::operator=(google::protobuf::internal::LogMessage&)+26) + #06 pc 0000d27f /system/lib/libprotobuf-cpp-lite.so (google::protobuf::internal::VerifyVersion(int, int, char const*)+574) + #07 pc 007cd236 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #08 pc 000111a9 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libprotobuf_lite.cr.so (offset 0x1c000) + #09 pc 00013228 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libprotobuf_lite.cr.so (offset 0x1c000) + #10 pc 000131de /data/app/com.google.android.apps.chrome-2/base.apk!lib/libprotobuf_lite.cr.so (offset 0x1c000) + #11 pc 007cd2d8 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #12 pc 007cd956 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #13 pc 007c2d4a /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #14 pc 009fc9f1 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #15 pc 009fc8ea /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #16 pc 00561c63 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #17 pc 0106fbdb /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #18 pc 004d7371 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #19 pc 004d8159 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #20 pc 004d7b96 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #21 pc 004da4b6 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #22 pc 005ab66c /data/app/com.google.android.apps.chrome-2/base.apk!lib/libcontent.cr.so (offset 0xc2d000) + #23 pc 005afca2 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libcontent.cr.so (offset 0xc2d000) + #24 pc 0000cae8 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so (offset 0x90e000) + #25 pc 00ce864f /data/app/com.google.android.apps.chrome-2/base.apk!lib/libcontent.cr.so (offset 0xc2d000) + #26 pc 00ce8dfa /data/app/com.google.android.apps.chrome-2/base.apk!lib/libcontent.cr.so (offset 0xc2d000) + #27 pc 00ce74c6 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libcontent.cr.so (offset 0xc2d000) + #28 pc 00004616 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libembedder.cr.so (offset 0x28000) + #29 pc 00ce8215 /data/app/com.google.android.apps.chrome-2/base.apk!lib/libcontent.cr.so (offset 0xc2d000) + #30 pc 0013d8c7 /system/lib/libart.so (art_quick_generic_jni_trampoline+71) + #31 pc 00137c52 /system/lib/libart.so (art_quick_invoke_static_stub+418) + #32 pc 00143651 /system/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+353) + #33 pc 005e06ae /system/lib/libart.so (artInterpreterToCompiledCodeBridge+190) + #34 pc 00328b5d /system/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+445) + #35 pc 0032cfc0 /system/lib/libart.so (bool art::interpreter::DoInvoke<(art::InvokeType)0, false, false>(art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+160) + #36 pc 000fc703 /system/lib/libart.so (art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+29891) + #37 pc 00300af7 /system/lib/libart.so (artInterpreterToInterpreterBridge+188) + #38 pc 00328b5d /system/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+445) + #39 pc 0032cfc0 /system/lib/libart.so (bool art::interpreter::DoInvoke<(art::InvokeType)0, false, false>(art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+160) + #40 pc 000fc703 /system/lib/libart.so (art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+29891) + #41 pc 00300af7 /system/lib/libart.so (artInterpreterToInterpreterBridge+188) + #42 pc 00328b5d /system/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+445) + #43 pc 0032ebf9 /system/lib/libart.so (bool art::interpreter::DoInvoke<(art::InvokeType)2, false, false>(art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+297) + #44 pc 000fc955 /system/lib/libart.so (art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+30485) + #45 pc 00300af7 /system/lib/libart.so (artInterpreterToInterpreterBridge+188) + #46 pc 00328b5d /system/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+445) + #47 pc 0033090c /system/lib/libart.so (bool art::interpreter::DoInvoke<(art::InvokeType)4, false, false>(art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+636) + #48 pc 000fc67f /system/lib/libart.so (art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+29759) + #49 pc 00300700 /system/lib/libart.so (art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame*)+128) + #50 pc 00667c73 /system/lib/libart.so (artQuickToInterpreterBridge+808) + #51 pc 0013d98d /system/lib/libart.so (art_quick_to_interpreter_bridge+77) + #52 pc 7264bc5b /data/dalvik-cache/x86/system@framework@boot.oat (offset 0x1eb2000) +''' + +_EXPECTED_BACKTRACE_OFFSETS_MAP = { + '/data/app/com.google.android.apps.chrome-2/base.apk!lib/libprotobuf_lite.cr.so': + set([ + 0x1c000 + 0x111a9, + 0x1c000 + 0x13228, + 0x1c000 + 0x131de, + ]), + + '/data/app/com.google.android.apps.chrome-2/base.apk!lib/libchrome.cr.so': + set([ + 0x90e000 + 0x7cd236, + 0x90e000 + 0x7cd2d8, + 0x90e000 + 0x7cd956, + 0x90e000 + 0x7c2d4a, + 0x90e000 + 0x9fc9f1, + 0x90e000 + 0x9fc8ea, + 0x90e000 + 0x561c63, + 0x90e000 + 0x106fbdb, + 0x90e000 + 0x4d7371, + 0x90e000 + 0x4d8159, + 0x90e000 + 0x4d7b96, + 0x90e000 + 0x4da4b6, + 0x90e000 + 0xcae8, + ]), + '/data/app/com.google.android.apps.chrome-2/base.apk!lib/libcontent.cr.so': + set([ + 0xc2d000 + 0x5ab66c, + 0xc2d000 + 0x5afca2, + 0xc2d000 + 0xce864f, + 0xc2d000 + 0xce8dfa, + 0xc2d000 + 0xce74c6, + 0xc2d000 + 0xce8215, + ]), + '/data/app/com.google.android.apps.chrome-2/base.apk!lib/libembedder.cr.so': + set([ + 0x28000 + 0x4616, + ]) +} + +# pylint: enable=line-too-long + +_ONE_MB = 1024 * 1024 +_TEST_SYMBOL_DATA = { + # Regular symbols + 0: 'mock_sym_for_addr_0 [mock_src/libmock1.so.c:0]', + 0x1000: 'mock_sym_for_addr_4096 [mock_src/libmock1.so.c:4096]', + + # Symbols without source file path. + _ONE_MB: 'mock_sym_for_addr_1048576 [??:0]', + _ONE_MB + 0x8234: 'mock_sym_for_addr_1081908 [??:0]', + + # Unknown symbol. + 2 * _ONE_MB: '?? [??:0]', + + # Inlined symbol. + 3 * _ONE_MB: + 'mock_sym_for_addr_3145728_inner [mock_src/libmock1.so.c:3145728]', +} + +@contextlib.contextmanager +def _TempDir(): + dirname = tempfile.mkdtemp() + try: + yield dirname + finally: + shutil.rmtree(dirname) + + +def _TouchFile(path): + # Create parent directories. + try: + os.makedirs(os.path.dirname(path)) + except OSError: + pass + with open(path, 'a'): + os.utime(path, None) + +class MockApkTranslator(object): + """A mock ApkLibraryPathTranslator object used for testing.""" + + # Regex that matches the content of APK native library map files generated + # with apk_lib_dump.py. + _RE_MAP_FILE = re.compile( + r'0x(?P<file_start>[0-9a-f]+)\s+' + + r'0x(?P<file_end>[0-9a-f]+)\s+' + + r'0x(?P<file_size>[0-9a-f]+)\s+' + + r'0x(?P<lib_path>[0-9a-f]+)\s+') + + def __init__(self, test_apk_libs=None): + """Initialize instance. + + Args: + test_apk_libs: Optional list of (file_start, file_end, size, lib_path) + tuples, like _TEST_APK_LIBS for example. This will be used to + implement TranslatePath(). + """ + self._apk_libs = [] + if test_apk_libs: + self._AddLibEntries(test_apk_libs) + + def _AddLibEntries(self, entries): + self._apk_libs = sorted(self._apk_libs + entries, + lambda x, y: cmp(x[0], y[0])) + + def ReadMapFile(self, file_path): + """Read an .apk.native-libs file that was produced with apk_lib_dump.py. + + Args: + file_path: input path to .apk.native-libs file. Its format is + essentially: 0x<start> 0x<end> 0x<size> <library-path> + """ + new_libs = [] + with open(file_path) as f: + for line in f.readlines(): + m = MockApkTranslator._RE_MAP_FILE.match(line) + if m: + file_start = int(m.group('file_start'), 16) + file_end = int(m.group('file_end'), 16) + file_size = int(m.group('file_size'), 16) + lib_path = m.group('lib_path') + # Sanity check + if file_start + file_size != file_end: + logging.warning('%s: Inconsistent (start, end, size) values ' + '(0x%x, 0x%x, 0x%x)', + file_path, file_start, file_end, file_size) + else: + new_libs.append((file_start, file_end, file_size, lib_path)) + + self._AddLibEntries(new_libs) + + def TranslatePath(self, lib_path, lib_offset): + """Translate an APK file path + offset into a library path + offset.""" + min_pos = 0 + max_pos = len(self._apk_libs) + while min_pos < max_pos: + mid_pos = (min_pos + max_pos) / 2 + mid_entry = self._apk_libs[mid_pos] + mid_offset = mid_entry[0] + mid_size = mid_entry[2] + if lib_offset < mid_offset: + max_pos = mid_pos + elif lib_offset >= mid_offset + mid_size: + min_pos = mid_pos + 1 + else: + # Found it + new_path = '%s!lib/%s' % (lib_path, mid_entry[3]) + new_offset = lib_offset - mid_offset + return (new_path, new_offset) + + return lib_path, lib_offset + + +class HostLibraryFinderTest(unittest.TestCase): + + def testEmpty(self): + finder = symbol_utils.HostLibraryFinder() + self.assertIsNone(finder.Find('/data/data/com.example.app-1/lib/libfoo.so')) + self.assertIsNone( + finder.Find('/data/data/com.example.app-1/base.apk!lib/libfoo.so')) + + + def testSimpleDirectory(self): + finder = symbol_utils.HostLibraryFinder() + with _TempDir() as tmp_dir: + host_libfoo_path = os.path.join(tmp_dir, 'libfoo.so') + host_libbar_path = os.path.join(tmp_dir, 'libbar.so') + _TouchFile(host_libfoo_path) + _TouchFile(host_libbar_path) + + finder.AddSearchDir(tmp_dir) + + # Regular library path (extracted at installation by the PackageManager). + # Note that the extraction path has changed between Android releases, + # i.e. it can be /data/app/, /data/data/ or /data/app-lib/ depending + # on the system. + self.assertEqual( + host_libfoo_path, + finder.Find('/data/app-lib/com.example.app-1/lib/libfoo.so')) + + # Verify that the path doesn't really matter + self.assertEqual( + host_libfoo_path, + finder.Find('/whatever/what.apk!lib/libfoo.so')) + + self.assertEqual( + host_libbar_path, + finder.Find('/data/data/com.example.app-1/lib/libbar.so')) + + self.assertIsNone( + finder.Find('/data/data/com.example.app-1/lib/libunknown.so')) + + + def testMultipleDirectories(self): + with _TempDir() as tmp_dir: + # Create the following files: + # <tmp_dir>/aaa/ + # libfoo.so + # <tmp_dir>/bbb/ + # libbar.so + # libfoo.so (this one should never be seen because 'aaa' + # shall be first in the search path list). + # + aaa_dir = os.path.join(tmp_dir, 'aaa') + bbb_dir = os.path.join(tmp_dir, 'bbb') + os.makedirs(aaa_dir) + os.makedirs(bbb_dir) + + host_libfoo_path = os.path.join(aaa_dir, 'libfoo.so') + host_libbar_path = os.path.join(bbb_dir, 'libbar.so') + host_libfoo2_path = os.path.join(bbb_dir, 'libfoo.so') + + _TouchFile(host_libfoo_path) + _TouchFile(host_libbar_path) + _TouchFile(host_libfoo2_path) + + finder = symbol_utils.HostLibraryFinder() + finder.AddSearchDir(aaa_dir) + finder.AddSearchDir(bbb_dir) + + self.assertEqual( + host_libfoo_path, + finder.Find('/data/data/com.example.app-1/lib/libfoo.so')) + + self.assertEqual( + host_libfoo_path, + finder.Find('/data/whatever/base.apk!lib/libfoo.so')) + + self.assertEqual( + host_libbar_path, + finder.Find('/data/data/com.example.app-1/lib/libbar.so')) + + self.assertIsNone( + finder.Find('/data/data/com.example.app-1/lib/libunknown.so')) + + +class ElfSymbolResolverTest(unittest.TestCase): + + def testCreation(self): + resolver = symbol_utils.ElfSymbolResolver( + addr2line_path_for_tests=_MOCK_A2L_PATH) + self.assertTrue(resolver) + + def testWithSimpleOffsets(self): + resolver = symbol_utils.ElfSymbolResolver( + addr2line_path_for_tests=_MOCK_A2L_PATH) + resolver.SetAndroidAbi('ignored-abi') + + for addr, expected_sym in _TEST_SYMBOL_DATA.iteritems(): + self.assertEqual(resolver.FindSymbolInfo('/some/path/libmock1.so', addr), + expected_sym) + + def testWithPreResolvedSymbols(self): + resolver = symbol_utils.ElfSymbolResolver( + addr2line_path_for_tests=_MOCK_A2L_PATH) + resolver.SetAndroidAbi('ignored-abi') + resolver.AddLibraryOffsets('/some/path/libmock1.so', + _TEST_SYMBOL_DATA.keys()) + + resolver.DisallowSymbolizerForTesting() + + for addr, expected_sym in _TEST_SYMBOL_DATA.iteritems(): + sym_info = resolver.FindSymbolInfo('/some/path/libmock1.so', addr) + self.assertIsNotNone(sym_info, 'None symbol info for addr %x' % addr) + self.assertEqual( + sym_info, expected_sym, + 'Invalid symbol info for addr %x [%s] expected [%s]' % ( + addr, sym_info, expected_sym)) + + +class MemoryMapTest(unittest.TestCase): + + def testCreation(self): + mem_map = symbol_utils.MemoryMap('test-abi32') + self.assertIsNone(mem_map.FindSectionForAddress(0)) + + def testParseLines(self): + mem_map = symbol_utils.MemoryMap('test-abi32') + mem_map.ParseLines(_TEST_MEMORY_MAP.splitlines()) + for exp_addr, exp_size, exp_path, exp_offset in _TEST_MEMORY_MAP_SECTIONS: + text = '(addr:%x, size:%x, path:%s, offset=%x)' % ( + exp_addr, exp_size, exp_path, exp_offset) + + t = mem_map.FindSectionForAddress(exp_addr) + self.assertTrue(t, 'Could not find %s' % text) + self.assertEqual(t.address, exp_addr) + self.assertEqual(t.size, exp_size) + self.assertEqual(t.offset, exp_offset) + self.assertEqual(t.path, exp_path) + + def testTranslateLine(self): + android_abi = 'test-abi' + apk_translator = MockApkTranslator(_TEST_APK_LIBS) + mem_map = symbol_utils.MemoryMap(android_abi) + for line, expected_line in zip(_TEST_MEMORY_MAP.splitlines(), + _EXPECTED_TEST_MEMORY_MAP.splitlines()): + self.assertEqual(mem_map.TranslateLine(line, apk_translator), + expected_line) + +class StackTranslatorTest(unittest.TestCase): + + def testSimpleStack(self): + android_abi = 'test-abi32' + mem_map = symbol_utils.MemoryMap(android_abi) + mem_map.ParseLines(_TEST_MEMORY_MAP) + apk_translator = MockApkTranslator(_TEST_APK_LIBS) + stack_translator = symbol_utils.StackTranslator(android_abi, mem_map, + apk_translator) + input_stack = _TEST_STACK.splitlines() + expected_stack = _EXPECTED_STACK.splitlines() + self.assertEqual(len(input_stack), len(expected_stack)) + for stack_line, expected_line in zip(input_stack, expected_stack): + new_line = stack_translator.TranslateLine(stack_line) + self.assertEqual(new_line, expected_line) + + +class MockSymbolResolver(symbol_utils.SymbolResolver): + + # A regex matching a symbol definition as it appears in a test symbol file. + # Format is: <hex-offset> <whitespace> <symbol-string> + _RE_SYMBOL_DEFINITION = re.compile( + r'(?P<offset>[0-9a-f]+)\s+(?P<symbol>.*)') + + def __init__(self): + super(MockSymbolResolver, self).__init__() + self._map = collections.defaultdict(dict) + + def AddTestLibrarySymbols(self, lib_name, offsets_map): + """Add a new test entry for a given library name. + + Args: + lib_name: Library name (e.g. 'libfoo.so') + offsets_map: A mapping from offsets to symbol info strings. + """ + self._map[lib_name] = offsets_map + + def ReadTestFile(self, file_path, lib_name): + """Read a single test symbol file, matching a given library. + + Args: + file_path: Input file path. + lib_name: Library name these symbols correspond to (e.g. 'libfoo.so') + """ + with open(file_path) as f: + for line in f.readlines(): + line = line.rstrip() + m = MockSymbolResolver._RE_SYMBOL_DEFINITION.match(line) + if m: + offset = int(m.group('offset')) + symbol = m.group('symbol') + self._map[lib_name][offset] = symbol + + def ReadTestFilesInDir(self, dir_path, file_suffix): + """Read all symbol test files in a given directory. + + Args: + dir_path: Directory path. + file_suffix: File suffix used to detect test symbol files. + """ + for filename in os.listdir(dir_path): + if filename.endswith(file_suffix): + lib_name = filename[:-len(file_suffix)] + self.ReadTestFile(os.path.join(dir_path, filename), lib_name) + + def FindSymbolInfo(self, device_path, device_offset): + """Implement SymbolResolver.FindSymbolInfo.""" + lib_name = os.path.basename(device_path) + offsets = self._map.get(lib_name) + if not offsets: + return None + + return offsets.get(device_offset) + + +class BacktraceTranslatorTest(unittest.TestCase): + + def testEmpty(self): + android_abi = 'test-abi' + apk_translator = MockApkTranslator() + backtrace_translator = symbol_utils.BacktraceTranslator(android_abi, + apk_translator) + self.assertTrue(backtrace_translator) + + def testFindLibraryOffsets(self): + android_abi = 'test-abi' + apk_translator = MockApkTranslator(_TEST_APK_LIBS) + backtrace_translator = symbol_utils.BacktraceTranslator(android_abi, + apk_translator) + input_backtrace = _EXPECTED_BACKTRACE.splitlines() + expected_lib_offsets_map = _EXPECTED_BACKTRACE_OFFSETS_MAP + offset_map = backtrace_translator.FindLibraryOffsets(input_backtrace) + for lib_path, offsets in offset_map.iteritems(): + self.assertTrue(lib_path in expected_lib_offsets_map, + '%s is not in expected library-offsets map!' % lib_path) + sorted_offsets = sorted(offsets) + sorted_expected_offsets = sorted(expected_lib_offsets_map[lib_path]) + self.assertEqual(sorted_offsets, sorted_expected_offsets, + '%s has invalid offsets %s expected %s' % ( + lib_path, sorted_offsets, sorted_expected_offsets)) + + def testTranslateLine(self): + android_abi = 'test-abi' + apk_translator = MockApkTranslator(_TEST_APK_LIBS) + backtrace_translator = symbol_utils.BacktraceTranslator(android_abi, + apk_translator) + input_backtrace = _TEST_BACKTRACE.splitlines() + expected_backtrace = _EXPECTED_BACKTRACE.splitlines() + self.assertEqual(len(input_backtrace), len(expected_backtrace)) + for trace_line, expected_line in zip(input_backtrace, expected_backtrace): + line = backtrace_translator.TranslateLine(trace_line, + MockSymbolResolver()) + self.assertEqual(line, expected_line) + + +if __name__ == '__main__': + unittest.main()
diff --git a/build/android/pylib/utils/google_storage_helper.py b/build/android/pylib/utils/google_storage_helper.py index 3101d71..d184810 100644 --- a/build/android/pylib/utils/google_storage_helper.py +++ b/build/android/pylib/utils/google_storage_helper.py
@@ -79,10 +79,7 @@ cmd = [_GSUTIL_PATH, '-q', 'stat', gs_path] return_code = cmd_helper.RunCmd(cmd) - if return_code == 0: - return True - else: - return False + return return_code == 0 # TODO(jbudorick): Delete this function. Only one user of it.
diff --git a/build/android/pylib/utils/logdog_helper.py b/build/android/pylib/utils/logdog_helper.py index 58fe781..68a7ba5 100644 --- a/build/android/pylib/utils/logdog_helper.py +++ b/build/android/pylib/utils/logdog_helper.py
@@ -92,4 +92,3 @@ def get_logdog_client(): logging.info('Getting logdog client.') return bootstrap.ButlerBootstrap.probe().stream_client() -
diff --git a/build/android/pylib/valgrind_tools.py b/build/android/pylib/valgrind_tools.py index 3dc2488..4c27b08 100644 --- a/build/android/pylib/valgrind_tools.py +++ b/build/android/pylib/valgrind_tools.py
@@ -127,4 +127,3 @@ print 'Unknown tool %s, available tools: %s' % ( tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))) sys.exit(1) -
diff --git a/build/android/pylintrc b/build/android/pylintrc index 8005a5d..2a721bf2 100644 --- a/build/android/pylintrc +++ b/build/android/pylintrc
@@ -4,7 +4,7 @@ [MESSAGES CONTROL] -disable=abstract-class-not-used,bad-continuation,bad-indentation,duplicate-code,fixme,invalid-name,locally-disabled,locally-enabled,missing-docstring,star-args,too-few-public-methods,too-many-arguments,too-many-branches,too-many-instance-attributes,too-many-lines,too-many-locals,too-many-public-methods,too-many-statements, +disable=abstract-class-not-used,bad-continuation,bad-indentation,duplicate-code,fixme,invalid-name,locally-disabled,locally-enabled,missing-docstring,star-args,too-few-public-methods,too-many-arguments,too-many-branches,too-many-instance-attributes,too-many-lines,too-many-locals,too-many-public-methods,too-many-statements,wrong-import-position [REPORTS]
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index a83d9ab..8512acc 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -25,6 +25,7 @@ # See http://crbug.com/724524 and https://bugs.python.org/issue7980. import _strptime # pylint: disable=unused-import +# pylint: disable=ungrouped-imports from pylib.constants import host_paths if host_paths.DEVIL_PATH not in sys.path: @@ -49,7 +50,6 @@ from py_utils import contextlib_ext - _DEVIL_STATIC_CONFIG_FILE = os.path.abspath(os.path.join( host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'devil_config.json')) @@ -212,10 +212,12 @@ def ProcessCommonOptions(args): """Processes and handles all common options.""" run_tests_helper.SetLogLevel(args.verbose_count, add_handler=False) + # pylint: disable=redefined-variable-type if args.verbose_count > 0: handler = logging_utils.ColorStreamHandler() else: handler = logging.StreamHandler(sys.stdout) + # pylint: enable=redefined-variable-type handler.setFormatter(run_tests_helper.CustomFormatter()) logging.getLogger().addHandler(handler) @@ -429,6 +431,7 @@ split_arg = arg.split(',') if len(split_arg) != 2: raise argparse.ArgumentError( + arg, 'Expected two comma-separated strings for --replace-system-package, ' 'received %d' % len(split_arg)) PackageReplacement = collections.namedtuple('PackageReplacement',
diff --git a/build/check_gn_headers_whitelist.txt b/build/check_gn_headers_whitelist.txt index 9547f35..d570a03f 100644 --- a/build/check_gn_headers_whitelist.txt +++ b/build/check_gn_headers_whitelist.txt
@@ -51,7 +51,6 @@ chrome/browser/download/download_file_icon_extractor.h chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.h chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h -chrome/browser/extensions/api/socket/mock_tcp_client_socket.h chrome/browser/mac/bluetooth_utility.h chrome/browser/media/router/mojo/media_route_provider_util_win.h chrome/browser/media/webrtc/desktop_media_list_ash.h
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index 6aea38e..7af1b221 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//base/android/linker/config.gni") +import("//base/android/proguard/proguard.gni") import("//build/config/android/rules.gni") import("//build/config/locales.gni") import("//build/config/android/extract_unwind_tables.gni") @@ -13,9 +14,6 @@ import("channel.gni") declare_args() { - # Enables ProGuard obfuscation of Chromium packages. - enable_proguard_obfuscation = true - # Enable multidex in release builds. multidex_in_release = false } @@ -105,7 +103,7 @@ [ "//base/android/proguard/enable_obfuscation.flags" ] } else { proguard_configs += - [ "//base/android/proguard/disable_chromium_obfuscation.flags" ] + [ "//base/android/proguard/disable_all_obfuscation.flags" ] } }
diff --git a/chrome/android/java/res/layout/toolbar_phone_common.xml b/chrome/android/java/res/layout/toolbar_phone_common.xml index e136f91..f456850 100644 --- a/chrome/android/java/res/layout/toolbar_phone_common.xml +++ b/chrome/android/java/res/layout/toolbar_phone_common.xml
@@ -44,23 +44,27 @@ android:layout_width="4dp" android:layout_height="match_parent" /> - <ViewStub - android:id="@+id/experimental_button_stub" - android:inflatedId="@+id/experimental_toolbar_button" - android:layout="@layout/experimental_toolbar_button" - style="@style/ToolbarButton" - android:paddingStart="8dp" - android:layout_gravity="top" - android:visibility="gone" /> + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="top" > - <ViewStub - android:id="@+id/incognito_button_stub" - android:inflatedId="@+id/incognito_button" - android:layout="@layout/toolbar_phone_incognito_button" - style="@style/ToolbarButton" - android:layout_gravity="top" - android:contentDescription="@string/accessibility_tabstrip_btn_incognito_toggle_standard" - android:visibility="gone" /> + <ViewStub + android:id="@+id/experimental_button_stub" + android:inflatedId="@+id/experimental_toolbar_button" + android:layout="@layout/experimental_toolbar_button" + style="@style/ToolbarButton" + android:paddingStart="8dp" + android:visibility="gone" /> + + <ViewStub + android:id="@+id/incognito_button_stub" + android:inflatedId="@+id/incognito_button" + android:layout="@layout/toolbar_phone_incognito_button" + style="@style/ToolbarButton" + android:contentDescription="@string/accessibility_tabstrip_btn_incognito_toggle_standard" + android:visibility="gone" /> + </FrameLayout> <ImageButton android:id="@+id/tab_switcher_button" style="@style/ToolbarButton"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java index 13a4a44..fd948bb77 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java
@@ -217,9 +217,9 @@ */ private void prefetchDnsForUrlInBackground(final String url) { mDnsRequestsInFlight.add(url); - new AsyncTask<String, Void, Void>() { + new AsyncTask<Void, Void, Void>() { @Override - protected Void doInBackground(String... params) { + protected Void doInBackground(Void... params) { try (TraceEvent e = TraceEvent.scoped("WarmupManager.prefetchDnsForUrlInBackground")) { InetAddress.getByName(new URL(url).getHost()); @@ -242,7 +242,8 @@ maybePreconnectUrlAndSubResources(profile, url); } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url); + } + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } /** Launches a background DNS query for a given URL if the data reduction proxy is not in use.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java index dae4a74d..2ce8121 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java
@@ -23,7 +23,7 @@ public abstract class AsyncFeedbackSourceAdapter<Result> implements AsyncFeedbackSource { private Worker mWorker; - private class Worker extends AsyncTask<Context, Void, Result> { + private class Worker extends AsyncTask<Void, Void, Result> { private final Runnable mCallback; public Worker(Runnable callback) { @@ -32,14 +32,13 @@ // AsyncTask implementation. @Override - protected Result doInBackground(Context... params) { - return AsyncFeedbackSourceAdapter.this.doInBackground(params[0]); + protected Result doInBackground(Void... params) { + return AsyncFeedbackSourceAdapter.this.doInBackground( + ContextUtils.getApplicationContext()); } @Override protected void onPostExecute(Result result) { - super.onPostExecute(result); - mCallback.run(); } } @@ -75,7 +74,6 @@ public final void start(Runnable callback) { if (mWorker != null) return; mWorker = new Worker(callback); - mWorker.executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, ContextUtils.getApplicationContext()); + mWorker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java index bb9aafb4..45a70997 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java
@@ -66,12 +66,18 @@ * Class used for writing logs to external log file asynchronously to prevent violating strict * mode during test. */ - private class LogTask extends AsyncTask<String, Void, Void> { + private class LogTask extends AsyncTask<Void, Void, Void> { + final String mLogString; + + LogTask(String logString) { + mLogString = logString; + } + @Override - protected Void doInBackground(String... strings) { + protected Void doInBackground(Void... params) { try { synchronized (mLogOutput) { - mLogOutput.write(strings[0]); + mLogOutput.write(mLogString); mLogOutput.flush(); } } catch (IOException e) { @@ -198,9 +204,9 @@ new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.getDefault()); String logString = formatter.format(date) + ": " + sourceTag + " | " + message + System.getProperty("line.separator"); - LogTask logTask = new LogTask(); + LogTask logTask = new LogTask(logString); Log.d(TAG, logString); - logTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, logString); + logTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); } public void closeLog() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java index 123f0d3b..656b023 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java
@@ -17,18 +17,21 @@ /** * A worker task to scale bitmaps in the background. */ -class BitmapScalerTask extends AsyncTask<Bitmap, Void, Bitmap> { +class BitmapScalerTask extends AsyncTask<Void, Void, Bitmap> { private final LruCache<String, Bitmap> mCache; private final String mFilePath; private final int mSize; + private final Bitmap mBitmap; /** * A BitmapScalerTask constructor. */ - public BitmapScalerTask(LruCache<String, Bitmap> cache, String filePath, int size) { + public BitmapScalerTask( + LruCache<String, Bitmap> cache, String filePath, int size, Bitmap bitmap) { mCache = cache; mFilePath = filePath; mSize = size; + mBitmap = bitmap; } /** @@ -37,13 +40,13 @@ * @return A sorted list of images (by last-modified first). */ @Override - protected Bitmap doInBackground(Bitmap... bitmaps) { + protected Bitmap doInBackground(Void... params) { assert !ThreadUtils.runningOnUiThread(); if (isCancelled()) return null; long begin = SystemClock.elapsedRealtime(); - Bitmap bitmap = BitmapUtils.scale(bitmaps[0], mSize, false); + Bitmap bitmap = BitmapUtils.scale(mBitmap, mSize, false); long scaleTime = SystemClock.elapsedRealtime() - begin; RecordHistogram.recordTimesHistogram( "Android.PhotoPicker.BitmapScalerTask", scaleTime, TimeUnit.MILLISECONDS);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java index 72a39c69..ef22a284 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java
@@ -55,8 +55,9 @@ if (mCategoryView.getLowResBitmaps().get(filePath) == null) { Resources resources = mItemView.getContext().getResources(); new BitmapScalerTask(mCategoryView.getLowResBitmaps(), filePath, - resources.getDimensionPixelSize(R.dimen.photo_picker_grainy_thumbnail_size)) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, bitmap); + resources.getDimensionPixelSize(R.dimen.photo_picker_grainy_thumbnail_size), + bitmap) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } if (!TextUtils.equals(mBitmapDetails.getFilePath(), filePath)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java index 4803507..8da8a34c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -868,8 +868,12 @@ // We set the incognito toggle button's visibility from GONE to VISIBLE when the tab // switcher starts to open, but we don't want this to affect the Omnibox's size during the // animation, so we have to make an adjustment here. + // However, if the experimental button is showing it sits in a FrameLayout with the + // incognito button and the omnibox will be appropriately sized without an explicit + // adjustment. int incognitoButtonWidth = 0; - if (mIncognitoToggleButton != null && mIncognitoToggleButton.getVisibility() == VISIBLE) { + if (mIncognitoToggleButton != null && mIncognitoToggleButton.getVisibility() == VISIBLE + && (mExperimentalButton == null || mExperimentalButton.getVisibility() == GONE)) { incognitoButtonWidth += mIncognitoToggleButton.getMeasuredWidth(); } return Math.max(mToolbarSidePadding, @@ -1392,10 +1396,15 @@ // Draw the experimental button if necessary. if (mExperimentalButton != null && mExperimentalButton.getVisibility() != View.GONE) { + canvas.save(); + translateCanvasToView(mToolbarButtonsContainer, mExperimentalButton, canvas); + previousAlpha = mExperimentalButton.getAlpha(); mExperimentalButton.setAlpha(previousAlpha * floatAlpha); drawChild(canvas, mExperimentalButton, SystemClock.uptimeMillis()); mExperimentalButton.setAlpha(previousAlpha); + + canvas.restore(); } // Draw the tab stack button and associated text.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrShellImpl.java index 94467d3..3ac2c5c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrShellImpl.java
@@ -164,12 +164,6 @@ mActivity.getFindToolbarManager().hideToolbar(); } - if (ChromeFeatureList.isEnabled(ChromeFeatureList.VR_BROWSING_NATIVE_ANDROID_UI)) { - mNonVrUiWidgetFactory = UiWidgetFactory.getInstance(); - UiWidgetFactory.setInstance( - new VrUiWidgetFactory(this, mActivity.getModalDialogManager())); - } - // This overrides the default intent created by GVR to return to Chrome when the DON flow // is triggered by resuming the GvrLayout, which is the usual way Daydream apps enter VR. // See VrShellDelegate#getEnterVrPendingIntent for why we need to do this. @@ -200,6 +194,13 @@ if (mVrBrowsingEnabled) injectVrHostedUiView(); + // This has to happen after VrModalDialogManager is created. + if (ChromeFeatureList.isEnabled(ChromeFeatureList.VR_BROWSING_NATIVE_ANDROID_UI)) { + mNonVrUiWidgetFactory = UiWidgetFactory.getInstance(); + UiWidgetFactory.setInstance( + new VrUiWidgetFactory(this, mActivity.getModalDialogManager())); + } + mTabRedirectHandler = new TabRedirectHandler(mActivity) { @Override public boolean shouldStayInChrome(boolean hasExternalProtocol) {
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java index a10297901..695ccbb 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java
@@ -71,7 +71,7 @@ try { String hostPackage = getHostBrowserPackageName(context); return context.getApplicationContext().createPackageContext( - hostPackage, Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE); + hostPackage, 0); } catch (NameNotFoundException e) { e.printStackTrace(); }
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index d3d5d68a..7d4f3f8c 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -961,6 +961,9 @@ </message> </if> <if expr="chromeos"> + <message name="IDS_UPDATE_RECOMMENDED_DIALOG_TITLE" desc="The window title for the Update Recommended dialog."> + Restart Chromium OS + </message> <message name="IDS_UPDATE_RECOMMENDED" desc="The main text of the Update Recommended dialog."> Chromium OS needs to be restarted to apply the update. </message> @@ -1187,40 +1190,79 @@ </message> </if> <!-- Relaunch notification bubble and dialog. --> - <if expr="not is_android and not chromeos"> - <message name="IDS_RELAUNCH_RECOMMENDED_TITLE" desc="The title of a dialog that tells users that a browser relaunch is recommended for an update available for some number of days."> - {0, plural, - =0 {A Chromium update is available} - =1 {A Chromium update is available} - other {A Chromium update has been available for # days}} - </message> - <message name="IDS_RELAUNCH_RECOMMENDED_BODY" desc="The body text of a dialog that tells users that a browser relaunch is recommended for an update."> - Your administrator asks that you relaunch Chromium to apply this update - </message> - <message name="IDS_RELAUNCH_REQUIRED_TITLE_DAYS" desc="The title of a dialog that tells users the browser must be relaunched within two or more days."> - {0, plural, - =1 {Relaunch Chromium within a day} - other {Relaunch Chromium within # days}} - </message> - <message name="IDS_RELAUNCH_REQUIRED_TITLE_HOURS" desc="The title of a dialog that tells users the browser must be relaunched within one or more hours."> - {0, plural, - =1 {Chromium will relaunch in an hour} - other {Chromium will relaunch in # hours}} - </message> - <message name="IDS_RELAUNCH_REQUIRED_TITLE_MINUTES" desc="The title of a dialog that tells users the browser must be relaunched within one or more minutes."> - {0, plural, - =1 {Chromium will relaunch in 1 minute} - other {Chromium will relaunch in # minutes}} - </message> - <message name="IDS_RELAUNCH_REQUIRED_TITLE_SECONDS" desc="The title of a dialog that tells users the browser must be relaunched within some number of seconds."> - {0, plural, - =0 {Chromium will relaunch now} - =1 {Chromium will relaunch in 1 second} - other {Chromium will relaunch in # seconds}} - </message> - <message name="IDS_RELAUNCH_REQUIRED_BODY" desc="The body text of a dialog that tells users the browser must be relaunched."> - Your administrator requires that you relaunch Chromium to apply an update - </message> + <if expr="not is_android"> + <if expr="not chromeos"> + <then> + <message name="IDS_RELAUNCH_RECOMMENDED_TITLE" desc="The title of a dialog that tells users that a browser relaunch is recommended for an update available for some number of days."> + {0, plural, + =0 {A Chromium update is available} + =1 {A Chromium update is available} + other {A Chromium update has been available for # days}} + </message> + <message name="IDS_RELAUNCH_RECOMMENDED_BODY" desc="The body text of a dialog that tells users that a browser relaunch is recommended for an update."> + Your administrator asks that you relaunch Chromium to apply this update + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_DAYS" desc="The title of a dialog that tells users the browser must be relaunched within two or more days."> + {0, plural, + =1 {Relaunch Chromium within a day} + other {Relaunch Chromium within # days}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_HOURS" desc="The title of a dialog that tells users the browser must be relaunched within one or more hours."> + {0, plural, + =1 {Chromium will relaunch in an hour} + other {Chromium will relaunch in # hours}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_MINUTES" desc="The title of a dialog that tells users the browser must be relaunched within one or more minutes."> + {0, plural, + =1 {Chromium will relaunch in 1 minute} + other {Chromium will relaunch in # minutes}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_SECONDS" desc="The title of a dialog that tells users the browser must be relaunched within some number of seconds."> + {0, plural, + =0 {Chromium will relaunch now} + =1 {Chromium will relaunch in 1 second} + other {Chromium will relaunch in # seconds}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_BODY" desc="The body text of a dialog that tells users the browser must be relaunched."> + Your administrator requires that you relaunch Chromium to apply an update + </message> + </then> + <else> + <message name="IDS_RELAUNCH_RECOMMENDED_TITLE" desc="The title of a dialog that tells users that a device restart is recommended for an update available for some number of days."> + {0, plural, + =0 {A Chromium OS update is available} + =1 {A Chromium OS update is available} + other {A Chromium OS update has been available for # days}} + </message> + <message name="IDS_RELAUNCH_RECOMMENDED_BODY" desc="The body text of a dialog that tells users that a device restart is recommended for an update."> + Your administrator asks that you restart Chromium OS to apply this update + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_DAYS" desc="The title of a dialog that tells users the device must be restarted within two or more days."> + {0, plural, + =1 {Restart Chromium OS within a day} + other {Restart Chromium OS within # days}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_HOURS" desc="The title of a dialog that tells users the device must be restarted within one or more hours."> + {0, plural, + =1 {Chromium OS will restart in an hour} + other {Chromium OS will restart in # hours}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_MINUTES" desc="The title of a dialog that tells users the device must be restarted within one or more minutes."> + {0, plural, + =1 {Chromium OS will restart in 1 minute} + other {Chromium OS will restart in # minutes}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_SECONDS" desc="The title of a dialog that tells users the device must be restarted within some number of seconds."> + {0, plural, + =0 {Chromium OS will restart now} + =1 {Chromium OS will restart in 1 second} + other {Chromium OS will restart in # seconds}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_BODY" desc="The body text of a dialog that tells users the device must be restarted."> + Your administrator requires that you restart Chromium OS to apply an update + </message> + </else> + </if> </if> <!-- Chroium launch blocking dialog. --> <if expr="not is_android and not chromeos">
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 7c9aa1a..7356de0 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -9018,10 +9018,17 @@ Upload </message> <!-- Relaunch notification bubble and dialog. --> - <if expr="not is_android and not chromeos"> - <message name="IDS_RELAUNCH_ACCEPT_BUTTON" desc="The text in the accept button of a dialog that causes the browser to be relaunched immediately."> - Relaunch now - </message> + <if expr="not is_android"> + <if expr="not chromeos"> + <message name="IDS_RELAUNCH_ACCEPT_BUTTON" desc="The text in the accept button of a dialog that causes the browser to be relaunched immediately."> + Relaunch now + </message> + </if> + <if expr="chromeos"> + <message name="IDS_RELAUNCH_ACCEPT_BUTTON" desc="The text in the accept button of a dialog that causes the device to be restarted immediately."> + Restart now + </message> + </if> <message name="IDS_RELAUNCH_REQUIRED_CANCEL_BUTTON" desc="The text in the cancel button that dismisses a dialog telling users the browser must be relaunched."> Got it </message>
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 4552b231..ec8b999c9 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -979,6 +979,9 @@ </message> </if> <if expr="chromeos"> + <message name="IDS_UPDATE_RECOMMENDED_DIALOG_TITLE" desc="The window title for the Update Recommended dialog."> + Restart Chrome OS + </message> <message name="IDS_UPDATE_RECOMMENDED" desc="The main text of the Update Recommended dialog."> Chrome OS needs to be restarted to apply the update. </message> @@ -1205,40 +1208,79 @@ </message> </if> <!-- Relaunch notification bubble and dialog. --> - <if expr="not is_android and not chromeos"> - <message name="IDS_RELAUNCH_RECOMMENDED_TITLE" desc="The title of a dialog that tells users that a browser relaunch is recommended for an update available for some number of days."> - {0, plural, - =0 {A Chrome update is available} - =1 {A Chrome update is available} - other {A Chrome update has been available for # days}} - </message> - <message name="IDS_RELAUNCH_RECOMMENDED_BODY" desc="The body text of a dialog that tells users that a browser relaunch is recommended for an update."> - Your administrator asks that you relaunch Chrome to apply this update - </message> - <message name="IDS_RELAUNCH_REQUIRED_TITLE_DAYS" desc="The title of a dialog that tells users the browser must be relaunched within two or more days."> - {0, plural, - =1 {Relaunch Chrome within a day} - other {Relaunch Chrome within # days}} - </message> - <message name="IDS_RELAUNCH_REQUIRED_TITLE_HOURS" desc="The title of a dialog that tells users the browser must be relaunched within one or more hours."> - {0, plural, - =1 {Chrome will relaunch in an hour} - other {Chrome will relaunch in # hours}} - </message> - <message name="IDS_RELAUNCH_REQUIRED_TITLE_MINUTES" desc="The title of a dialog that tells users the browser must be relaunched within one or more minutes."> - {0, plural, - =1 {Chrome will relaunch in 1 minute} - other {Chrome will relaunch in # minutes}} - </message> - <message name="IDS_RELAUNCH_REQUIRED_TITLE_SECONDS" desc="The title of a dialog that tells users the browser must be relaunched within some number of seconds."> - {0, plural, - =0 {Chrome will relaunch now} - =1 {Chrome will relaunch in 1 second} - other {Chrome will relaunch in # seconds}} - </message> - <message name="IDS_RELAUNCH_REQUIRED_BODY" desc="The body text of a dialog that tells users the browser must be relaunched."> - Your administrator requires that you relaunch Chrome to apply an update - </message> + <if expr="not is_android"> + <if expr="not chromeos"> + <then> + <message name="IDS_RELAUNCH_RECOMMENDED_TITLE" desc="The title of a dialog that tells users that a browser relaunch is recommended for an update available for some number of days."> + {0, plural, + =0 {A Chrome update is available} + =1 {A Chrome update is available} + other {A Chrome update has been available for # days}} + </message> + <message name="IDS_RELAUNCH_RECOMMENDED_BODY" desc="The body text of a dialog that tells users that a browser relaunch is recommended for an update."> + Your administrator asks that you relaunch Chrome to apply this update + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_DAYS" desc="The title of a dialog that tells users the browser must be relaunched within two or more days."> + {0, plural, + =1 {Relaunch Chrome within a day} + other {Relaunch Chrome within # days}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_HOURS" desc="The title of a dialog that tells users the browser must be relaunched within one or more hours."> + {0, plural, + =1 {Chrome will relaunch in an hour} + other {Chrome will relaunch in # hours}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_MINUTES" desc="The title of a dialog that tells users the browser must be relaunched within one or more minutes."> + {0, plural, + =1 {Chrome will relaunch in 1 minute} + other {Chrome will relaunch in # minutes}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_SECONDS" desc="The title of a dialog that tells users the browser must be relaunched within some number of seconds."> + {0, plural, + =0 {Chrome will relaunch now} + =1 {Chrome will relaunch in 1 second} + other {Chrome will relaunch in # seconds}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_BODY" desc="The body text of a dialog that tells users the browser must be relaunched."> + Your administrator requires that you relaunch Chrome to apply an update + </message> + </then> + <else> + <message name="IDS_RELAUNCH_RECOMMENDED_TITLE" desc="The title of a dialog that tells users that a device restart is recommended for an update available for some number of days."> + {0, plural, + =0 {A Chrome OS update is available} + =1 {A Chrome OS update is available} + other {A Chrome OS update has been available for # days}} + </message> + <message name="IDS_RELAUNCH_RECOMMENDED_BODY" desc="The body text of a dialog that tells users that a device restart is recommended for an update."> + Your administrator asks that you restart Chrome OS to apply this update + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_DAYS" desc="The title of a dialog that tells users the device must be restarted within two or more days."> + {0, plural, + =1 {Restart Chrome OS within a day} + other {Restart Chrome OS within # days}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_HOURS" desc="The title of a dialog that tells users the device must be restarted within one or more hours."> + {0, plural, + =1 {Chrome OS will restart in an hour} + other {Chrome OS will restart in # hours}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_MINUTES" desc="The title of a dialog that tells users the device must be restarted within one or more minutes."> + {0, plural, + =1 {Chrome OS will restart in 1 minute} + other {Chrome OS will restart in # minutes}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_TITLE_SECONDS" desc="The title of a dialog that tells users the device must be restarted within some number of seconds."> + {0, plural, + =0 {Chrome OS will restart now} + =1 {Chrome OS will restart in 1 second} + other {Chrome OS will restart in # seconds}} + </message> + <message name="IDS_RELAUNCH_REQUIRED_BODY" desc="The body text of a dialog that tells users the device must be restarted."> + Your administrator requires that you restart Chrome OS to apply an update + </message> + </else> + </if> </if> <!-- Chrome launch blocking dialog. -->
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index ddb5ad4b..0aaade1f2 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1678,6 +1678,11 @@ flag_descriptions::kNewPasswordFormParsingName, flag_descriptions::kNewPasswordFormParsingDescription, kOsAll, FEATURE_VALUE_TYPE(password_manager::features::kNewPasswordFormParsing)}, + {"new-password-form-parsing-for-saving", + flag_descriptions::kNewPasswordFormParsingForSavingName, + flag_descriptions::kNewPasswordFormParsingForSavingDescription, kOsAll, + FEATURE_VALUE_TYPE( + password_manager::features::kNewPasswordFormParsingForSaving)}, {"enable-show-autofill-signatures", flag_descriptions::kShowAutofillSignaturesName, flag_descriptions::kShowAutofillSignaturesDescription, kOsAll,
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device.cc b/chrome/browser/android/vr/arcore_device/arcore_device.cc index d49ff76..0b1b6f9e 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_device.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_device.cc
@@ -277,7 +277,7 @@ } void ARCoreDevice::OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { TRACE_EVENT0("gpu", __FUNCTION__); DCHECK(IsOnMainThread()); // We should not be able to reach this point if we are not initialized. @@ -312,7 +312,7 @@ void ARCoreDevice::RequestHitTest( mojom::XRRayPtr ray, - mojom::VRMagicWindowProvider::RequestHitTestCallback callback) { + mojom::XREnviromentIntegrationProvider::RequestHitTestCallback callback) { DCHECK(IsOnMainThread()); PostTaskToGlThread(base::BindOnce( @@ -441,16 +441,19 @@ &ARCoreGl::Resume, arcore_gl_thread_->GetARCoreGl()->GetWeakPtr())); } - // TODO(offenwanger) When the XRMagicWindowProvider or equivalent is returned - // here, clean out this dummy code. - auto connection = mojom::XRPresentationConnection::New(); - mojom::VRSubmitFrameClientPtr submit_client; - connection->client_request = mojo::MakeRequest(&submit_client); - mojom::VRPresentationProviderPtr provider; - mojo::MakeRequest(&provider); - connection->provider = provider.PassInterface(); - connection->transport_options = mojom::VRDisplayFrameTransportOptions::New(); - std::move(callback).Run(std::move(connection), nullptr); + auto session = mojom::XRSession::New(); + + mojom::XRFrameDataProviderPtr data_provider; + mojom::XREnviromentIntegrationProviderPtr enviroment_provider; + mojom::XRSessionControllerPtr controller; + magic_window_sessions_.push_back(std::make_unique<VRDisplayImpl>( + this, mojo::MakeRequest(&data_provider), + mojo::MakeRequest(&enviroment_provider), mojo::MakeRequest(&controller))); + + session->data_provider = data_provider.PassInterface(); + session->enviroment_provider = enviroment_provider.PassInterface(); + + std::move(callback).Run(std::move(session), std::move(controller)); } void ARCoreDevice::OnRequestAndroidCameraPermissionResult(
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device.h b/chrome/browser/android/vr/arcore_device/arcore_device.h index ad09a36..d3ecff7 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_device.h +++ b/chrome/browser/android/vr/arcore_device/arcore_device.h
@@ -52,10 +52,11 @@ // VRDeviceBase implementation bool ShouldPauseTrackingWhenFrameDataRestricted() override; void OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) override; + mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; void RequestHitTest( mojom::XRRayPtr ray, - mojom::VRMagicWindowProvider::RequestHitTestCallback callback) override; + mojom::XREnviromentIntegrationProvider::RequestHitTestCallback callback) + override; void OnMailboxBridgeReady(); void OnARCoreGlThreadInitialized();
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.cc b/chrome/browser/android/vr/arcore_device/arcore_gl.cc index 891ed17..a7dd48da 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_gl.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_gl.cc
@@ -83,7 +83,7 @@ ARCoreHitTestRequest() = default; ~ARCoreHitTestRequest() = default; mojom::XRRayPtr ray; - mojom::VRMagicWindowProvider::RequestHitTestCallback callback; + mojom::XREnviromentIntegrationProvider::RequestHitTestCallback callback; private: DISALLOW_COPY_AND_ASSIGN(ARCoreHitTestRequest); @@ -176,7 +176,7 @@ void ARCoreGl::ProduceFrame( const gfx::Size& frame_size, display::Display::Rotation display_rotation, - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { TRACE_EVENT0("gpu", __FUNCTION__); DCHECK(IsOnGlThread()); DCHECK(is_initialized_); @@ -252,7 +252,7 @@ void ARCoreGl::RequestHitTest( mojom::XRRayPtr ray, - mojom::VRMagicWindowProvider::RequestHitTestCallback callback) { + mojom::XREnviromentIntegrationProvider::RequestHitTestCallback callback) { DCHECK(IsOnGlThread()); DCHECK(is_initialized_); @@ -266,7 +266,7 @@ void ARCoreGl::ProcessFrame( mojom::XRFrameDataPtr frame_data, const gfx::Size& frame_size, - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { DCHECK(IsOnGlThread()); DCHECK(is_initialized_);
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.h b/chrome/browser/android/vr/arcore_device/arcore_gl.h index d190193..2262ca97 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_gl.h +++ b/chrome/browser/android/vr/arcore_device/arcore_gl.h
@@ -50,7 +50,7 @@ void ProduceFrame(const gfx::Size& frame_size, display::Display::Rotation display_rotation, - mojom::VRMagicWindowProvider::GetFrameDataCallback); + mojom::XRFrameDataProvider::GetFrameDataCallback); void Pause(); void Resume(); @@ -58,17 +58,17 @@ return gl_thread_task_runner_; } - void RequestHitTest(mojom::XRRayPtr, - mojom::VRMagicWindowProvider::RequestHitTestCallback); + void RequestHitTest( + mojom::XRRayPtr, + mojom::XREnviromentIntegrationProvider::RequestHitTestCallback); base::WeakPtr<ARCoreGl> GetWeakPtr(); private: // TODO(https://crbug/835948): remove frame_size. - void ProcessFrame( - mojom::XRFrameDataPtr frame_data, - const gfx::Size& frame_size, - mojom::VRMagicWindowProvider::GetFrameDataCallback callback); + void ProcessFrame(mojom::XRFrameDataPtr frame_data, + const gfx::Size& frame_size, + mojom::XRFrameDataProvider::GetFrameDataCallback callback); bool InitializeGl(); bool IsOnGlThread() const;
diff --git a/chrome/browser/android/vr/gl_browser_interface.h b/chrome/browser/android/vr/gl_browser_interface.h index 77959c2..0e03d914 100644 --- a/chrome/browser/android/vr/gl_browser_interface.h +++ b/chrome/browser/android/vr/gl_browser_interface.h
@@ -32,11 +32,8 @@ virtual void ContentOverlaySurfaceCreated(jobject surface, gl::SurfaceTexture* texture) = 0; virtual void GvrDelegateReady(gvr::ViewerType viewer_type) = 0; - virtual void SendRequestPresentReply( - bool success, - device::mojom::VRSubmitFrameClientRequest, - device::mojom::VRPresentationProviderPtr, - device::mojom::VRDisplayFrameTransportOptionsPtr) = 0; + // XRSessionPtr is optional, if null, the request failed. + virtual void SendRequestPresentReply(device::mojom::XRSessionPtr) = 0; virtual void DialogSurfaceCreated(jobject surface, gl::SurfaceTexture* texture) = 0; virtual void UpdateGamepadData(device::GvrGamepadData) = 0;
diff --git a/chrome/browser/android/vr/vr_gl_thread.cc b/chrome/browser/android/vr/vr_gl_thread.cc index 0e88057..22b57b5 100644 --- a/chrome/browser/android/vr/vr_gl_thread.cc +++ b/chrome/browser/android/vr/vr_gl_thread.cc
@@ -131,17 +131,11 @@ base::BindOnce(&VrShell::GvrDelegateReady, weak_vr_shell_, viewer_type)); } -void VrGLThread::SendRequestPresentReply( - bool success, - device::mojom::VRSubmitFrameClientRequest request, - device::mojom::VRPresentationProviderPtr provider, - device::mojom::VRDisplayFrameTransportOptionsPtr transport_options) { +void VrGLThread::SendRequestPresentReply(device::mojom::XRSessionPtr session) { DCHECK(OnGlThread()); main_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&VrShell::SendRequestPresentReply, weak_vr_shell_, success, - std::move(request), provider.PassInterface(), - std::move(transport_options))); + FROM_HERE, base::BindOnce(&VrShell::SendRequestPresentReply, + weak_vr_shell_, std::move(session))); } void VrGLThread::UpdateGamepadData(device::GvrGamepadData pad) {
diff --git a/chrome/browser/android/vr/vr_gl_thread.h b/chrome/browser/android/vr/vr_gl_thread.h index 127aef7..2a490eb 100644 --- a/chrome/browser/android/vr/vr_gl_thread.h +++ b/chrome/browser/android/vr/vr_gl_thread.h
@@ -65,11 +65,7 @@ void ContentOverlaySurfaceCreated(jobject surface, gl::SurfaceTexture* texture) override; void GvrDelegateReady(gvr::ViewerType viewer_type) override; - void SendRequestPresentReply( - bool success, - device::mojom::VRSubmitFrameClientRequest, - device::mojom::VRPresentationProviderPtr, - device::mojom::VRDisplayFrameTransportOptionsPtr) override; + void SendRequestPresentReply(device::mojom::XRSessionPtr) override; void DialogSurfaceCreated(jobject surface, gl::SurfaceTexture* texture) override; void UpdateGamepadData(device::GvrGamepadData) override;
diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc index f6ac330f..8da7fd7 100644 --- a/chrome/browser/android/vr/vr_shell.cc +++ b/chrome/browser/android/vr/vr_shell.cc
@@ -92,9 +92,6 @@ constexpr base::TimeDelta kPollCapturingStateInterval = base::TimeDelta::FromSecondsD(0.2); -constexpr base::TimeDelta kExitVrDueToUnsupportedModeDelay = - base::TimeDelta::FromSeconds(5); - constexpr base::TimeDelta kAssetsComponentWaitDelay = base::TimeDelta::FromSeconds(2); @@ -754,17 +751,8 @@ delegate_provider_->SetDelegate(this, viewer_type); } -void VrShell::SendRequestPresentReply( - bool success, - device::mojom::VRSubmitFrameClientRequest request, - device::mojom::VRPresentationProviderPtrInfo provider_info, - device::mojom::VRDisplayFrameTransportOptionsPtr transport_options) { - device::mojom::VRPresentationProviderPtr provider; - provider.Bind(std::move(provider_info)); - - delegate_provider_->SendRequestPresentReply(success, std::move(request), - std::move(provider), - std::move(transport_options)); +void VrShell::SendRequestPresentReply(device::mojom::XRSessionPtr session) { + delegate_provider_->SendRequestPresentReply(std::move(session)); } void VrShell::BufferBoundsChanged(JNIEnv* env, @@ -866,28 +854,15 @@ UiUnsupportedMode::kCount); } -void VrShell::ExitVrDueToUnsupportedMode(UiUnsupportedMode mode) { - ui_->SetIsExiting(); - PostToGlThread(FROM_HERE, base::BindOnce(&VrShellGl::set_is_exiting, - gl_thread_->GetVrShellGl(), true)); - main_thread_task_runner_->PostDelayedTask( - FROM_HERE, - base::BindOnce(&VrShell::ForceExitVr, weak_ptr_factory_.GetWeakPtr()), - kExitVrDueToUnsupportedModeDelay); - LogUnsupportedModeUserMetric(mode); -} - content::WebContents* VrShell::GetNonNativePageWebContents() const { return !web_contents_is_native_page_ ? web_contents_ : nullptr; } void VrShell::OnUnsupportedMode(UiUnsupportedMode mode) { switch (mode) { - case UiUnsupportedMode::kUnhandledCodePoint: // Fall through. - case UiUnsupportedMode::kUnhandledCertificateInfo: - case UiUnsupportedMode::kUnhandledConnectionSecurityInfo: - case UiUnsupportedMode::kGenericUnsupportedFeature: - ExitVrDueToUnsupportedMode(mode); + case UiUnsupportedMode::kUnhandledCodePoint: + // We should never have this case. + CHECK(false); return; case UiUnsupportedMode::kVoiceSearchNeedsRecordAudioOsPermission: { JNIEnv* env = base::android::AttachCurrentThread(); @@ -899,20 +874,21 @@ Java_VrShellImpl_onNeedsKeyboardUpdate(env, j_vr_shell_); return; } - // Is not sent by the UI anymore. Enum value still exists to show correct - // exit prompt if vr-browsing-native-android-ui flag is false. + // These modes are not sent by the UI anymore. Enum values still exist to + // show correct exit prompt if vr-browsing-native-android-ui flag is false. case UiUnsupportedMode::kUnhandledPageInfo: + case UiUnsupportedMode::kUnhandledCertificateInfo: + case UiUnsupportedMode::kUnhandledConnectionSecurityInfo: + case UiUnsupportedMode::kGenericUnsupportedFeature: // kSearchEnginePromo should directly DOFF without showing a promo. So it // should never be used from VR ui thread. case UiUnsupportedMode::kSearchEnginePromo: - // Should never be used as a mode. case UiUnsupportedMode::kCount: NOTREACHED(); return; } NOTREACHED(); - ExitVrDueToUnsupportedMode(mode); } void VrShell::OnExitVrPromptResult(UiUnsupportedMode reason,
diff --git a/chrome/browser/android/vr/vr_shell.h b/chrome/browser/android/vr/vr_shell.h index da2d1e9..fb7a271 100644 --- a/chrome/browser/android/vr/vr_shell.h +++ b/chrome/browser/android/vr/vr_shell.h
@@ -181,11 +181,7 @@ void ContentOverlaySurfaceCreated(jobject surface, gl::SurfaceTexture* texture); void GvrDelegateReady(gvr::ViewerType viewer_type); - void SendRequestPresentReply( - bool success, - device::mojom::VRSubmitFrameClientRequest, - device::mojom::VRPresentationProviderPtrInfo, - device::mojom::VRDisplayFrameTransportOptionsPtr); + void SendRequestPresentReply(device::mojom::XRSessionPtr); void DialogSurfaceCreated(jobject surface, gl::SurfaceTexture* texture); @@ -302,8 +298,6 @@ bool HasDaydreamSupport(JNIEnv* env); - void ExitVrDueToUnsupportedMode(UiUnsupportedMode mode); - content::WebContents* GetNonNativePageWebContents() const; void LoadAssets();
diff --git a/chrome/browser/android/vr/vr_shell_delegate.cc b/chrome/browser/android/vr/vr_shell_delegate.cc index f843dd95..f754485 100644 --- a/chrome/browser/android/vr/vr_shell_delegate.cc +++ b/chrome/browser/android/vr/vr_shell_delegate.cc
@@ -187,7 +187,7 @@ if (!vr_shell_) { // We have to wait until the GL thread is ready since we have to get the - // VRSubmitFrameClient. + // XRPresentationClient. pending_successful_present_request_ = true; on_present_result_callback_ = base::BindOnce( &VrShellDelegate::OnPresentResult, base::Unretained(this), @@ -211,30 +211,15 @@ } void VrShellDelegate::SendRequestPresentReply( - bool success, - device::mojom::VRSubmitFrameClientRequest request, - device::mojom::VRPresentationProviderPtr provider, - device::mojom::VRDisplayFrameTransportOptionsPtr transport_options) { + device::mojom::XRSessionPtr session) { DVLOG(1) << __FUNCTION__; if (!request_present_response_callback_) { DLOG(ERROR) << __FUNCTION__ << ": ERROR: no callback"; return; } - if (success) { - auto connection = device::mojom::XRPresentationConnection::New(); - connection->client_request = std::move(request); - connection->provider = provider.PassInterface(); - connection->transport_options = std::move(transport_options); - - device::mojom::XRSessionPtr xr_session = device::mojom::XRSession::New(); - xr_session->connection = std::move(connection); - - base::ResetAndReturn(&request_present_response_callback_) - .Run(std::move(xr_session)); - } else { - base::ResetAndReturn(&request_present_response_callback_).Run(nullptr); - } + base::ResetAndReturn(&request_present_response_callback_) + .Run(std::move(session)); } void VrShellDelegate::DisplayActivate(JNIEnv* env,
diff --git a/chrome/browser/android/vr/vr_shell_delegate.h b/chrome/browser/android/vr/vr_shell_delegate.h index 859f616..b523ac0 100644 --- a/chrome/browser/android/vr/vr_shell_delegate.h +++ b/chrome/browser/android/vr/vr_shell_delegate.h
@@ -68,11 +68,7 @@ device::GvrDevice* GetDevice(); - void SendRequestPresentReply( - bool success, - device::mojom::VRSubmitFrameClientRequest request, - device::mojom::VRPresentationProviderPtr provider, - device::mojom::VRDisplayFrameTransportOptionsPtr); + void SendRequestPresentReply(device::mojom::XRSessionPtr session); // device::GvrDelegateProvider implementation. void ExitWebVRPresent() override;
diff --git a/chrome/browser/android/vr/vr_shell_gl.cc b/chrome/browser/android/vr/vr_shell_gl.cc index 9a1d110..e4c9811 100644 --- a/chrome/browser/android/vr/vr_shell_gl.cc +++ b/chrome/browser/android/vr/vr_shell_gl.cc
@@ -338,7 +338,8 @@ daydream_support_(daydream_support), content_paused_(pause_content), task_runner_(base::ThreadTaskRunnerHandle::Get()), - binding_(this), + presentation_binding_(this), + frame_data_binding_(this), browser_(browser_interface), vr_ui_fps_meter_(), webvr_fps_meter_(), @@ -681,7 +682,8 @@ DVLOG(1) << __FUNCTION__ << ": wrong frame index, got " << frame_index << ", expected " << animating_frame->index; mojo::ReportBadMessage("SubmitFrame called with wrong frame index"); - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); return false; } @@ -846,8 +848,10 @@ device::mojom::XRDeviceRuntimeSessionOptionsPtr options) { ClosePresentationBindings(); - device::mojom::VRPresentationProviderPtr provider; - binding_.Bind(mojo::MakeRequest(&provider)); + device::mojom::XRPresentationProviderPtr presentation_provider; + presentation_binding_.Bind(mojo::MakeRequest(&presentation_provider)); + device::mojom::XRFrameDataProviderPtr frame_data_provider; + frame_data_binding_.Bind(mojo::MakeRequest(&frame_data_provider)); gfx::Size webvr_size( display_info->leftEye->renderWidth + display_info->rightEye->renderWidth, @@ -857,7 +861,7 @@ // Decide which transport mechanism we want to use. This sets // the webxr_use_* options as a side effect. - device::mojom::VRDisplayFrameTransportOptionsPtr transport_options = + device::mojom::XRPresentationTransportOptionsPtr transport_options = GetWebVrFrameTransportOptions(options); if (webxr_use_shared_buffer_draw_) { @@ -877,9 +881,16 @@ ScheduleOrCancelWebVrFrameTimeout(); - browser_->SendRequestPresentReply(true, mojo::MakeRequest(&submit_client_), - std::move(provider), - std::move(transport_options)); + auto submit_frame_sink = device::mojom::XRPresentationConnection::New(); + submit_frame_sink->client_request = mojo::MakeRequest(&submit_client_); + submit_frame_sink->provider = presentation_provider.PassInterface(); + submit_frame_sink->transport_options = std::move(transport_options); + + auto session = device::mojom::XRSession::New(); + session->data_provider = frame_data_provider.PassInterface(); + session->submit_frame_sink = std::move(submit_frame_sink); + + browser_->SendRequestPresentReply(std::move(session)); } void VrShellGl::OnSwapContents(int new_content_id) { @@ -1077,7 +1088,7 @@ } } -device::mojom::VRDisplayFrameTransportOptionsPtr +device::mojom::XRPresentationTransportOptionsPtr VrShellGl::GetWebVrFrameTransportOptions( const device::mojom::XRDeviceRuntimeSessionOptionsPtr& options) { DVLOG(1) << __FUNCTION__; @@ -1120,19 +1131,19 @@ DVLOG(1) << __FUNCTION__ << ": render_path=" << static_cast<int>(render_path); MetricsUtilAndroid::LogXrRenderPathUsed(render_path); - device::mojom::VRDisplayFrameTransportOptionsPtr transport_options = - device::mojom::VRDisplayFrameTransportOptions::New(); + device::mojom::XRPresentationTransportOptionsPtr transport_options = + device::mojom::XRPresentationTransportOptions::New(); // Only set boolean options that we need. Default is false, and we should be // able to safely ignore ones that our implementation doesn't care about. transport_options->wait_for_transfer_notification = true; if (webxr_use_shared_buffer_draw_) { transport_options->transport_method = - device::mojom::VRDisplayFrameTransportMethod::DRAW_INTO_TEXTURE_MAILBOX; + device::mojom::XRPresentationTransportMethod::DRAW_INTO_TEXTURE_MAILBOX; DCHECK(webxr_use_gpu_fence_); transport_options->wait_for_gpu_fence = true; } else { transport_options->transport_method = - device::mojom::VRDisplayFrameTransportMethod::SUBMIT_AS_MAILBOX_HOLDER; + device::mojom::XRPresentationTransportMethod::SUBMIT_AS_MAILBOX_HOLDER; transport_options->wait_for_transfer_notification = true; if (webxr_use_gpu_fence_) { transport_options->wait_for_gpu_fence = true; @@ -1244,13 +1255,6 @@ const RenderInfo& render_info, base::TimeTicks current_time) { gfx::Vector3dF head_direction = GetForwardVector(render_info.head_pose); - if (is_exiting_) { - // When we're exiting, we don't show the reticle and the only input - // processing we do is to handle immediate exits. - SendImmediateExitRequestIfNecessary(); - return; - } - gfx::Vector3dF ergo_neutral_pose; if (!controller_->IsConnected()) { // No controller detected, set up a gaze cursor that tracks the @@ -1323,19 +1327,6 @@ ui_->OnControllerUpdated(controller_model, reticle_model); } -void VrShellGl::SendImmediateExitRequestIfNecessary() { - gvr::ControllerButton buttons[] = { - gvr::kControllerButtonClick, gvr::kControllerButtonApp, - gvr::kControllerButtonHome, - }; - for (size_t i = 0; i < arraysize(buttons); ++i) { - if (controller_->ButtonUpHappened(buttons[i]) || - controller_->ButtonDownHappened(buttons[i])) { - browser_->ForceExitVr(); - } - } -} - bool VrShellGl::ResizeForWebVR(int16_t frame_index) { // Process all pending_bounds_ changes targeted for before this frame, being // careful of wrapping frame indices. @@ -2252,7 +2243,7 @@ } void VrShellGl::GetFrameData( - device::mojom::VRPresentationProvider::GetFrameDataCallback callback) { + device::mojom::XRFrameDataProvider::GetFrameDataCallback callback) { TRACE_EVENT0("gpu", __FUNCTION__); if (!get_frame_data_callback_.is_null()) { DLOG(WARNING) << ": previous get_frame_data_callback_ was not used yet"; @@ -2286,14 +2277,16 @@ const gfx::Size& source_size) { if (!ValidateRect(left_bounds) || !ValidateRect(right_bounds)) { mojo::ReportBadMessage("UpdateLayerBounds called with invalid bounds"); - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); return; } if (frame_index >= 0 && !webxr_->HaveAnimatingFrame()) { // The optional UpdateLayerBounds call must happen before SubmitFrame. mojo::ReportBadMessage("UpdateLayerBounds called without animating frame"); - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); return; } @@ -2467,7 +2460,8 @@ // the connection is closing. base::ResetAndReturn(&get_frame_data_callback_).Run(nullptr); } - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); } device::mojom::XRInputSourceStatePtr VrShellGl::GetGazeInputSourceState() {
diff --git a/chrome/browser/android/vr/vr_shell_gl.h b/chrome/browser/android/vr/vr_shell_gl.h index e227dcd..619a81e 100644 --- a/chrome/browser/android/vr/vr_shell_gl.h +++ b/chrome/browser/android/vr/vr_shell_gl.h
@@ -264,7 +264,8 @@ // This class manages all GLThread owned objects and GL rendering for VrShell. // It is not threadsafe and must only be used on the GL thread. -class VrShellGl : public device::mojom::VRPresentationProvider { +class VrShellGl : public device::mojom::XRPresentationProvider, + public device::mojom::XRFrameDataProvider { public: VrShellGl(GlBrowserInterface* browser_interface, std::unique_ptr<UiInterface> ui, @@ -309,8 +310,6 @@ device::mojom::VRDisplayInfoPtr display_info, device::mojom::XRDeviceRuntimeSessionOptionsPtr options); - void set_is_exiting(bool exiting) { is_exiting_ = exiting; } - void OnSwapContents(int new_content_id); void EnableAlertDialog(PlatformInputHandler* input_handler, @@ -333,7 +332,7 @@ private: void GvrInit(gvr_context* gvr_api); - device::mojom::VRDisplayFrameTransportOptionsPtr + device::mojom::XRPresentationTransportOptionsPtr GetWebVrFrameTransportOptions( const device::mojom::XRDeviceRuntimeSessionOptionsPtr&); @@ -362,7 +361,6 @@ void UpdateController(const RenderInfo& render_info, base::TimeTicks current_time); - void SendImmediateExitRequestIfNecessary(); void HandleControllerInput(const gfx::Point3F& laser_origin, const RenderInfo& render_info, base::TimeTicks current_time); @@ -386,9 +384,11 @@ bool IsSubmitFrameExpected(int16_t frame_index); - // VRPresentationProvider - void GetFrameData(device::mojom::VRPresentationProvider::GetFrameDataCallback + // XRFrameDataProvider + void GetFrameData(device::mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; + + // XRPresentationProvider void SubmitFrameMissing(int16_t frame_index, const gpu::SyncToken&) override; void SubmitFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox, @@ -530,7 +530,6 @@ bool paused_ = true; const bool surfaceless_rendering_; bool daydream_support_; - bool is_exiting_ = false; bool content_paused_; bool cardboard_trigger_pressed_ = false; bool cardboard_trigger_clicked_ = false; @@ -550,11 +549,12 @@ // updated in OnVSync and used as the rAF animation timer in SendVSync. base::TimeTicks pending_time_; bool pending_vsync_ = false; - device::mojom::VRPresentationProvider::GetFrameDataCallback + device::mojom::XRFrameDataProvider::GetFrameDataCallback get_frame_data_callback_; - mojo::Binding<device::mojom::VRPresentationProvider> binding_; - device::mojom::VRSubmitFrameClientPtr submit_client_; + mojo::Binding<device::mojom::XRPresentationProvider> presentation_binding_; + mojo::Binding<device::mojom::XRFrameDataProvider> frame_data_binding_; + device::mojom::XRPresentationClientPtr submit_client_; GlBrowserInterface* browser_;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index b0625b33..e22fae5 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -143,8 +143,8 @@ <include name="IDR_DOWNLOAD_INTERNALS_JS" file="resources\download_internals\download_internals.js" type="BINDATA" compress="gzip" /> <include name="IDR_DOWNLOAD_INTERNALS_BROWSER_PROXY_JS" file="resources\download_internals\download_internals_browser_proxy.js" type="BINDATA" compress="gzip" /> <include name="IDR_DOWNLOAD_INTERNALS_VISUALS_JS" file="resources\download_internals\download_internals_visuals.js" type="BINDATA" compress="gzip" /> - <include name="IDR_UKM_INTERNALS_HTML" file="resources/ukm/ukm_internals.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" /> - <include name="IDR_UKM_INTERNALS_JS" file="resources/ukm/ukm_internals.js" flattenhtml="true" compress="gzip" type="BINDATA" /> + <include name="IDR_UKM_INTERNALS_HTML" file="../../components/ukm/debug/ukm_internals.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" /> + <include name="IDR_UKM_INTERNALS_JS" file="../../components/ukm/debug/ukm_internals.js" flattenhtml="true" compress="gzip" type="BINDATA" /> <if expr="not is_android"> <include name="IDR_MD_DOWNLOADS_1X_INCOGNITO_MARKER_PNG" file="resources\md_downloads\1x\incognito_marker.png" type="BINDATA" /> <include name="IDR_MD_DOWNLOADS_2X_INCOGNITO_MARKER_PNG" file="resources\md_downloads\2x\incognito_marker.png" type="BINDATA" />
diff --git a/chrome/browser/extensions/api/socket/combined_socket_unittest.cc b/chrome/browser/extensions/api/socket/combined_socket_unittest.cc deleted file mode 100644 index 6feb6fe9..0000000 --- a/chrome/browser/extensions/api/socket/combined_socket_unittest.cc +++ /dev/null
@@ -1,145 +0,0 @@ -// 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 <memory> - -#include "chrome/browser/extensions/api/socket/mock_tcp_client_socket.h" -#include "extensions/browser/api/socket/socket.h" -#include "extensions/browser/api/socket/tcp_socket.h" -#include "extensions/browser/api/socket/tls_socket.h" -#include "net/socket/stream_socket.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace extensions { - -const int kBufferLength = 10; - -template <typename T> -std::unique_ptr<T> CreateTestSocket( - std::unique_ptr<MockTCPClientSocket> stream); - -template <> -std::unique_ptr<TCPSocket> CreateTestSocket( - std::unique_ptr<MockTCPClientSocket> stream) { - return std::make_unique<TCPSocket>(std::move(stream), "fake id", - true /* is_connected */); -} - -template <> -std::unique_ptr<TLSSocket> CreateTestSocket( - std::unique_ptr<MockTCPClientSocket> stream) { - return std::make_unique<TLSSocket>(std::move(stream), "fake id"); -} - -class CombinedSocketTest : public testing::Test { - public: - CombinedSocketTest() : count_(0), io_buffer_(nullptr) {} - - // Strict test for synchronous (immediate) read behavior - template <typename T> - void TestRead() { - net::IOBuffer* buffer = nullptr; - - std::unique_ptr<MockTCPClientSocket> stream( - new testing::StrictMock<MockTCPClientSocket>()); - EXPECT_CALL(*stream, Read(testing::NotNull(), kBufferLength, testing::_)) - .WillOnce(DoAll(testing::SaveArg<0>(&buffer), - testing::Return(kBufferLength))); - EXPECT_CALL(*stream, Disconnect()); - - std::unique_ptr<T> socket = CreateTestSocket<T>(std::move(stream)); - ReadCompletionCallback read_callback = - base::Bind(&CombinedSocketTest::OnRead, base::Unretained(this)); - socket->Read(kBufferLength, read_callback); - EXPECT_EQ(kBufferLength, count_); - EXPECT_NE(nullptr, buffer); - EXPECT_EQ(buffer, io_buffer_); - } - - // Strict test for async read behavior (read returns PENDING) - template <typename T> - void TestReadPending() { - net::IOBuffer* buffer = nullptr; - net::CompletionCallback socket_cb; - - std::unique_ptr<MockTCPClientSocket> stream( - new testing::StrictMock<MockTCPClientSocket>()); - EXPECT_CALL(*stream, Read(testing::NotNull(), kBufferLength, testing::_)) - .WillOnce(DoAll(testing::SaveArg<0>(&buffer), - testing::SaveArg<2>(&socket_cb), - testing::Return(net::ERR_IO_PENDING))); - EXPECT_CALL(*stream, Disconnect()); - - std::unique_ptr<T> socket = CreateTestSocket<T>(std::move(stream)); - ReadCompletionCallback read_callback = - base::Bind(&CombinedSocketTest::OnRead, base::Unretained(this)); - socket->Read(kBufferLength, read_callback); - EXPECT_EQ(0, count_); - EXPECT_EQ(nullptr, io_buffer_); - socket_cb.Run(kBufferLength); - EXPECT_EQ(kBufferLength, count_); - EXPECT_NE(nullptr, buffer); - EXPECT_EQ(buffer, io_buffer_); - } - - // Even if the socket is closed, it may still have data left to read. - template <typename T> - void TestReadAfterDisconnect() { - net::IOBuffer* buffer = nullptr; - - std::unique_ptr<MockTCPClientSocket> stream( - new testing::NiceMock<MockTCPClientSocket>()); - EXPECT_CALL(*stream, Read(testing::NotNull(), kBufferLength, testing::_)) - .WillOnce(DoAll(testing::SaveArg<0>(&buffer), - testing::Return(kBufferLength))); - ON_CALL(*stream, IsConnected()).WillByDefault(testing::Return(false)); - EXPECT_CALL(*stream, Disconnect()); - - std::unique_ptr<T> socket = CreateTestSocket<T>(std::move(stream)); - ReadCompletionCallback read_callback = - base::Bind(&CombinedSocketTest::OnRead, base::Unretained(this)); - socket->Read(kBufferLength, read_callback); - EXPECT_EQ(kBufferLength, count_); - EXPECT_NE(nullptr, buffer); - EXPECT_EQ(buffer, io_buffer_); - } - - void OnRead(int count, - scoped_refptr<net::IOBuffer> io_buffer, - bool socket_destroying) { - count_ = count; - io_buffer_ = io_buffer.get(); - } - - protected: - int count_; - net::IOBuffer* io_buffer_; -}; - -TEST_F(CombinedSocketTest, TlsRead) { - TestRead<TLSSocket>(); -} - -TEST_F(CombinedSocketTest, TcpRead) { - TestRead<TCPSocket>(); -} - -TEST_F(CombinedSocketTest, TlsReadPending) { - TestReadPending<TLSSocket>(); -} - -TEST_F(CombinedSocketTest, TcpReadPending) { - TestReadPending<TCPSocket>(); -} - -TEST_F(CombinedSocketTest, TlsReadAfterDisconnect) { - TestReadAfterDisconnect<TLSSocket>(); -} - -TEST_F(CombinedSocketTest, TcpReadAfterDisconnect) { - TestReadAfterDisconnect<TCPSocket>(); -} - -} // namespace extensions
diff --git a/chrome/browser/extensions/api/socket/mock_tcp_client_socket.h b/chrome/browser/extensions/api/socket/mock_tcp_client_socket.h deleted file mode 100644 index fddad10..0000000 --- a/chrome/browser/extensions/api/socket/mock_tcp_client_socket.h +++ /dev/null
@@ -1,82 +0,0 @@ -// 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 CHROME_BROWSER_EXTENSIONS_API_SOCKET_MOCK_TCP_CLIENT_SOCKET_H_ -#define CHROME_BROWSER_EXTENSIONS_API_SOCKET_MOCK_TCP_CLIENT_SOCKET_H_ - -#include "base/callback_helpers.h" -#include "net/log/net_log_source.h" -#include "net/log/net_log_with_source.h" -#include "net/socket/tcp_client_socket.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace extensions { -class MockTCPClientSocket : public net::TCPClientSocket { - public: - MockTCPClientSocket(); - ~MockTCPClientSocket() override; - - int Read(net::IOBuffer* buffer, - int bytes, - net::CompletionOnceCallback callback) override { - return Read(buffer, bytes, - base::AdaptCallbackForRepeating(std::move(callback))); - } - - int Write(net::IOBuffer* buffer, - int bytes, - net::CompletionOnceCallback callback, - const net::NetworkTrafficAnnotationTag& tag) override { - return Write(buffer, bytes, - base::AdaptCallbackForRepeating(std::move(callback)), tag); - } - - int Connect(net::CompletionOnceCallback callback) override { - return Connect(base::AdaptCallbackForRepeating(std::move(callback))); - } - - MOCK_METHOD3(Read, int(net::IOBuffer*, int, const net::CompletionCallback&)); - MOCK_METHOD4(Write, - int(net::IOBuffer*, - int, - const net::CompletionCallback&, - const net::NetworkTrafficAnnotationTag&)); - MOCK_METHOD1(SetReceiveBufferSize, int(int32_t)); - MOCK_METHOD1(SetSendBufferSize, int(int32_t)); - MOCK_METHOD1(Connect, int(const net::CompletionCallback&)); - MOCK_METHOD0(Disconnect, void()); - MOCK_CONST_METHOD0(IsConnected, bool()); - MOCK_CONST_METHOD0(IsConnectedAndIdle, bool()); - MOCK_CONST_METHOD1(GetPeerAddress, int(net::IPEndPoint*)); - MOCK_CONST_METHOD1(GetLocalAddress, int(net::IPEndPoint*)); - MOCK_CONST_METHOD0(NetLog, const net::NetLogWithSource&()); - MOCK_CONST_METHOD0(WasEverUsed, bool()); - MOCK_CONST_METHOD0(UsingTCPFastOpen, bool()); - MOCK_CONST_METHOD0(NumBytesRead, int64_t()); - MOCK_CONST_METHOD0(GetConnectTimeMicros, base::TimeDelta()); - MOCK_CONST_METHOD0(WasAlpnNegotiated, bool()); - MOCK_CONST_METHOD0(GetNegotiatedProtocol, net::NextProto()); - MOCK_METHOD1(GetSSLInfo, bool(net::SSLInfo*)); - MOCK_CONST_METHOD1(GetConnectionAttempts, void(net::ConnectionAttempts*)); - MOCK_METHOD0(ClearConnectionAttempts, void()); - MOCK_METHOD1(AddConnectionAttempts, void(const net::ConnectionAttempts&)); - MOCK_CONST_METHOD0(GetTotalReceivedBytes, int64_t()); - - // Methods specific to MockTCPClientSocket - MOCK_METHOD1(Bind, int(const net::IPEndPoint&)); - MOCK_METHOD2(SetKeepAlive, bool(bool, int)); - MOCK_METHOD1(SetNoDelay, bool(bool)); -}; - -MockTCPClientSocket::MockTCPClientSocket() - : TCPClientSocket(net::AddressList(), - nullptr, - nullptr, - net::NetLogSource()) {} -MockTCPClientSocket::~MockTCPClientSocket() {} - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_API_SOCKET_MOCK_TCP_CLIENT_SOCKET_H_
diff --git a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc index 6351e3d..90c7937 100644 --- a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc +++ b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
@@ -4,274 +4,717 @@ #include <memory> -#include "base/callback_helpers.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/test/bind_test_util.h" +#include "chrome/browser/extensions/extension_service_test_base.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/browser/browser_context.h" +#include "content/public/test/test_storage_partition.h" #include "extensions/browser/api/socket/tcp_socket.h" #include "net/base/address_list.h" #include "net/base/completion_callback.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" -#include "net/base/rand_callback.h" -#include "net/log/net_log_source.h" -#include "net/socket/tcp_client_socket.h" -#include "net/socket/tcp_server_socket.h" +#include "net/base/test_completion_callback.h" +#include "net/socket/socket_test_util.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "testing/gmock/include/gmock/gmock.h" - -using testing::_; -using testing::DoAll; -using testing::Return; -using testing::SaveArg; +#include "net/url_request/url_request_test_util.h" +#include "services/network/network_context.h" +#include "services/network/public/mojom/network_context.mojom.h" namespace extensions { -class MockTCPSocket : public net::TCPClientSocket { - public: - explicit MockTCPSocket(const net::AddressList& address_list) - : net::TCPClientSocket(address_list, NULL, NULL, net::NetLogSource()) {} +namespace { - int Read(net::IOBuffer* buffer, - int bytes, - net::CompletionOnceCallback callback) override { - return Read(buffer, bytes, - base::AdaptCallbackForRepeating(std::move(callback))); - } - - int Write(net::IOBuffer* buffer, - int bytes, - net::CompletionOnceCallback callback, - const net::NetworkTrafficAnnotationTag& tag) override { - return Write(buffer, bytes, - base::AdaptCallbackForRepeating(std::move(callback)), tag); - } - - MOCK_METHOD3(Read, int(net::IOBuffer* buf, int buf_len, - const net::CompletionCallback& callback)); - MOCK_METHOD4(Write, - int(net::IOBuffer* buf, - int buf_len, - const net::CompletionCallback& callback, - const net::NetworkTrafficAnnotationTag&)); - MOCK_METHOD2(SetKeepAlive, bool(bool enable, int delay)); - MOCK_METHOD1(SetNoDelay, bool(bool no_delay)); - bool IsConnected() const override { - return true; - } - - private: - DISALLOW_COPY_AND_ASSIGN(MockTCPSocket); -}; - -class MockTCPServerSocket : public net::TCPServerSocket { - public: - MockTCPServerSocket() : net::TCPServerSocket(NULL, net::NetLogSource()) {} - MOCK_METHOD2(Listen, int(const net::IPEndPoint& address, int backlog)); - MOCK_METHOD2(Accept, - int(std::unique_ptr<net::StreamSocket>* socket, - const net::CompletionCallback& callback)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockTCPServerSocket); -}; - -class CompleteHandler { - public: - CompleteHandler() {} - MOCK_METHOD1(OnComplete, void(int result_code)); - MOCK_METHOD3(OnReadComplete, - void(int result_code, - scoped_refptr<net::IOBuffer> io_buffer, - bool socket_destroying)); - - // MOCK_METHOD cannot mock a scoped_ptr argument. - MOCK_METHOD2(OnAcceptMock, void(int, net::TCPClientSocket*)); - void OnAccept(int count, std::unique_ptr<net::TCPClientSocket> socket) { - OnAcceptMock(count, socket.get()); - } - - private: - DISALLOW_COPY_AND_ASSIGN(CompleteHandler); -}; +const char kTestMsg[] = "abcdefghij"; +const int kTestMsgLength = strlen(kTestMsg); const char FAKE_ID[] = "abcdefghijklmnopqrst"; -TEST(SocketTest, TestTCPSocketRead) { - net::AddressList address_list; - std::unique_ptr<MockTCPSocket> tcp_client_socket( - new MockTCPSocket(address_list)); - CompleteHandler handler; +class TCPSocketUnitTestBase : public extensions::ExtensionServiceTestBase { + public: + TCPSocketUnitTestBase() + : url_request_context_(true /* delay_initialization */) {} + ~TCPSocketUnitTestBase() override {} - EXPECT_CALL(*tcp_client_socket, Read(_, _, _)) - .Times(1); - EXPECT_CALL(handler, OnReadComplete(_, _, _)).Times(1); + std::unique_ptr<TCPSocket> CreateSocket() { + auto socket = std::make_unique<TCPSocket>(&profile_, FAKE_ID); + socket->SetStoragePartitionForTest(&partition_); + return socket; + } - std::unique_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting( - std::move(tcp_client_socket), FAKE_ID, true)); + std::unique_ptr<TCPSocket> CreateAndConnectSocketWithAddress( + const net::IPEndPoint& ip_end_point) { + auto socket = CreateSocket(); + net::AddressList address(ip_end_point); + net::TestCompletionCallback callback; + socket->Connect(address, callback.callback()); + EXPECT_EQ(net::OK, callback.WaitForResult()); + return socket; + } + + std::unique_ptr<TCPSocket> CreateAndConnectSocket() { + net::IPEndPoint ip_end_point(net::IPAddress::IPv4Localhost(), 1234); + return CreateAndConnectSocketWithAddress(ip_end_point); + } + + // Reads data from |socket| and compares it with |expected_data|. + void ReadData(Socket* socket, const std::string& expected_data) { + std::string received_data; + const int count = 512; + while (true) { + base::RunLoop run_loop; + int net_error = net::ERR_FAILED; + socket->Read(count, + base::BindLambdaForTesting( + [&](int result, scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + net_error = result; + EXPECT_FALSE(socket_destroying); + if (result > 0) + received_data.append(io_buffer->data(), result); + run_loop.Quit(); + })); + run_loop.Run(); + if (net_error <= 0) + break; + } + EXPECT_EQ(expected_data, received_data); + } + + protected: + // extensions::ExtensionServiceTestBase implementation. + void SetUp() override { InitializeEmptyExtensionService(); } + + void Initialize() { + url_request_context_.Init(); + network_context_ = std::make_unique<network::NetworkContext>( + nullptr, mojo::MakeRequest(&network_context_ptr_), + &url_request_context_); + partition_.set_network_context(network_context_ptr_.get()); + } + + net::TestURLRequestContext url_request_context_; + + private: + TestingProfile profile_; + content::TestStoragePartition partition_; + std::unique_ptr<network::NetworkContext> network_context_; + network::mojom::NetworkContextPtr network_context_ptr_; +}; + +} // namespace + +class TCPSocketUnitTest : public TCPSocketUnitTestBase, + public ::testing::WithParamInterface<net::IoMode> { + public: + TCPSocketUnitTest() : TCPSocketUnitTestBase() { + mock_client_socket_factory_.set_enable_read_if_ready(true); + url_request_context_.set_client_socket_factory( + &mock_client_socket_factory_); + Initialize(); + } + ~TCPSocketUnitTest() override {} + + net::MockClientSocketFactory* mock_client_socket_factory() { + return &mock_client_socket_factory_; + } + + private: + net::MockClientSocketFactory mock_client_socket_factory_; +}; + +INSTANTIATE_TEST_CASE_P(/* no prefix */, + TCPSocketUnitTest, + testing::Values(net::SYNCHRONOUS, net::ASYNC)); + +TEST_F(TCPSocketUnitTest, SocketConnectError) { + net::IPEndPoint ip_end_point(net::IPAddress::IPv4Localhost(), 1234); + net::StaticSocketDataProvider data_provider((base::span<net::MockRead>()), + base::span<net::MockWrite>()); + data_provider.set_connect_data( + net::MockConnect(net::ASYNC, net::ERR_FAILED, ip_end_point)); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateSocket(); + + net::AddressList address(ip_end_point); + net::TestCompletionCallback callback; + socket->Connect(address, callback.callback()); + EXPECT_EQ(net::ERR_FAILED, callback.WaitForResult()); +} + +TEST_P(TCPSocketUnitTest, SocketConnectAfterDisconnect) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = {net::MockRead(io_mode, net::OK)}; + net::StaticSocketDataProvider data_provider1(kReads, + base::span<net::MockWrite>()); + net::StaticSocketDataProvider data_provider2(kReads, + base::span<net::MockWrite>()); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider1); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider2); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + socket->Disconnect(false /* socket_destroying */); + net::TestCompletionCallback callback2; + net::IPEndPoint ip_end_point(net::IPAddress::IPv4Localhost(), 1234); + net::AddressList address(ip_end_point); + socket->Connect(address, callback2.callback()); + EXPECT_EQ(net::OK, callback2.WaitForResult()); + + EXPECT_TRUE(data_provider1.AllReadDataConsumed()); + EXPECT_TRUE(data_provider1.AllWriteDataConsumed()); + EXPECT_TRUE(data_provider2.AllReadDataConsumed()); + EXPECT_TRUE(data_provider2.AllWriteDataConsumed()); +} + +TEST_F(TCPSocketUnitTest, DestroyWhileReadPending) { + const net::MockRead kReads[] = { + net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING)}; + net::StaticSocketDataProvider data_provider(kReads, + base::span<net::MockWrite>()); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + + int net_result = net::ERR_FAILED; + base::RunLoop run_loop; + int count = 1; + // Read one byte, and it should be pending. + socket->Read(count, + base::BindLambdaForTesting( + [&](int result, scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + net_result = result; + // |socket_destroying| should correctly denote that this + // read callback is invoked through the destructor of + // TCPSocket. + EXPECT_TRUE(socket_destroying); + run_loop.Quit(); + })); + // Destroy socket. + socket = nullptr; + // Wait for read callback. + run_loop.Run(); + EXPECT_EQ(net::ERR_CONNECTION_CLOSED, net_result); +} + +TEST_P(TCPSocketUnitTest, Read) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(io_mode, kTestMsg, kTestMsgLength), + net::MockRead(io_mode, net::OK)}; + net::StaticSocketDataProvider data_provider(kReads, + base::span<net::MockWrite>()); + + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + + ReadData(socket.get(), kTestMsg); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +// Tests the case where a message is split over two separate socket reads. +TEST_P(TCPSocketUnitTest, SocketMultipleRead) { + const char kFirstHalfTestMsg[] = "abcde"; + const char kSecondHalfTestMsg[] = "fghij"; + EXPECT_EQ(kTestMsg, std::string(kFirstHalfTestMsg) + kSecondHalfTestMsg); + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(io_mode, kFirstHalfTestMsg, strlen(kFirstHalfTestMsg)), + net::MockRead(io_mode, kSecondHalfTestMsg, strlen(kSecondHalfTestMsg)), + net::MockRead(io_mode, net::OK)}; + net::StaticSocketDataProvider data_provider(kReads, + base::span<net::MockWrite>()); + + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + + ReadData(socket.get(), kTestMsg); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +// Tests the case where read size is smaller than the actual message. +TEST_P(TCPSocketUnitTest, SocketPartialRead) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(io_mode, kTestMsg, kTestMsgLength), + net::MockRead(io_mode, net::OK)}; + net::StaticSocketDataProvider data_provider(kReads, + base::span<net::MockWrite>()); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + + int count = 1; + std::string received_data; + while (true) { + int net_result = net::ERR_FAILED; + base::RunLoop run_loop; + socket->Read(count, + base::BindLambdaForTesting( + [&](int result, scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + net_result = result; + EXPECT_FALSE(socket_destroying); + if (result > 0) + received_data.append(io_buffer->data(), result); + run_loop.Quit(); + })); + run_loop.Run(); + if (net_result <= 0) + break; + // Double the read size in the next iteration. + count *= 2; + } + EXPECT_EQ(kTestMsg, received_data); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +TEST_P(TCPSocketUnitTest, ReadError) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(io_mode, kTestMsg, kTestMsgLength), + net::MockRead(io_mode, net::ERR_INSUFFICIENT_RESOURCES)}; + net::StaticSocketDataProvider data_provider(kReads, + base::span<net::MockWrite>()); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); const int count = 512; - socket->Read(count, base::Bind(&CompleteHandler::OnReadComplete, - base::Unretained(&handler))); -} - -TEST(SocketTest, TestTCPSocketWrite) { - net::AddressList address_list; - std::unique_ptr<MockTCPSocket> tcp_client_socket( - new MockTCPSocket(address_list)); - CompleteHandler handler; - - net::CompletionCallback callback; - EXPECT_CALL(*tcp_client_socket, Write(_, _, _, _)) - .Times(2) - .WillRepeatedly(testing::DoAll(SaveArg<2>(&callback), Return(128))); - EXPECT_CALL(handler, OnComplete(_)) - .Times(1); - - std::unique_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting( - std::move(tcp_client_socket), FAKE_ID, true)); - - scoped_refptr<net::IOBufferWithSize> io_buffer( - new net::IOBufferWithSize(256)); - socket->Write(io_buffer.get(), io_buffer->size(), - base::Bind(&CompleteHandler::OnComplete, base::Unretained(&handler))); -} - -TEST(SocketTest, TestTCPSocketBlockedWrite) { - net::AddressList address_list; - std::unique_ptr<MockTCPSocket> tcp_client_socket( - new MockTCPSocket(address_list)); - CompleteHandler handler; - - net::CompletionCallback callback; - EXPECT_CALL(*tcp_client_socket, Write(_, _, _, _)) - .Times(2) - .WillRepeatedly( - testing::DoAll(SaveArg<2>(&callback), Return(net::ERR_IO_PENDING))); - - std::unique_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting( - std::move(tcp_client_socket), FAKE_ID, true)); - - scoped_refptr<net::IOBufferWithSize> io_buffer(new net::IOBufferWithSize(42)); - socket->Write(io_buffer.get(), io_buffer->size(), - base::Bind(&CompleteHandler::OnComplete, base::Unretained(&handler))); - - // Good. Original call came back unable to complete. Now pretend the socket - // finished, and confirm that we passed the error back. - EXPECT_CALL(handler, OnComplete(42)) - .Times(1); - callback.Run(40); - callback.Run(2); -} - -TEST(SocketTest, TestTCPSocketBlockedWriteReentry) { - net::AddressList address_list; - std::unique_ptr<MockTCPSocket> tcp_client_socket( - new MockTCPSocket(address_list)); - CompleteHandler handlers[5]; - - net::CompletionCallback callback; - EXPECT_CALL(*tcp_client_socket, Write(_, _, _, _)) - .Times(5) - .WillRepeatedly( - testing::DoAll(SaveArg<2>(&callback), Return(net::ERR_IO_PENDING))); - - std::unique_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting( - std::move(tcp_client_socket), FAKE_ID, true)); - - scoped_refptr<net::IOBufferWithSize> io_buffers[5]; - int i; - for (i = 0; i < 5; i++) { - io_buffers[i] = new net::IOBufferWithSize(128 + i * 50); - scoped_refptr<net::IOBufferWithSize> io_buffer1( - new net::IOBufferWithSize(42)); - socket->Write(io_buffers[i].get(), io_buffers[i]->size(), - base::Bind(&CompleteHandler::OnComplete, - base::Unretained(&handlers[i]))); - - EXPECT_CALL(handlers[i], OnComplete(io_buffers[i]->size())) - .Times(1); + int net_error = net::OK; + while (true) { + base::RunLoop run_loop; + socket->Read(count, + base::BindLambdaForTesting( + [&](int result, scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + net_error = result; + EXPECT_FALSE(socket_destroying); + if (result <= 0) { + EXPECT_FALSE(socket->IsConnected()); + EXPECT_EQ(nullptr, io_buffer); + } else { + EXPECT_TRUE(socket->IsConnected()); + } + run_loop.Quit(); + })); + run_loop.Run(); + if (net_error < 0) + break; } - - for (i = 0; i < 5; i++) { - callback.Run(128 + i * 50); - } + // Note that TCPSocket only detects that receive pipe is broken and propagates + // it as a net::ERR_FAILED. It doesn't know the specific net error code. To do + // that, it needs to register itself as a network::mojom::SocketObserver. + EXPECT_EQ(net::ERR_FAILED, net_error); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); } -TEST(SocketTest, TestTCPSocketSetNoDelay) { - net::AddressList address_list; - std::unique_ptr<MockTCPSocket> tcp_client_socket( - new MockTCPSocket(address_list)); +TEST_P(TCPSocketUnitTest, Write) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING)}; + const net::MockWrite kWrites[] = { + net::MockWrite(io_mode, kTestMsg, kTestMsgLength)}; - bool no_delay = false; + net::StaticSocketDataProvider data_provider(kReads, kWrites); + + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + net::TestCompletionCallback write_callback; + socket->Write(io_buffer.get(), kTestMsgLength, write_callback.callback()); + EXPECT_EQ(kTestMsgLength, write_callback.WaitForResult()); +} + +// Tests the case where a message is split over two separate socket writes. +TEST_P(TCPSocketUnitTest, MultipleWrite) { + const char kFirstHalfTestMsg[] = "abcde"; + const char kSecondHalfTestMsg[] = "fghij"; + EXPECT_EQ(kTestMsg, std::string(kFirstHalfTestMsg) + kSecondHalfTestMsg); + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING)}; + const net::MockWrite kWrites[] = { + net::MockWrite(io_mode, kFirstHalfTestMsg, strlen(kFirstHalfTestMsg)), + net::MockWrite(io_mode, kSecondHalfTestMsg, strlen(kSecondHalfTestMsg))}; + + net::StaticSocketDataProvider data_provider(kReads, kWrites); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + + int num_bytes_written = 0; + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + auto drainable_io_buffer = base::MakeRefCounted<net::DrainableIOBuffer>( + io_buffer.get(), kTestMsgLength); + while (num_bytes_written < kTestMsgLength) { + net::TestCompletionCallback write_callback; + socket->Write(drainable_io_buffer.get(), kTestMsgLength - num_bytes_written, + write_callback.callback()); + int result = write_callback.WaitForResult(); + ASSERT_GT(result, net::OK); + drainable_io_buffer->DidConsume(result); + num_bytes_written += result; + // Flushes the write. + base::RunLoop().RunUntilIdle(); + } + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +TEST_P(TCPSocketUnitTest, PartialWrite) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING)}; + const net::MockWrite kWrites[] = { + net::MockWrite(io_mode, "a", 1), net::MockWrite(io_mode, "bc", 2), + net::MockWrite(io_mode, "defg", 4), net::MockWrite(io_mode, "hij", 3)}; + + net::StaticSocketDataProvider data_provider(kReads, kWrites); + + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + + // Start with writing one byte, and double that in the next iteration. + int num_bytes_to_write = 1; + int num_bytes_written = 0; + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + auto drainable_io_buffer = base::MakeRefCounted<net::DrainableIOBuffer>( + io_buffer.get(), kTestMsgLength); + while (num_bytes_written < kTestMsgLength) { + net::TestCompletionCallback write_callback; + socket->Write( + drainable_io_buffer.get(), + std::max(kTestMsgLength - num_bytes_written, num_bytes_to_write), + write_callback.callback()); + int result = write_callback.WaitForResult(); + ASSERT_GT(result, net::OK); + drainable_io_buffer->DidConsume(result); + num_bytes_written += result; + num_bytes_to_write *= 2; + // Flushes the write. + base::RunLoop().RunUntilIdle(); + } + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +TEST_P(TCPSocketUnitTest, WriteError) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING)}; + const net::MockWrite kWrites[] = { + net::MockWrite(io_mode, net::ERR_INSUFFICIENT_RESOURCES)}; + + net::StaticSocketDataProvider data_provider(kReads, kWrites); + + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + + // Mojo data pipe might buffer some write data, so continue writing until the + // write error is received. + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + int net_error = net::OK; + while (true) { + base::RunLoop run_loop; + socket->Write(io_buffer.get(), kTestMsgLength, + base::BindLambdaForTesting([&](int result) { + EXPECT_EQ(result > 0, socket->IsConnected()); + net_error = result; + run_loop.Quit(); + })); + run_loop.Run(); + if (net_error <= 0) + break; + } + // Note that TCPSocket only detects that send pipe is broken and propagates + // it as a net::ERR_FAILED. It doesn't know the specific net error code. To do + // that, it needs to register itself as a network::mojom::SocketObserver. + EXPECT_EQ(net::ERR_FAILED, net_error); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +namespace { + +class ExtensionsMockClientSocket : public net::MockTCPClientSocket { + public: + ExtensionsMockClientSocket(net::SocketDataProvider* provider, bool success) + : MockTCPClientSocket( + net::AddressList( + net::IPEndPoint(net::IPAddress::IPv4Localhost(), 1234)), + nullptr /* netlog */, + provider), + success_(success) { + this->set_enable_read_if_ready(true); + } + ~ExtensionsMockClientSocket() override {} + + bool SetNoDelay(bool no_delay) override { return success_; } + bool SetKeepAlive(bool enable, int delay) override { return success_; } + + private: + // Whether to return success for SetNoDelay() and SetKeepAlive(). + const bool success_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionsMockClientSocket); +}; + +static const net::MockRead kMockReads[] = {net::MockRead(net::ASYNC, net::OK)}; + +// A ClientSocketFactory to create sockets that simulate SetNoDelay and +// SetKeepAlive success and failures. +class TestSocketFactory : public net::ClientSocketFactory { + public: + explicit TestSocketFactory(bool success) : success_(success) {} + ~TestSocketFactory() override = default; + + std::unique_ptr<net::DatagramClientSocket> CreateDatagramClientSocket( + net::DatagramSocket::BindType, + net::NetLog*, + const net::NetLogSource&) override { + NOTIMPLEMENTED(); + return nullptr; + } + std::unique_ptr<net::TransportClientSocket> CreateTransportClientSocket( + const net::AddressList&, + std::unique_ptr<net::SocketPerformanceWatcher>, + net::NetLog*, + const net::NetLogSource&) override { + providers_.push_back(std::make_unique<net::StaticSocketDataProvider>( + kMockReads, base::span<net::MockWrite>())); + return std::make_unique<ExtensionsMockClientSocket>(providers_.back().get(), + success_); + } + std::unique_ptr<net::SSLClientSocket> CreateSSLClientSocket( + std::unique_ptr<net::ClientSocketHandle>, + const net::HostPortPair&, + const net::SSLConfig&, + const net::SSLClientSocketContext&) override { + NOTIMPLEMENTED(); + return std::unique_ptr<net::SSLClientSocket>(); + } + std::unique_ptr<net::ProxyClientSocket> CreateProxyClientSocket( + std::unique_ptr<net::ClientSocketHandle> transport_socket, + const std::string& user_agent, + const net::HostPortPair& endpoint, + net::HttpAuthController* http_auth_controller, + bool tunnel, + bool using_spdy, + net::NextProto negotiated_protocol, + bool is_https_proxy, + const net::NetworkTrafficAnnotationTag& traffic_annotation) override { + NOTIMPLEMENTED(); + return nullptr; + } + void ClearSSLSessionCache() override { NOTIMPLEMENTED(); } + + private: + std::vector<std::unique_ptr<net::StaticSocketDataProvider>> providers_; + // Whether to return success for net::TransportClientSocket::SetNoDelay() and + // SetKeepAlive(). + const bool success_; + + DISALLOW_COPY_AND_ASSIGN(TestSocketFactory); +}; + +} // namespace + +class TCPSocketSettingsTest : public TCPSocketUnitTestBase, + public ::testing::WithParamInterface<bool> { + public: + TCPSocketSettingsTest() + : TCPSocketUnitTestBase(), client_socket_factory_(GetParam()) { + url_request_context_.set_client_socket_factory(&client_socket_factory_); + Initialize(); + } + ~TCPSocketSettingsTest() override {} + + private: + TestSocketFactory client_socket_factory_; +}; + +INSTANTIATE_TEST_CASE_P(/* no prefix */, + TCPSocketSettingsTest, + testing::Bool()); + +TEST_P(TCPSocketSettingsTest, SetNoDelay) { + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + bool expected_success = GetParam(); { - testing::InSequence dummy; - EXPECT_CALL(*tcp_client_socket, SetNoDelay(_)) - .WillOnce(testing::DoAll(SaveArg<0>(&no_delay), Return(true))); - EXPECT_CALL(*tcp_client_socket, SetNoDelay(_)) - .WillOnce(testing::DoAll(SaveArg<0>(&no_delay), Return(false))); + base::RunLoop run_loop; + socket->SetNoDelay(true, base::BindLambdaForTesting([&](bool success) { + EXPECT_EQ(expected_success, success); + run_loop.Quit(); + })); + run_loop.Run(); } - std::unique_ptr<TCPSocket> socket( - TCPSocket::CreateSocketForTesting(std::move(tcp_client_socket), FAKE_ID)); - - EXPECT_FALSE(no_delay); - int result = socket->SetNoDelay(true); - EXPECT_TRUE(result); - EXPECT_TRUE(no_delay); - - result = socket->SetNoDelay(false); - EXPECT_FALSE(result); - EXPECT_FALSE(no_delay); -} - -TEST(SocketTest, TestTCPSocketSetKeepAlive) { - net::AddressList address_list; - std::unique_ptr<MockTCPSocket> tcp_client_socket( - new MockTCPSocket(address_list)); - - bool enable = false; - int delay = 0; { - testing::InSequence dummy; - EXPECT_CALL(*tcp_client_socket, SetKeepAlive(_, _)) - .WillOnce(testing::DoAll(SaveArg<0>(&enable), SaveArg<1>(&delay), - Return(true))); - EXPECT_CALL(*tcp_client_socket, SetKeepAlive(_, _)) - .WillOnce(testing::DoAll(SaveArg<0>(&enable), SaveArg<1>(&delay), - Return(false))); + base::RunLoop run_loop; + socket->SetNoDelay(false, base::BindLambdaForTesting([&](bool success) { + EXPECT_EQ(expected_success, success); + run_loop.Quit(); + })); + run_loop.Run(); } - - std::unique_ptr<TCPSocket> socket( - TCPSocket::CreateSocketForTesting(std::move(tcp_client_socket), FAKE_ID)); - - EXPECT_FALSE(enable); - int result = socket->SetKeepAlive(true, 4500); - EXPECT_TRUE(result); - EXPECT_TRUE(enable); - EXPECT_EQ(4500, delay); - - result = socket->SetKeepAlive(false, 0); - EXPECT_FALSE(result); - EXPECT_FALSE(enable); - EXPECT_EQ(0, delay); } -TEST(SocketTest, TestTCPServerSocketListenAccept) { - std::unique_ptr<MockTCPServerSocket> tcp_server_socket( - new MockTCPServerSocket()); - CompleteHandler handler; +TEST_P(TCPSocketSettingsTest, SetKeepAlive) { + std::unique_ptr<TCPSocket> socket = CreateAndConnectSocket(); + bool expected_success = GetParam(); + { + base::RunLoop run_loop; + socket->SetKeepAlive(true /* enable */, 123 /* delay */, + base::BindLambdaForTesting([&](bool success) { + EXPECT_EQ(expected_success, success); + run_loop.Quit(); + })); + run_loop.Run(); + } - EXPECT_CALL(*tcp_server_socket, Accept(_, _)).Times(1); - EXPECT_CALL(*tcp_server_socket, Listen(_, _)).Times(1); + { + base::RunLoop run_loop; + socket->SetKeepAlive(false /* enable */, 123 /* delay */, + base::BindLambdaForTesting([&](bool success) { + EXPECT_EQ(expected_success, success); + run_loop.Quit(); + })); + run_loop.Run(); + } +} - std::unique_ptr<TCPSocket> socket(TCPSocket::CreateServerSocketForTesting( - std::move(tcp_server_socket), FAKE_ID)); +class TCPSocketServerTest : public TCPSocketUnitTestBase { + public: + TCPSocketServerTest() : TCPSocketUnitTestBase() { Initialize(); } + ~TCPSocketServerTest() override {} - EXPECT_CALL(handler, OnAcceptMock(_, _)); + private: + net::MockClientSocketFactory mock_client_socket_factory_; +}; - std::string err_msg; - EXPECT_EQ(net::OK, socket->Listen("127.0.0.1", 9999, 10, &err_msg)); - socket->Accept(base::Bind(&CompleteHandler::OnAccept, - base::Unretained(&handler))); +TEST_F(TCPSocketServerTest, ListenAccept) { + // Create a server socket. + std::unique_ptr<TCPSocket> socket = CreateSocket(); + net::TestCompletionCallback callback; + base::RunLoop run_loop; + socket->Listen( + "127.0.0.1", 0 /* port */, 1 /* backlog */, + base::BindLambdaForTesting([&](int result, const std::string& error_msg) { + EXPECT_EQ(net::OK, result); + run_loop.Quit(); + })); + run_loop.Run(); + net::IPEndPoint server_addr; + EXPECT_TRUE(socket->GetLocalAddress(&server_addr)); + + base::RunLoop accept_run_loop; + net::IPEndPoint accept_client_addr; + socket->Accept(base::BindLambdaForTesting( + [&](int result, network::mojom::TCPConnectedSocketPtr accepted_socket, + const base::Optional<net::IPEndPoint>& remote_addr, + mojo::ScopedDataPipeConsumerHandle receive_handle, + mojo::ScopedDataPipeProducerHandle send_handle) { + EXPECT_EQ(net::OK, result); + accept_client_addr = remote_addr.value(); + accept_run_loop.Quit(); + })); + + // Create a client socket to talk to the server socket. + auto client_socket = CreateAndConnectSocketWithAddress(server_addr); + accept_run_loop.Run(); + + net::IPEndPoint peer_addr; + EXPECT_TRUE(client_socket->GetPeerAddress(&peer_addr)); + net::IPEndPoint client_addr; + EXPECT_TRUE(client_socket->GetLocalAddress(&client_addr)); + EXPECT_EQ(server_addr, peer_addr); + EXPECT_EQ(client_addr, accept_client_addr); +} + +TEST_F(TCPSocketServerTest, ReadAndWrite) { + // Create a server socket. + std::unique_ptr<TCPSocket> socket = CreateSocket(); + net::TestCompletionCallback callback; + base::RunLoop run_loop; + socket->Listen( + "127.0.0.1", 0 /* port */, 1 /* backlog */, + base::BindLambdaForTesting([&](int result, const std::string& error_msg) { + EXPECT_EQ(net::OK, result); + run_loop.Quit(); + })); + run_loop.Run(); + net::IPEndPoint server_addr; + EXPECT_TRUE(socket->GetLocalAddress(&server_addr)); + + base::RunLoop accept_run_loop; + std::unique_ptr<TCPSocket> accepted_socket; + + socket->Accept(base::BindLambdaForTesting( + [&](int result, network::mojom::TCPConnectedSocketPtr connected_socket, + const base::Optional<net::IPEndPoint>& remote_addr, + mojo::ScopedDataPipeConsumerHandle receive_handle, + mojo::ScopedDataPipeProducerHandle send_handle) { + EXPECT_EQ(net::OK, result); + accepted_socket = std::make_unique<TCPSocket>( + std::move(connected_socket), std::move(receive_handle), + std::move(send_handle), remote_addr, FAKE_ID); + accept_run_loop.Quit(); + })); + + // Create a client socket to talk to the server socket. + auto client_socket = CreateAndConnectSocketWithAddress(server_addr); + net::TestCompletionCallback connect_callback; + accept_run_loop.Run(); + + // Send data from the client to the server. + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + net::TestCompletionCallback write_callback; + client_socket->Write(io_buffer.get(), kTestMsgLength, + write_callback.callback()); + EXPECT_EQ(kTestMsgLength, write_callback.WaitForResult()); + + std::string received_contents; + while (received_contents.size() < kTestMsgLength) { + base::RunLoop run_loop; + accepted_socket->Read( + kTestMsgLength, + base::BindLambdaForTesting([&](int result, + scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + ASSERT_GT(result, 0); + EXPECT_FALSE(socket_destroying); + received_contents.append(std::string(io_buffer->data(), result)); + run_loop.Quit(); + })); + run_loop.Run(); + } + EXPECT_EQ(kTestMsg, received_contents); + + // Send data from the server to the client. + net::TestCompletionCallback write_callback2; + accepted_socket->Write(io_buffer.get(), kTestMsgLength, + write_callback2.callback()); + EXPECT_EQ(kTestMsgLength, write_callback2.WaitForResult()); + + std::string sent_contents; + while (sent_contents.size() < kTestMsgLength) { + base::RunLoop run_loop; + client_socket->Read( + kTestMsgLength, + base::BindLambdaForTesting([&](int result, + scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + ASSERT_GT(result, 0); + EXPECT_FALSE(socket_destroying); + sent_contents.append(std::string(io_buffer->data(), result)); + run_loop.Quit(); + })); + run_loop.Run(); + } + EXPECT_EQ(kTestMsg, sent_contents); } } // namespace extensions
diff --git a/chrome/browser/extensions/api/socket/tls_socket_unittest.cc b/chrome/browser/extensions/api/socket/tls_socket_unittest.cc index 678b630..5e25fcf0 100644 --- a/chrome/browser/extensions/api/socket/tls_socket_unittest.cc +++ b/chrome/browser/extensions/api/socket/tls_socket_unittest.cc
@@ -2,372 +2,482 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <stddef.h> -#include <stdint.h> - #include <memory> #include <utility> -#include "base/callback_helpers.h" -#include "base/containers/circular_deque.h" #include "base/macros.h" -#include "base/strings/string_piece.h" +#include "base/test/bind_test_util.h" +#include "chrome/browser/extensions/extension_service_test_base.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/browser/browser_context.h" +#include "content/public/test/test_storage_partition.h" #include "extensions/browser/api/socket/tls_socket.h" #include "net/base/address_list.h" #include "net/base/completion_callback.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" -#include "net/base/rand_callback.h" -#include "net/log/net_log_source.h" -#include "net/log/net_log_with_source.h" -#include "net/socket/next_proto.h" -#include "net/socket/socket_tag.h" -#include "net/socket/ssl_client_socket.h" -#include "net/socket/tcp_client_socket.h" -#include "net/traffic_annotation/network_traffic_annotation.h" -#include "testing/gmock/include/gmock/gmock.h" - -using testing::_; -using testing::DoAll; -using testing::Invoke; -using testing::Gt; -using testing::Return; -using testing::SaveArg; -using testing::WithArgs; -using base::StringPiece; +#include "net/base/test_completion_callback.h" +#include "net/socket/socket_test_util.h" +#include "net/url_request/url_request_test_util.h" +#include "services/network/network_context.h" +#include "services/network/public/mojom/network_context.mojom.h" namespace extensions { -class MockSSLClientSocket : public net::SSLClientSocket { +namespace { + +const char kTestMsg[] = "abcdefghij"; +const int kTestMsgLength = strlen(kTestMsg); + +const char FAKE_ID[] = "abcdefghijklmnopqrst"; + +class TLSSocketTestBase : public extensions::ExtensionServiceTestBase { public: - MockSSLClientSocket() {} - int Read(net::IOBuffer* buffer, - int bytes, - net::CompletionOnceCallback callback) override { - return Read(buffer, bytes, - base::AdaptCallbackForRepeating(std::move(callback))); + TLSSocketTestBase() : url_request_context_(true) {} + ~TLSSocketTestBase() override {} + + // Creates a TCP socket. + std::unique_ptr<TCPSocket> CreateTCPSocket() { + auto socket = std::make_unique<TCPSocket>(&profile_, FAKE_ID); + socket->SetStoragePartitionForTest(&partition_); + net::TestCompletionCallback connect_callback; + net::IPEndPoint ip_end_point(net::IPAddress::IPv4Localhost(), kPort); + socket->Connect(net::AddressList(ip_end_point), + connect_callback.callback()); + if (net::OK != connect_callback.WaitForResult()) { + return nullptr; + } + return socket; } - int Write(net::IOBuffer* buffer, - int bytes, - net::CompletionOnceCallback callback, - const net::NetworkTrafficAnnotationTag& tag) override { - return Write(buffer, bytes, - base::AdaptCallbackForRepeating(std::move(callback)), tag); + // Create a TCP socket and upgrade it to TLS. + std::unique_ptr<TLSSocket> CreateSocket() { + auto socket = CreateTCPSocket(); + if (!socket) + return nullptr; + base::RunLoop run_loop; + net::HostPortPair host_port_pair("example.com", kPort); + net::IPEndPoint local_addr; + net::IPEndPoint peer_addr; + if (!socket->GetLocalAddress(&local_addr) || + !socket->GetPeerAddress(&peer_addr)) { + return nullptr; + } + std::unique_ptr<TLSSocket> tls_socket; + socket->UpgradeToTLS( + nullptr /* options */, + base::BindLambdaForTesting( + [&](int result, network::mojom::TLSClientSocketPtr tls_socket_ptr, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_handle, + mojo::ScopedDataPipeProducerHandle send_handle) { + if (net::OK == result) { + tls_socket = std::make_unique<TLSSocket>( + std::move(tls_socket_ptr), local_addr, peer_addr, + std::move(receive_handle), std::move(send_handle), FAKE_ID); + } + run_loop.Quit(); + })); + run_loop.Run(); + return tls_socket; } - int Connect(net::CompletionOnceCallback callback) override { - return Connect(base::AdaptCallbackForRepeating(std::move(callback))); - } - - MOCK_METHOD0(Disconnect, void()); - MOCK_METHOD3(Read, - int(net::IOBuffer* buf, - int buf_len, - const net::CompletionCallback& callback)); - MOCK_METHOD4(Write, - int(net::IOBuffer* buf, - int buf_len, - const net::CompletionCallback& callback, - const net::NetworkTrafficAnnotationTag&)); - MOCK_METHOD1(SetReceiveBufferSize, int(int32_t)); - MOCK_METHOD1(SetSendBufferSize, int(int32_t)); - MOCK_METHOD1(Connect, int(const CompletionCallback&)); - MOCK_CONST_METHOD0(IsConnectedAndIdle, bool()); - MOCK_CONST_METHOD1(GetPeerAddress, int(net::IPEndPoint*)); - MOCK_CONST_METHOD1(GetLocalAddress, int(net::IPEndPoint*)); - MOCK_CONST_METHOD0(NetLog, const net::NetLogWithSource&()); - MOCK_CONST_METHOD0(WasEverUsed, bool()); - MOCK_CONST_METHOD0(UsingTCPFastOpen, bool()); - MOCK_CONST_METHOD0(WasAlpnNegotiated, bool()); - MOCK_CONST_METHOD0(GetNegotiatedProtocol, net::NextProto()); - MOCK_METHOD1(GetSSLInfo, bool(net::SSLInfo*)); - MOCK_CONST_METHOD1(GetConnectionAttempts, void(net::ConnectionAttempts*)); - MOCK_METHOD0(ClearConnectionAttempts, void()); - MOCK_METHOD1(AddConnectionAttempts, void(const net::ConnectionAttempts&)); - MOCK_CONST_METHOD0(GetTotalReceivedBytes, int64_t()); - MOCK_METHOD1(ApplySocketTag, void(const net::SocketTag&)); - MOCK_METHOD5(ExportKeyingMaterial, - int(const StringPiece&, - bool, - const StringPiece&, - unsigned char*, - unsigned int)); - MOCK_CONST_METHOD1(GetSSLCertRequestInfo, void(net::SSLCertRequestInfo*)); - MOCK_CONST_METHOD0(GetUnverifiedServerCertificateChain, - scoped_refptr<net::X509Certificate>()); - MOCK_CONST_METHOD0(GetChannelIDService, net::ChannelIDService*()); - MOCK_METHOD3(GetTokenBindingSignature, - net::Error(crypto::ECPrivateKey*, - net::TokenBindingType, - std::vector<uint8_t>*)); - MOCK_CONST_METHOD0(GetChannelIDKey, crypto::ECPrivateKey*()); - bool IsConnected() const override { return true; } - - private: - DISALLOW_COPY_AND_ASSIGN(MockSSLClientSocket); -}; - -class MockTCPSocket : public net::TCPClientSocket { - public: - explicit MockTCPSocket(const net::AddressList& address_list) - : net::TCPClientSocket(address_list, NULL, NULL, net::NetLogSource()) {} - - int Read(net::IOBuffer* buffer, - int bytes, - net::CompletionOnceCallback callback) override { - return Read(buffer, bytes, - base::AdaptCallbackForRepeating(std::move(callback))); - } - - int Write(net::IOBuffer* buffer, - int bytes, - net::CompletionOnceCallback callback, - const net::NetworkTrafficAnnotationTag& tag) override { - return Write(buffer, bytes, - base::AdaptCallbackForRepeating(std::move(callback)), tag); - } - - MOCK_METHOD3(Read, - int(net::IOBuffer* buf, - int buf_len, - const net::CompletionCallback& callback)); - MOCK_METHOD4(Write, - int(net::IOBuffer* buf, - int buf_len, - const net::CompletionCallback& callback, - const net::NetworkTrafficAnnotationTag&)); - MOCK_METHOD2(SetKeepAlive, bool(bool enable, int delay)); - MOCK_METHOD1(SetNoDelay, bool(bool no_delay)); - - bool IsConnected() const override { return true; } - - private: - DISALLOW_COPY_AND_ASSIGN(MockTCPSocket); -}; - -class CompleteHandler { - public: - CompleteHandler() {} - MOCK_METHOD1(OnComplete, void(int result_code)); - MOCK_METHOD3(OnReadComplete, - void(int result_code, - scoped_refptr<net::IOBuffer> io_buffer, - bool socket_destroying)); - MOCK_METHOD2(OnAccept, void(int, net::TCPClientSocket*)); - - private: - DISALLOW_COPY_AND_ASSIGN(CompleteHandler); -}; - -class TLSSocketTest : public ::testing::Test { - public: - TLSSocketTest() {} - - void SetUp() override { - net::AddressList address_list; - // |ssl_socket_| is owned by |socket_|. TLSSocketTest keeps a pointer to - // it to expect invocations from TLSSocket to |ssl_socket_|. - std::unique_ptr<MockSSLClientSocket> ssl_sock(new MockSSLClientSocket); - ssl_socket_ = ssl_sock.get(); - socket_.reset(new TLSSocket(std::move(ssl_sock), "test_extension_id")); - EXPECT_CALL(*ssl_socket_, Disconnect()).Times(1); - }; - - void TearDown() override { - ssl_socket_ = NULL; - socket_.reset(); - }; - protected: - MockSSLClientSocket* ssl_socket_; - std::unique_ptr<TLSSocket> socket_; + // extensions::ExtensionServiceTestBase implementation. + void SetUp() override { InitializeEmptyExtensionService(); } + + void Initialize() { + url_request_context_.Init(); + network_context_ = std::make_unique<network::NetworkContext>( + nullptr, mojo::MakeRequest(&network_context_ptr_), + &url_request_context_); + partition_.set_network_context(network_context_ptr_.get()); + } + + net::TestURLRequestContext url_request_context_; + + private: + static const int kPort = 1234; + TestingProfile profile_; + content::TestStoragePartition partition_; + std::unique_ptr<network::NetworkContext> network_context_; + network::mojom::NetworkContextPtr network_context_ptr_; }; -// Verify that a Read() on TLSSocket will pass through into a Read() on -// |ssl_socket_| and invoke its completion callback. -TEST_F(TLSSocketTest, TestTLSSocketRead) { - CompleteHandler handler; +} // namespace - EXPECT_CALL(*ssl_socket_, Read(_, _, _)).Times(1); - EXPECT_CALL(handler, OnReadComplete(_, _, _)).Times(1); +class TLSSocketTest : public TLSSocketTestBase, + public ::testing::WithParamInterface<net::IoMode> { + public: + TLSSocketTest() : TLSSocketTestBase() { + mock_client_socket_factory_.set_enable_read_if_ready(true); + url_request_context_.set_client_socket_factory( + &mock_client_socket_factory_); + Initialize(); + } + ~TLSSocketTest() override {} + + net::MockClientSocketFactory* mock_client_socket_factory() { + return &mock_client_socket_factory_; + } + + private: + net::MockClientSocketFactory mock_client_socket_factory_; +}; + +TEST_F(TLSSocketTest, DestroyWhileReadPending) { + const net::MockRead kReads[] = {net::MockRead(net::SYNCHRONOUS, net::OK, 1)}; + const net::MockWrite kWrites[] = { + net::MockWrite(net::ASYNC, kTestMsg, kTestMsgLength, 0)}; + net::StaticSocketDataProvider data_provider(kReads, kWrites); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK); + mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); + + std::unique_ptr<TLSSocket> socket = CreateSocket(); + + int net_result = net::ERR_FAILED; + base::RunLoop run_loop; + int count = 1; + // Read one byte, and it should be pending because it is blocked on the mock + // write. + socket->Read(count, + base::BindLambdaForTesting( + [&](int result, scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + net_result = result; + // |socket_destroying| should correctly denote that this + // read callback is invoked through the destructor of + // TLSSocket. + EXPECT_TRUE(socket_destroying); + run_loop.Quit(); + })); + // Destroy socket. + socket = nullptr; + // Wait for read callback. + run_loop.Run(); + EXPECT_EQ(net::ERR_CONNECTION_CLOSED, net_result); +} + +// UpgradeToTLS() fails when there is a pending read. +TEST_F(TLSSocketTest, UpgradeToTLSWhilePendingRead) { + const net::MockRead kReads[] = { + net::MockRead(net::ASYNC, net::ERR_IO_PENDING)}; + net::StaticSocketDataProvider data_provider(kReads, + base::span<net::MockWrite>()); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + auto socket = CreateTCPSocket(); + // This read will be pending when UpgradeToTLS() is called. + socket->Read(1 /* count */, base::DoNothing()); + network::mojom::TLSClientSocketPtr tls_socket_ptr; + base::RunLoop run_loop; + socket->UpgradeToTLS( + nullptr /* options */, + base::BindLambdaForTesting( + [&](int result, network::mojom::TLSClientSocketPtr tls_socket_ptr, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_handle, + mojo::ScopedDataPipeProducerHandle send_handle) { + EXPECT_EQ(net::ERR_FAILED, result); + run_loop.Quit(); + })); + run_loop.Run(); +} + +TEST_F(TLSSocketTest, UpgradeToTLSWithCustomOptions) { + // Mock data are not consumed. These are here so that net::StreamSocket::Read + // is always pending and blocked on the write. Otherwise, mock socket data + // will complains that there aren't any data to read. + const net::MockRead kReads[] = { + net::MockRead(net::ASYNC, kTestMsg, kTestMsgLength, 1), + net::MockRead(net::ASYNC, net::OK, 2)}; + const net::MockWrite kWrites[] = { + net::MockWrite(net::ASYNC, kTestMsg, kTestMsgLength, 0)}; + net::SequencedSocketData data_provider(kReads, kWrites); + net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK); + ssl_socket.expected_ssl_version_min = net::SSL_PROTOCOL_VERSION_TLS1_1; + ssl_socket.expected_ssl_version_max = net::SSL_PROTOCOL_VERSION_TLS1_2; + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); + + auto socket = CreateTCPSocket(); + network::mojom::TLSClientSocketPtr tls_socket_ptr; + api::socket::SecureOptions options; + options.tls_version = std::make_unique<api::socket::TLSVersionConstraints>(); + options.tls_version->min = std::make_unique<std::string>("tls1.1"); + options.tls_version->max = std::make_unique<std::string>("tls1.2"); + int net_error = net::ERR_FAILED; + base::RunLoop run_loop; + socket->UpgradeToTLS( + &options, + base::BindLambdaForTesting( + [&](int result, network::mojom::TLSClientSocketPtr tls_socket_ptr, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_handle, + mojo::ScopedDataPipeProducerHandle send_handle) { + net_error = result; + run_loop.Quit(); + })); + run_loop.Run(); + EXPECT_EQ(net::OK, net_error); + EXPECT_TRUE(ssl_socket.ConnectDataConsumed()); +} + +INSTANTIATE_TEST_CASE_P(/* no prefix */, + TLSSocketTest, + testing::Values(net::SYNCHRONOUS, net::ASYNC)); + +TEST_P(TLSSocketTest, ReadWrite) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(net::ASYNC, kTestMsg, kTestMsgLength, 1), + net::MockRead(io_mode, net::OK, 2)}; + const net::MockWrite kWrites[] = { + net::MockWrite(net::SYNCHRONOUS, kTestMsg, kTestMsgLength, 0)}; + net::SequencedSocketData data_provider(kReads, kWrites); + net::SSLSocketDataProvider ssl_socket(io_mode, net::OK); + + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); + std::unique_ptr<TLSSocket> socket = CreateSocket(); + + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + net::TestCompletionCallback write_callback; + socket->Write(io_buffer.get(), kTestMsgLength, write_callback.callback()); + EXPECT_EQ(kTestMsgLength, write_callback.WaitForResult()); + + std::string received_data; + int count = 512; + while (true) { + base::RunLoop run_loop; + int net_error = net::ERR_FAILED; + socket->Read(count, + base::BindLambdaForTesting( + [&](int result, scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + net_error = result; + EXPECT_FALSE(socket_destroying); + if (result > 0) + received_data.append(io_buffer->data(), result); + run_loop.Quit(); + })); + run_loop.Run(); + if (net_error <= 0) + break; + } + EXPECT_EQ(kTestMsg, received_data); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); + EXPECT_TRUE(ssl_socket.ConnectDataConsumed()); +} + +// Tests the case where read size is smaller than the actual message. +TEST_P(TLSSocketTest, PartialRead) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(net::ASYNC, kTestMsg, kTestMsgLength, 1), + net::MockRead(io_mode, net::OK, 2)}; + const net::MockWrite kWrites[] = { + net::MockWrite(net::SYNCHRONOUS, kTestMsg, kTestMsgLength, 0)}; + net::SequencedSocketData data_provider(kReads, kWrites); + net::SSLSocketDataProvider ssl_socket(io_mode, net::OK); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); + std::unique_ptr<TLSSocket> socket = CreateSocket(); + + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + net::TestCompletionCallback write_callback; + socket->Write(io_buffer.get(), kTestMsgLength, write_callback.callback()); + EXPECT_EQ(kTestMsgLength, write_callback.WaitForResult()); + + int count = 1; + std::string received_data; + while (true) { + int net_result = net::ERR_FAILED; + base::RunLoop run_loop; + socket->Read(count, + base::BindLambdaForTesting( + [&](int result, scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + net_result = result; + EXPECT_FALSE(socket_destroying); + if (result > 0) + received_data.append(io_buffer->data(), result); + run_loop.Quit(); + })); + run_loop.Run(); + if (net_result <= 0) + break; + // Double the read size in the next iteration. + count *= 2; + } + EXPECT_EQ(kTestMsg, received_data); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); + EXPECT_TRUE(ssl_socket.ConnectDataConsumed()); +} + +TEST_P(TLSSocketTest, ReadError) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = { + net::MockRead(net::ASYNC, net::ERR_INSUFFICIENT_RESOURCES, 1)}; + const net::MockWrite kWrites[] = { + net::MockWrite(net::SYNCHRONOUS, kTestMsg, kTestMsgLength, 0)}; + net::SequencedSocketData data_provider(kReads, kWrites); + net::SSLSocketDataProvider ssl_socket(io_mode, net::OK); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); + + std::unique_ptr<TLSSocket> socket = CreateSocket(); + + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + net::TestCompletionCallback write_callback; + socket->Write(io_buffer.get(), kTestMsgLength, write_callback.callback()); + EXPECT_EQ(kTestMsgLength, write_callback.WaitForResult()); const int count = 512; - socket_->Read( - count, - base::Bind(&CompleteHandler::OnReadComplete, base::Unretained(&handler))); + int net_error = net::OK; + while (true) { + base::RunLoop run_loop; + socket->Read(count, + base::BindLambdaForTesting( + [&](int result, scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying) { + net_error = result; + EXPECT_FALSE(socket_destroying); + if (result <= 0) { + EXPECT_FALSE(socket->IsConnected()); + EXPECT_EQ(nullptr, io_buffer); + } else { + EXPECT_TRUE(socket->IsConnected()); + } + run_loop.Quit(); + })); + run_loop.Run(); + if (net_error < 0) + break; + } + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); + EXPECT_TRUE(ssl_socket.ConnectDataConsumed()); } -// Verify that a Write() on a TLSSocket will pass through to Write() -// invocations on |ssl_socket_|, handling partial writes correctly, and calls -// the completion callback correctly. -TEST_F(TLSSocketTest, TestTLSSocketWrite) { - CompleteHandler handler; - net::CompletionCallback callback; +// Tests the case where a message is split over two separate socket writes. +TEST_P(TLSSocketTest, MultipleWrite) { + const char kFirstHalfTestMsg[] = "abcde"; + const char kSecondHalfTestMsg[] = "fghij"; + EXPECT_EQ(kTestMsg, std::string(kFirstHalfTestMsg) + kSecondHalfTestMsg); + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 2)}; + const net::MockWrite kWrites[] = { + net::MockWrite(io_mode, kFirstHalfTestMsg, strlen(kFirstHalfTestMsg), 0), + net::MockWrite(io_mode, kSecondHalfTestMsg, strlen(kSecondHalfTestMsg), + 1)}; + net::SequencedSocketData data_provider(kReads, kWrites); + net::SSLSocketDataProvider ssl_socket(io_mode, net::OK); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); + std::unique_ptr<TLSSocket> socket = CreateSocket(); - EXPECT_CALL(*ssl_socket_, Write(_, _, _, _)) - .Times(2) - .WillRepeatedly(DoAll(SaveArg<2>(&callback), Return(128))); - EXPECT_CALL(handler, OnComplete(_)).Times(1); - - scoped_refptr<net::IOBufferWithSize> io_buffer( - new net::IOBufferWithSize(256)); - socket_->Write( - io_buffer.get(), - io_buffer->size(), - base::Bind(&CompleteHandler::OnComplete, base::Unretained(&handler))); + int num_bytes_written = 0; + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + auto drainable_io_buffer = base::MakeRefCounted<net::DrainableIOBuffer>( + io_buffer.get(), kTestMsgLength); + while (num_bytes_written < kTestMsgLength) { + net::TestCompletionCallback write_callback; + socket->Write(drainable_io_buffer.get(), kTestMsgLength - num_bytes_written, + write_callback.callback()); + int result = write_callback.WaitForResult(); + ASSERT_GT(result, net::OK); + drainable_io_buffer->DidConsume(result); + num_bytes_written += result; + // Flushes the write. + base::RunLoop().RunUntilIdle(); + } + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); + EXPECT_TRUE(ssl_socket.ConnectDataConsumed()); } -// Simulate a blocked Write, and verify that, when simulating the Write going -// through, the callback gets invoked. -TEST_F(TLSSocketTest, TestTLSSocketBlockedWrite) { - CompleteHandler handler; - net::CompletionCallback callback; +TEST_P(TLSSocketTest, PartialWrite) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 4)}; + const net::MockWrite kWrites[] = {net::MockWrite(io_mode, "a", 1, 0), + net::MockWrite(io_mode, "bc", 2, 1), + net::MockWrite(io_mode, "defg", 4, 2), + net::MockWrite(io_mode, "hij", 3, 3)}; - // Return ERR_IO_PENDING to say the Write()'s blocked. Save the |callback| - // Write()'s passed. - EXPECT_CALL(*ssl_socket_, Write(_, _, _, _)) - .Times(2) - .WillRepeatedly( - DoAll(SaveArg<2>(&callback), Return(net::ERR_IO_PENDING))); + net::SequencedSocketData data_provider(kReads, kWrites); + net::SSLSocketDataProvider ssl_socket(io_mode, net::OK); - scoped_refptr<net::IOBufferWithSize> io_buffer(new net::IOBufferWithSize(42)); - socket_->Write( - io_buffer.get(), - io_buffer->size(), - base::Bind(&CompleteHandler::OnComplete, base::Unretained(&handler))); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); - // After the simulated asynchronous writes come back (via calls to - // callback.Run()), hander's OnComplete() should get invoked with the total - // amount written. - EXPECT_CALL(handler, OnComplete(42)).Times(1); - callback.Run(40); - callback.Run(2); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + std::unique_ptr<TLSSocket> socket = CreateSocket(); + + // Start with writing one byte, and double that in the next iteration. + int num_bytes_to_write = 1; + int num_bytes_written = 0; + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + auto drainable_io_buffer = base::MakeRefCounted<net::DrainableIOBuffer>( + io_buffer.get(), kTestMsgLength); + while (num_bytes_written < kTestMsgLength) { + net::TestCompletionCallback write_callback; + socket->Write( + drainable_io_buffer.get(), + std::max(kTestMsgLength - num_bytes_written, num_bytes_to_write), + write_callback.callback()); + int result = write_callback.WaitForResult(); + ASSERT_GT(result, net::OK); + drainable_io_buffer->DidConsume(result); + num_bytes_written += result; + num_bytes_to_write *= 2; + // Flushes the write. + base::RunLoop().RunUntilIdle(); + } + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); + EXPECT_TRUE(ssl_socket.ConnectDataConsumed()); } -// Simulate multiple blocked Write()s. -TEST_F(TLSSocketTest, TestTLSSocketBlockedWriteReentry) { - const int kNumIOs = 5; - CompleteHandler handlers[kNumIOs]; - net::CompletionCallback callback; - scoped_refptr<net::IOBufferWithSize> io_buffers[kNumIOs]; +TEST_P(TLSSocketTest, WriteError) { + net::IoMode io_mode = GetParam(); + const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 1)}; + const net::MockWrite kWrites[] = { + net::MockWrite(io_mode, net::ERR_INSUFFICIENT_RESOURCES, 0)}; - // The implementation of TLSSocket::Write() is inherited from - // Socket::Write(), which implements an internal write queue that wraps - // TLSSocket::WriteImpl(). Each call from TLSSocket::WriteImpl() will invoke - // |ssl_socket_|'s Write() (mocked here). Save the |callback| (assume they - // will all be equivalent), and return ERR_IO_PENDING, to indicate a blocked - // request. The mocked SSLClientSocket::Write() will get one request per - // TLSSocket::Write() request invoked on |socket_| below. - EXPECT_CALL(*ssl_socket_, Write(_, _, _, _)) - .Times(kNumIOs) - .WillRepeatedly( - DoAll(SaveArg<2>(&callback), Return(net::ERR_IO_PENDING))); + net::SequencedSocketData data_provider(kReads, kWrites); + net::SSLSocketDataProvider ssl_socket(io_mode, net::OK); - // Send out |kNuMIOs| requests, each with a different size. - for (int i = 0; i < kNumIOs; i++) { - io_buffers[i] = new net::IOBufferWithSize(128 + i * 50); - socket_->Write(io_buffers[i].get(), - io_buffers[i]->size(), - base::Bind(&CompleteHandler::OnComplete, - base::Unretained(&handlers[i]))); + mock_client_socket_factory()->AddSocketDataProvider(&data_provider); + mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket); + std::unique_ptr<TLSSocket> socket = CreateSocket(); - // Set up expectations on all |kNumIOs| handlers. - EXPECT_CALL(handlers[i], OnComplete(io_buffers[i]->size())).Times(1); + // Mojo data pipe might buffer some write data, so continue writing until the + // write error is received. + auto io_buffer = base::MakeRefCounted<net::StringIOBuffer>(kTestMsg); + int net_error = net::OK; + while (true) { + base::RunLoop run_loop; + socket->Write(io_buffer.get(), kTestMsgLength, + base::BindLambdaForTesting([&](int result) { + if (result == net::ERR_FAILED) + EXPECT_FALSE(socket->IsConnected()); + net_error = result; + run_loop.Quit(); + })); + run_loop.Run(); + if (net_error <= 0) + break; } - - // Finish each pending I/O. This should satisfy the expectations on the - // handlers. - for (int i = 0; i < kNumIOs; i++) { - callback.Run(128 + i * 50); - } -} - -typedef std::pair<net::CompletionCallback, int> PendingCallback; - -class CallbackList : public base::circular_deque<PendingCallback> { - public: - void append(const net::CompletionCallback& cb, int arg) { - push_back(std::make_pair(cb, arg)); - } -}; - -// Simulate Write()s above and below a SSLClientSocket size limit. -TEST_F(TLSSocketTest, TestTLSSocketLargeWrites) { - const int kSizeIncrement = 4096; - const int kNumIncrements = 10; - const int kFragmentIncrement = 4; - const int kSizeLimit = kSizeIncrement * kFragmentIncrement; - net::CompletionCallback callback; - CompleteHandler handler; - scoped_refptr<net::IOBufferWithSize> io_buffers[kNumIncrements]; - CallbackList pending_callbacks; - size_t total_bytes_requested = 0; - size_t total_bytes_written = 0; - - // Some implementations of SSLClientSocket may have write-size limits (e.g, - // max 1 TLS record, which is 16k). This test mocks a size limit at - // |kSizeIncrement| and calls Write() above and below that limit. It - // simulates SSLClientSocket::Write() behavior in only writing up to the size - // limit, requiring additional calls for the remaining data to be sent. - // Socket::Write() (and supporting methods) execute the additional calls as - // needed. This test verifies that this inherited implementation does - // properly issue additional calls, and that the total amount returned from - // all mocked SSLClientSocket::Write() calls is the same as originally - // requested. - - // |ssl_socket_|'s Write() will write at most |kSizeLimit| bytes. The - // inherited Socket::Write() will repeatedly call |ssl_socket_|'s Write() - // until the entire original request is sent. Socket::Write() will queue any - // additional write requests until the current request is complete. A - // request is complete when the callback passed to Socket::WriteImpl() is - // invoked with an argument equal to the original number of bytes requested - // from Socket::Write(). If the callback is invoked with a smaller number, - // Socket::WriteImpl() will get repeatedly invoked until the sum of the - // callbacks' arguments is equal to the original requested amount. - EXPECT_CALL(*ssl_socket_, Write(_, _, _, _)) - .WillRepeatedly(DoAll( - WithArgs<2, 1>(Invoke(&pending_callbacks, &CallbackList::append)), - Return(net::ERR_IO_PENDING))); - - // Observe what comes back from Socket::Write() here. - EXPECT_CALL(handler, OnComplete(Gt(0))).Times(kNumIncrements); - - // Send out |kNumIncrements| requests, each with a different size. The - // last request is the same size as the first, and the ones in the middle - // are monotonically increasing from the first. - for (int i = 0; i < kNumIncrements; i++) { - const bool last = i == (kNumIncrements - 1); - io_buffers[i] = new net::IOBufferWithSize(last ? kSizeIncrement - : kSizeIncrement * (i + 1)); - total_bytes_requested += io_buffers[i]->size(); - - // Invoke Socket::Write(). This will invoke |ssl_socket_|'s Write(), which - // this test mocks out. That mocked Write() is in an asynchronous waiting - // state until the passed callback (saved in the EXPECT_CALL for - // |ssl_socket_|'s Write()) is invoked. - socket_->Write( - io_buffers[i].get(), - io_buffers[i]->size(), - base::Bind(&CompleteHandler::OnComplete, base::Unretained(&handler))); - } - - // Invoke callbacks for pending I/Os. These can synchronously invoke more of - // |ssl_socket_|'s Write() as needed. The callback checks how much is left - // in the request, and then starts issuing any queued Socket::Write() - // invocations. - while (!pending_callbacks.empty()) { - PendingCallback cb = pending_callbacks.front(); - pending_callbacks.pop_front(); - - int amount_written_invocation = std::min(kSizeLimit, cb.second); - total_bytes_written += amount_written_invocation; - cb.first.Run(amount_written_invocation); - } - - ASSERT_EQ(total_bytes_requested, total_bytes_written) - << "There should be exactly as many bytes written as originally " - << "requested to Write()."; + // Note that TCPSocket only detects that send pipe is broken and propagates + // it as a net::ERR_FAILED. It doesn't know the specific net error code. To do + // that, it needs to register itself as a network::mojom::SocketObserver. + EXPECT_EQ(net::ERR_FAILED, net_error); } } // namespace extensions
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index d5fccec..09755bb5 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1134,11 +1134,19 @@ const char kNewBookmarkAppsDescription[] = "Enables the new system for creating bookmark apps."; -const char kNewPasswordFormParsingName[] = "New password form parsing"; +const char kNewPasswordFormParsingName[] = + "New password form parsing for filling passwords"; const char kNewPasswordFormParsingDescription[] = - "Replaces existing form parsing in password manager with a new version, " - "currently under development. WARNING: when enabled Password Manager might " - "stop working"; + "Replaces existing form parsing for filling in password manager with a new " + "version, currently under development. WARNING: when enabled, Password " + "Manager might stop working"; + +const char kNewPasswordFormParsingForSavingName[] = + "New password form parsing for saving passwords"; +const char kNewPasswordFormParsingForSavingDescription[] = + "Replaces existing form parsing for saving in password manager with a new " + "version, currently under development. WARNING: when enabled, Password " + "Manager might stop working"; const char kNewRemotePlaybackPipelineName[] = "Enable the new remote playback pipeline.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index dd9999c..3a55f66 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -711,6 +711,9 @@ extern const char kNewPasswordFormParsingName[]; extern const char kNewPasswordFormParsingDescription[]; +extern const char kNewPasswordFormParsingForSavingName[]; +extern const char kNewPasswordFormParsingForSavingDescription[]; + extern const char kNewRemotePlaybackPipelineName[]; extern const char kNewRemotePlaybackPipelineDescription[];
diff --git a/chrome/browser/history/top_sites_factory.cc b/chrome/browser/history/top_sites_factory.cc index 5ca3310..a8746a8 100644 --- a/chrome/browser/history/top_sites_factory.cc +++ b/chrome/browser/history/top_sites_factory.cc
@@ -30,6 +30,7 @@ #include "components/history/core/browser/top_sites_impl.h" #include "components/history/core/browser/top_sites_provider.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/ntp_tiles/constants.h" #include "components/pref_registry/pref_registry_syncable.h" #include "content/public/browser/browser_thread.h" #include "ui/base/l10n/l10n_util.h" @@ -44,23 +45,22 @@ } struct RawPrepopulatedPage { - int url_id; // The resource for the page URL. - int title_id; // The resource for the page title. - int favicon_id; // The raw data resource for the favicon. - int thumbnail_id; // The raw data resource for the thumbnail. - SkColor color; // The best color to highlight the page (should roughly - // match favicon). + int url_id; // The resource for the page URL. + int title_id; // The resource for the page title. + int favicon_id; // The raw data resource for the favicon. + int large_favicon_id; // The raw data resource for the larger favicon. + int thumbnail_id; // The raw data resource for the thumbnail. + SkColor color; // The best color to highlight the page (should + // roughly match favicon). }; #if !defined(OS_ANDROID) // Android does not use prepopulated pages. const RawPrepopulatedPage kRawPrepopulatedPages[] = { { - IDS_WEBSTORE_URL, - IDS_EXTENSION_WEB_STORE_TITLE, - IDR_WEBSTORE_ICON_16, - IDR_NEWTAB_WEBSTORE_THUMBNAIL, - SkColorSetRGB(63, 132, 197), + IDS_WEBSTORE_URL, IDS_EXTENSION_WEB_STORE_TITLE, IDR_WEBSTORE_ICON_16, + IDR_WEBSTORE_ICON_32, IDR_NEWTAB_WEBSTORE_THUMBNAIL, + SkColorSetRGB(63, 132, 197), }, }; #endif @@ -74,7 +74,8 @@ const RawPrepopulatedPage& page = kRawPrepopulatedPages[i]; prepopulated_pages->push_back(history::PrepopulatedPage( GURL(l10n_util::GetStringUTF8(page.url_id)), - l10n_util::GetStringUTF16(page.title_id), page.favicon_id, + l10n_util::GetStringUTF16(page.title_id), + ntp_tiles::IsMDIconsEnabled() ? page.large_favicon_id : page.favicon_id, page.thumbnail_id, page.color)); } #endif
diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn index 880e6ae4..498fae2 100644 --- a/chrome/browser/media/router/BUILD.gn +++ b/chrome/browser/media/router/BUILD.gn
@@ -14,6 +14,7 @@ "//components/keyed_service/core", "//content/public/browser", "//content/public/common", + "//crypto", "//net", "//third_party/icu", "//url", @@ -93,6 +94,8 @@ "providers/cast/cast_app_availability_tracker.h", "providers/cast/cast_app_discovery_service.cc", "providers/cast/cast_app_discovery_service.h", + "providers/cast/cast_internal_message_util.cc", + "providers/cast/cast_internal_message_util.h", "providers/cast/cast_media_route_provider.cc", "providers/cast/cast_media_route_provider.h", "providers/cast/cast_media_route_provider_metrics.cc",
diff --git a/chrome/browser/media/router/media_router_feature.cc b/chrome/browser/media/router/media_router_feature.cc index 487e2f34..8f9385c 100644 --- a/chrome/browser/media/router/media_router_feature.cc +++ b/chrome/browser/media/router/media_router_feature.cc
@@ -4,10 +4,13 @@ #include "chrome/browser/media/router/media_router_feature.h" +#include "base/base64.h" #include "base/feature_list.h" +#include "base/strings/string_util.h" #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_context.h" +#include "crypto/random.h" #include "extensions/buildflags/buildflags.h" #include "ui/base/ui_features.h" @@ -73,6 +76,12 @@ PrefRegistry::PUBLIC); } +void RegisterProfilePrefs(PrefRegistrySimple* registry) { + // TODO(imcheng): Migrate existing Media Router prefs to here. + registry->RegisterStringPref(prefs::kMediaRouterReceiverIdHashToken, "", + PrefRegistry::PUBLIC); +} + const base::Feature kCastAllowAllIPsFeature{"CastAllowAllIPs", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -90,6 +99,19 @@ return allow_all_ips; } +std::string GetReceiverIdHashToken(PrefService* pref_service) { + static constexpr size_t kHashTokenSize = 64; + std::string token = + pref_service->GetString(prefs::kMediaRouterReceiverIdHashToken); + if (token.empty()) { + crypto::RandBytes(base::WriteInto(&token, kHashTokenSize + 1), + kHashTokenSize); + base::Base64Encode(token, &token); + pref_service->SetString(prefs::kMediaRouterReceiverIdHashToken, token); + } + return token; +} + bool DialMediaRouteProviderEnabled() { return base::FeatureList::IsEnabled(kDialMediaRouteProvider); }
diff --git a/chrome/browser/media/router/media_router_feature.h b/chrome/browser/media/router/media_router_feature.h index 73791ef..400912d3 100644 --- a/chrome/browser/media/router/media_router_feature.h +++ b/chrome/browser/media/router/media_router_feature.h
@@ -25,11 +25,18 @@ // Pref name for the enterprise policy for allowing Cast devices on all IPs. constexpr char kMediaRouterCastAllowAllIPs[] = "media_router.cast_allow_all_ips"; +// Pref name for the per-profile randomly generated token to include with the +// hash when externalizing MediaSink IDs. +constexpr char kMediaRouterReceiverIdHashToken[] = + "media_router.receiver_id_hash_token"; } // namespace prefs // Registers |kMediaRouterCastAllowAllIPs| with local state pref |registry|. void RegisterLocalStatePrefs(PrefRegistrySimple* registry); +// Registers Media Router related preferences with per-profile pref |registry|. +void RegisterProfilePrefs(PrefRegistrySimple* registry); + // If enabled, allows Media Router to connect to Cast devices on all IP // addresses, not just RFC1918/RFC4913 private addresses. Workaround for // https://crbug.com/813974. @@ -39,6 +46,11 @@ // all IPs, as determined by local state |pref_service| / feature flag. bool GetCastAllowAllIPsPref(PrefService* pref_service); +// Returns the hash token to use for externalizing MediaSink IDs from +// |pref_service|. If the token does not exist, the token will be created from a +// randomly generated string and stored in |pref_service|. +std::string GetReceiverIdHashToken(PrefService* pref_service); + extern const base::Feature kEnableDialSinkQuery; extern const base::Feature kEnableCastDiscovery; extern const base::Feature kCastMediaRouteProvider;
diff --git a/chrome/browser/media/router/media_router_feature_unittest.cc b/chrome/browser/media/router/media_router_feature_unittest.cc index 16ed5b7..e61e9d4 100644 --- a/chrome/browser/media/router/media_router_feature_unittest.cc +++ b/chrome/browser/media/router/media_router_feature_unittest.cc
@@ -30,4 +30,16 @@ EXPECT_FALSE(GetCastAllowAllIPsPref(pref_service.get())); } +TEST(MediaRouterFeatureTest, GetReceiverIdHashToken) { + auto pref_service = std::make_unique<TestingPrefServiceSimple>(); + pref_service->registry()->RegisterStringPref( + prefs::kMediaRouterReceiverIdHashToken, ""); + + std::string token = GetReceiverIdHashToken(pref_service.get()); + EXPECT_FALSE(token.empty()); + + // Token stays the same on subsequent invocation. + EXPECT_EQ(token, GetReceiverIdHashToken(pref_service.get())); +} + } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc b/chrome/browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc index 591ef24..f2fd454 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc
@@ -76,7 +76,7 @@ TEST_F(CastAppAvailabilityTrackerTest, MultipleAppIdsAlreadyTrackingOne) { // One of the mirroring app IDs. - auto source1 = CastMediaSource::From("cast:0F5096E8"); + auto source1 = CastMediaSource::From("cast:0F5096E8?clientId=123"); ASSERT_TRUE(source1); base::flat_set<std::string> new_app_ids = {"0F5096E8"};
diff --git a/chrome/browser/media/router/providers/cast/cast_internal_message_util.cc b/chrome/browser/media/router/providers/cast/cast_internal_message_util.cc new file mode 100644 index 0000000..a73dfe7 --- /dev/null +++ b/chrome/browser/media/router/providers/cast/cast_internal_message_util.cc
@@ -0,0 +1,394 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h" + +#include "base/base64url.h" +#include "base/json/json_writer.h" +#include "base/memory/ptr_util.h" +#include "base/sha1.h" +#include "chrome/common/media_router/discovery/media_sink_internal.h" +#include "chrome/common/media_router/providers/cast/cast_media_source.h" +#include "components/cast_channel/cast_socket.h" +#include "components/cast_channel/proto/cast_channel.pb.h" +#include "net/base/escape.h" + +namespace media_router { + +namespace { + +constexpr char kClientConnect[] = "client_connect"; +constexpr char kAppMessage[] = "app_message"; +constexpr char kReceiverAction[] = "receiver_action"; +constexpr char kNewSession[] = "new_session"; + +bool GetString(const base::Value& value, + const std::string& key, + std::string* out) { + const base::Value* string_value = + value.FindKeyOfType(key, base::Value::Type::STRING); + if (!string_value) + return false; + + *out = string_value->GetString(); + return !out->empty(); +} + +void CopyValueWithDefault(const base::Value& from, + const std::string& key, + base::Value default_value, + base::Value* to) { + const base::Value* value = from.FindKey(key); + to->SetKey(key, value ? value->Clone() : std::move(default_value)); +} + +void CopyValue(const base::Value& from, + const std::string& key, + base::Value* to) { + const base::Value* value = from.FindKey(key); + if (value) + to->SetKey(key, value->Clone()); +} + +CastInternalMessage::Type CastInternalMessageTypeFromString( + const std::string& type) { + if (type == kClientConnect) + return CastInternalMessage::Type::kClientConnect; + if (type == kAppMessage) + return CastInternalMessage::Type::kAppMessage; + if (type == kReceiverAction) + return CastInternalMessage::Type::kReceiverAction; + if (type == kNewSession) + return CastInternalMessage::Type::kNewSession; + + return CastInternalMessage::Type::kOther; +} + +std::string CastInternalMessageTypeToString(CastInternalMessage::Type type) { + switch (type) { + case CastInternalMessage::Type::kClientConnect: + return kClientConnect; + case CastInternalMessage::Type::kAppMessage: + return kAppMessage; + case CastInternalMessage::Type::kReceiverAction: + return kReceiverAction; + case CastInternalMessage::Type::kNewSession: + return kNewSession; + case CastInternalMessage::Type::kOther: + NOTREACHED(); + return ""; + } + NOTREACHED(); + return ""; +} + +// Possible types in a receiver_action message. +constexpr char kReceiverActionTypeCast[] = "cast"; +constexpr char kReceiverActionTypeStop[] = "stop"; + +base::ListValue CapabilitiesToListValue(uint8_t capabilities) { + base::ListValue value; + auto& storage = value.GetList(); + if (capabilities & cast_channel::VIDEO_OUT) + storage.emplace_back("video_out"); + if (capabilities & cast_channel::VIDEO_IN) + storage.emplace_back("video_in"); + if (capabilities & cast_channel::AUDIO_OUT) + storage.emplace_back("audio_out"); + if (capabilities & cast_channel::AUDIO_IN) + storage.emplace_back("audio_in"); + if (capabilities & cast_channel::MULTIZONE_GROUP) + storage.emplace_back("multizone_group"); + return value; +} + +base::Value CreateReceiver(const MediaSinkInternal& sink, + const std::string& hash_token) { + base::Value receiver(base::Value::Type::DICTIONARY); + + std::string label = base::SHA1HashString(sink.sink().id() + hash_token); + base::Base64UrlEncode(label, base::Base64UrlEncodePolicy::OMIT_PADDING, + &label); + receiver.SetKey("label", base::Value(label)); + + receiver.SetKey("friendlyName", + base::Value(net::EscapeForHTML(sink.sink().name()))); + receiver.SetKey("capabilities", + CapabilitiesToListValue(sink.cast_data().capabilities)); + receiver.SetKey("volume", base::Value()); + receiver.SetKey("isActiveInput", base::Value()); + receiver.SetKey("displayStatus", base::Value()); + + receiver.SetKey("receiverType", base::Value("cast")); + return receiver; +} + +base::Value CreateReceiverActionMessage(const std::string& client_id, + const MediaSinkInternal& sink, + const std::string& hash_token, + const char* action_type) { + base::Value message(base::Value::Type::DICTIONARY); + message.SetKey("receiver", CreateReceiver(sink, hash_token)); + message.SetKey("action", base::Value(action_type)); + + base::Value value(base::Value::Type::DICTIONARY); + value.SetKey("type", base::Value(CastInternalMessageTypeToString( + CastInternalMessage::Type::kReceiverAction))); + value.SetKey("message", std::move(message)); + value.SetKey("sequenceNumber", base::Value(-1)); + value.SetKey("timeoutMillis", base::Value(0)); + value.SetKey("clientId", base::Value(client_id)); + return value; +} + +base::Value CreateAppMessageBody( + const std::string& session_id, + const cast_channel::CastMessage& cast_message) { + // TODO(https://crbug.com/862532): Investigate whether it is possible to move + // instead of copying the contents of |cast_message|. Right now copying is + // done because the message is passed as a const ref at the + // CastSocket::Observer level. + base::Value message(base::Value::Type::DICTIONARY); + message.SetKey("sessionId", base::Value(session_id)); + message.SetKey("namespaceName", base::Value(cast_message.namespace_())); + switch (cast_message.payload_type()) { + case cast_channel::CastMessage_PayloadType_STRING: + message.SetKey("message", base::Value(cast_message.payload_utf8())); + break; + case cast_channel::CastMessage_PayloadType_BINARY: { + const auto& payload = cast_message.payload_binary(); + message.SetKey("message", + base::Value(base::Value::BlobStorage( + payload.front(), payload.front() + payload.size()))); + break; + } + default: + NOTREACHED(); + break; + } + return message; +} + +} // namespace + +// static +std::unique_ptr<CastInternalMessage> CastInternalMessage::From( + base::Value message) { + if (!message.is_dict()) { + DVLOG(2) << "Failed to read JSON message: " << message; + return nullptr; + } + + std::string str_type; + if (!GetString(message, "type", &str_type)) { + DVLOG(2) << "Missing type value, message: " << message; + return nullptr; + } + + CastInternalMessage::Type message_type = + CastInternalMessageTypeFromString(str_type); + if (message_type == CastInternalMessage::Type::kOther) { + DVLOG(2) << __func__ << ": Unsupported message type: " << str_type + << ", message: " << message; + return nullptr; + } + + std::string client_id; + if (!GetString(message, "clientId", &client_id)) { + DVLOG(2) << "Missing clientId, message: " << message; + return nullptr; + } + + base::Value* message_body_value = message.FindKey("message"); + if (!message_body_value || + (!message_body_value->is_dict() && !message_body_value->is_string())) { + DVLOG(2) << "Missing message body, message: " << message; + return nullptr; + } + + auto internal_message = + std::make_unique<CastInternalMessage>(message_type, client_id); + + base::Value* sequence_number_value = + message.FindKeyOfType("sequenceNumber", base::Value::Type::INTEGER); + if (sequence_number_value) + internal_message->sequence_number = sequence_number_value->GetInt(); + + if (message_type == CastInternalMessage::Type::kAppMessage) { + if (!message_body_value->is_dict()) + return nullptr; + + if (!GetString(*message_body_value, "namespaceName", + &internal_message->app_message_namespace) || + !GetString(*message_body_value, "sessionId", + &internal_message->app_message_session_id)) { + DVLOG(2) << "Missing namespace or session ID, message: " << message; + return nullptr; + } + + base::Value* app_message_value = message_body_value->FindKey("message"); + if (!app_message_value || + (!app_message_value->is_dict() && !app_message_value->is_string())) { + DVLOG(2) << "Missing app message, message: " << message; + return nullptr; + } + internal_message->app_message_body = std::move(*app_message_value); + } + + return internal_message; +} + +CastInternalMessage::CastInternalMessage(CastInternalMessage::Type type, + const std::string& client_id) + : type(type), client_id(client_id) {} + +CastInternalMessage::~CastInternalMessage() = default; + +blink::mojom::PresentationConnectionMessagePtr +CreatePresentationConnectionMessage(const base::Value& message) { + std::string str; + CHECK(base::JSONWriter::Write(message, &str)); + return blink::mojom::PresentationConnectionMessage::NewMessage(str); +} + +blink::mojom::PresentationConnectionMessagePtr CreateReceiverActionCastMessage( + const std::string& client_id, + const MediaSinkInternal& sink, + const std::string& hash_token) { + return CreatePresentationConnectionMessage(CreateReceiverActionMessage( + client_id, sink, hash_token, kReceiverActionTypeCast)); +} + +blink::mojom::PresentationConnectionMessagePtr CreateReceiverActionStopMessage( + const std::string& client_id, + const MediaSinkInternal& sink, + const std::string& hash_token) { + return CreatePresentationConnectionMessage(CreateReceiverActionMessage( + client_id, sink, hash_token, kReceiverActionTypeStop)); +} + +// static +std::unique_ptr<CastSession> CastSession::From( + const MediaSinkInternal& sink, + const std::string& hash_token, + const base::Value& receiver_status) { + // There should be only 1 app on |receiver_status|. + const base::Value* app_list_value = + receiver_status.FindKeyOfType("applications", base::Value::Type::LIST); + if (!app_list_value || app_list_value->GetList().size() != 1) { + DVLOG(2) << "receiver_status does not contain exactly one app: " + << receiver_status; + return nullptr; + } + + auto session = std::make_unique<CastSession>(); + + // Fill in mandatory Session fields. + const base::Value& app_value = app_list_value->GetList()[0]; + if (!GetString(app_value, "sessionId", &session->session_id) || + !GetString(app_value, "appId", &session->app_id) || + !GetString(app_value, "transportId", &session->transport_id) || + !GetString(app_value, "displayName", &session->display_name)) { + DVLOG(2) << "app_value missing mandatory fields: " << app_value; + return nullptr; + } + + // Optional Session fields. + GetString(app_value, "statusText", &session->status); + + base::Value receiver_value = CreateReceiver(sink, hash_token); + CopyValue(receiver_status, "volume", &receiver_value); + CopyValue(receiver_status, "isActiveInput", &receiver_value); + + // Create |session->value|. + session->value = base::Value(base::Value::Type::DICTIONARY); + auto& session_value = session->value; + session_value.SetKey("sessionId", base::Value(session->session_id)); + session_value.SetKey("appId", base::Value(session->app_id)); + session_value.SetKey("transportId", base::Value(session->transport_id)); + session_value.SetKey("receiver", std::move(receiver_value)); + + CopyValueWithDefault(app_value, "displayName", base::Value(""), + &session_value); + CopyValueWithDefault(app_value, "senderApps", base::ListValue(), + &session_value); + CopyValueWithDefault(app_value, "statusText", base::Value(), &session_value); + CopyValueWithDefault(app_value, "appImages", base::ListValue(), + &session_value); + CopyValueWithDefault(app_value, "namespaces", base::ListValue(), + &session_value); + + const base::Value* namespaces_value = + app_value.FindKeyOfType("namespaces", base::Value::Type::LIST); + if (!namespaces_value || namespaces_value->GetList().empty()) { + // A session without namespaces is invalid, except for a multizone leader. + if (session->app_id != kMultizoneLeaderAppId) + return nullptr; + } else { + for (const auto& namespace_value : namespaces_value->GetList()) { + std::string message_namespace; + if (!namespace_value.is_dict() || + !GetString(namespace_value, "name", &message_namespace)) + return nullptr; + + session->message_namespaces.insert(std::move(message_namespace)); + } + } + + session_value.SetKey("namespaces", + namespaces_value ? namespaces_value->Clone() + : base::Value(base::Value::Type::LIST)); + + return session; +} + +CastSession::CastSession() = default; +CastSession::~CastSession() = default; + +// static +std::string CastSession::GetRouteDescription(const CastSession& session) { + return !session.status.empty() ? session.status : session.display_name; +} + +blink::mojom::PresentationConnectionMessagePtr CreateNewSessionMessage( + const CastSession& session, + const std::string& client_id) { + base::Value message(base::Value::Type::DICTIONARY); + message.SetKey("type", base::Value(CastInternalMessageTypeToString( + CastInternalMessage::Type::kNewSession))); + message.SetKey("message", session.value.Clone()); + message.SetKey("sequenceNumber", base::Value(-1)); + message.SetKey("timeoutMillis", base::Value(0)); + message.SetKey("clientId", base::Value(client_id)); + return CreatePresentationConnectionMessage(message); +} + +blink::mojom::PresentationConnectionMessagePtr CreateAppMessageAck( + const std::string& client_id, + int sequence_number) { + base::Value message(base::Value::Type::DICTIONARY); + message.SetKey("type", base::Value(CastInternalMessageTypeToString( + CastInternalMessage::Type::kAppMessage))); + message.SetKey("message", base::Value()); + message.SetKey("sequenceNumber", base::Value(sequence_number)); + message.SetKey("timeoutMillis", base::Value(0)); + message.SetKey("clientId", base::Value(client_id)); + return CreatePresentationConnectionMessage(message); +} + +blink::mojom::PresentationConnectionMessagePtr CreateAppMessage( + const std::string& session_id, + const std::string& client_id, + const cast_channel::CastMessage& cast_message) { + base::Value message(base::Value::Type::DICTIONARY); + message.SetKey("type", base::Value(CastInternalMessageTypeToString( + CastInternalMessage::Type::kAppMessage))); + message.SetKey("message", CreateAppMessageBody(session_id, cast_message)); + message.SetKey("sequenceNumber", base::Value(-1)); + message.SetKey("timeoutMillis", base::Value(0)); + message.SetKey("clientId", base::Value(client_id)); + return CreatePresentationConnectionMessage(message); +} + +} // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/cast_internal_message_util.h b/chrome/browser/media/router/providers/cast/cast_internal_message_util.h new file mode 100644 index 0000000..f1755f03 --- /dev/null +++ b/chrome/browser/media/router/providers/cast/cast_internal_message_util.h
@@ -0,0 +1,123 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_CAST_CAST_INTERNAL_MESSAGE_UTIL_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_CAST_CAST_INTERNAL_MESSAGE_UTIL_H_ + +#include "base/containers/flat_set.h" +#include "base/macros.h" +#include "base/values.h" +#include "third_party/blink/public/platform/modules/presentation/presentation.mojom.h" + +namespace cast_channel { +class CastMessage; +} + +namespace media_router { + +class MediaSinkInternal; + +// Represents a message sent or received by the Cast SDK via a +// PresentationConnection. +struct CastInternalMessage { + // TODO(crbug.com/809249): Add other types of messages. + enum class Type { + kClientConnect, // Initial message sent by SDK client to connect to MRP. + kAppMessage, // App messages to pass through between SDK client and the + // receiver. + kReceiverAction, // Message sent by MRP to inform SDK client of action. + kNewSession, // Message sent by MRP to inform SDK client of new + // session. + kOther // All other types of messages which are not considered + // part of communication with Cast SDK. + }; + + // Returns a CastInternalMessage for |message|, or nullptr is |message| is not + // a valid Cast internal message. + static std::unique_ptr<CastInternalMessage> From(base::Value message); + + CastInternalMessage(Type type, const std::string& client_id); + ~CastInternalMessage(); + + Type type; + std::string client_id; + int sequence_number = -1; + + // The following are set if |type| is |kAppMessage|. + std::string app_message_namespace; + std::string app_message_session_id; + base::Value app_message_body; + + DISALLOW_COPY_AND_ASSIGN(CastInternalMessage); +}; + +// Represents a Cast session on a Cast device. Cast sessions are derived from +// RECEIVER_STATUS messages sent by Cast devices. +class CastSession { + public: + // Returns a CastSession from |receiver_status| message sent by |sink|, or + // nullptr if |receiver_status| is not a valid RECEIVER_STATUS message. + // |hash_token| is a per-profile value that is used to hash the sink ID. + static std::unique_ptr<CastSession> From(const MediaSinkInternal& sink, + const std::string& hash_token, + const base::Value& receiver_status); + + // Returns a string that can be used as the description of the MediaRoute + // associated with this session. + static std::string GetRouteDescription(const CastSession& session); + + CastSession(); + ~CastSession(); + + // ID of the session. + std::string session_id; + + // ID of the app in the session. + std::string app_id; + + // ID used for communicating with the session over the Cast channel. + std::string transport_id; + + // The set of accepted message namespaces. Must be non-empty, unless the + // session represents a multizone leader. + base::flat_set<std::string> message_namespaces; + + // The human-readable name of the Cast application, for example, "YouTube". + // Mandatory. + std::string display_name; + + // Descriptive text for the current application content, for example “My + // Wedding Slideshow”. May be empty. + std::string status; + + // The dictionary representing this session, derived from |receiver_status|. + // For convenience, this is used for generating messages sent to the SDK that + // include the session value. + base::Value value; +}; + +// Utility methods for generating messages sent to the SDK. +// |hash_token| is a per-profile value that is used to hash the sink ID. +blink::mojom::PresentationConnectionMessagePtr CreateReceiverActionCastMessage( + const std::string& client_id, + const MediaSinkInternal& sink, + const std::string& hash_token); +blink::mojom::PresentationConnectionMessagePtr CreateReceiverActionStopMessage( + const std::string& client_id, + const MediaSinkInternal& sink, + const std::string& hash_token); +blink::mojom::PresentationConnectionMessagePtr CreateNewSessionMessage( + const CastSession& session, + const std::string& client_id); +blink::mojom::PresentationConnectionMessagePtr CreateAppMessageAck( + const std::string& client_id, + int sequence_number); +blink::mojom::PresentationConnectionMessagePtr CreateAppMessage( + const std::string& session_id, + const std::string& client_id, + const cast_channel::CastMessage& cast_message); + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_CAST_CAST_INTERNAL_MESSAGE_UTIL_H_
diff --git a/chrome/browser/media/router/providers/cast/cast_internal_message_util_unittest.cc b/chrome/browser/media/router/providers/cast/cast_internal_message_util_unittest.cc new file mode 100644 index 0000000..ceed43cf --- /dev/null +++ b/chrome/browser/media/router/providers/cast/cast_internal_message_util_unittest.cc
@@ -0,0 +1,404 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h" + +#include "base/json/json_reader.h" +#include "chrome/browser/media/router/test/test_helper.h" +#include "chrome/common/media_router/test/test_helper.h" +#include "components/cast_channel/cast_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media_router { + +namespace { + +static constexpr char kReceiverIdToken[] = "token"; + +std::unique_ptr<base::Value> ReceiverStatus() { + std::string receiver_status_str = R"({ + "applications": [{ + "appId": "ABCDEFGH", + "displayName": "App display name", + "namespaces": [ + {"name": "urn:x-cast:com.google.cast.media"}, + {"name": "urn:x-cast:com.google.foo"} + ], + "sessionId": "sessionId", + "statusText":"App status", + "transportId":"transportId" + }] + })"; + return base::JSONReader::Read(receiver_status_str); +} + +void ExpectNoCastSession(const MediaSinkInternal& sink, + const std::string& receiver_status_str, + const std::string& reason) { + auto receiver_status = base::JSONReader::Read(receiver_status_str); + ASSERT_TRUE(receiver_status); + auto session = CastSession::From(sink, kReceiverIdToken, *receiver_status); + EXPECT_FALSE(session) << "Shouldn't have created session because of " + << reason; +} + +void ExpectJSONMessagesEqual(const std::string& expected_message, + const std::string& message) { + auto expected_message_value = base::JSONReader::Read(expected_message); + ASSERT_TRUE(expected_message_value); + + auto message_value = base::JSONReader::Read(message); + ASSERT_TRUE(message_value); + + EXPECT_EQ(*expected_message_value, *message_value); +} + +void ExpectInvalidCastInternalMessage(const std::string& message_str, + const std::string& invalid_reason) { + auto message_value = base::JSONReader::Read(message_str); + ASSERT_TRUE(message_value); + EXPECT_FALSE(CastInternalMessage::From(std::move(*message_value))) + << "message expected to be invlaid: " << invalid_reason; +} + +} // namespace + +TEST(CastInternalMessageUtilTest, CastInternalMessageFromAppMessageString) { + std::string message_str = R"({ + "type": "app_message", + "clientId": "12345", + "sequenceNumber": 999, + "message": { + "namespaceName": "urn:x-cast:com.google.foo", + "sessionId": "sessionId", + "message": { "foo": "bar" } + } + })"; + auto message_value = base::JSONReader::Read(message_str); + ASSERT_TRUE(message_value); + + auto message = CastInternalMessage::From(std::move(*message_value)); + ASSERT_TRUE(message); + EXPECT_EQ(CastInternalMessage::Type::kAppMessage, message->type); + EXPECT_EQ("12345", message->client_id); + EXPECT_EQ(999, message->sequence_number); + EXPECT_EQ("urn:x-cast:com.google.foo", message->app_message_namespace); + EXPECT_EQ("sessionId", message->app_message_session_id); + base::Value message_body(base::Value::Type::DICTIONARY); + message_body.SetKey("foo", base::Value("bar")); + EXPECT_EQ(message_body, message->app_message_body); +} + +TEST(CastInternalMessageUtilTest, CastInternalMessageFromClientConnectString) { + std::string message_str = R"({ + "type": "client_connect", + "clientId": "12345", + "message": {} + })"; + auto message_value = base::JSONReader::Read(message_str); + ASSERT_TRUE(message_value); + + auto message = CastInternalMessage::From(std::move(*message_value)); + ASSERT_TRUE(message); + EXPECT_EQ(CastInternalMessage::Type::kClientConnect, message->type); + EXPECT_EQ("12345", message->client_id); + EXPECT_EQ(-1, message->sequence_number); + EXPECT_TRUE(message->app_message_namespace.empty()); + EXPECT_TRUE(message->app_message_session_id.empty()); + EXPECT_EQ(base::Value(), message->app_message_body); +} + +TEST(CastInternalMessageUtilTest, CastInternalMessageFromInvalidStrings) { + std::string unknown_type = R"({ + "type": "some_unknown_type", + "clientId": "12345", + "message": {} + })"; + ExpectInvalidCastInternalMessage(unknown_type, "unknown_type"); + + std::string missing_client_id = R"({ + "type": "client_connect", + "message": {} + })"; + ExpectInvalidCastInternalMessage(missing_client_id, "missing client ID"); + + std::string missing_message = R"({ + "type": "client_connect", + "clientId": "12345" + })"; + ExpectInvalidCastInternalMessage(missing_message, "missing message"); + + std::string app_message_missing_namespace = R"({ + "type": "app_message", + "clientId": "12345", + "sequenceNumber": 999, + "message": { + "sessionId": "sessionId", + "message": { "foo": "bar" } + } + })"; + ExpectInvalidCastInternalMessage(app_message_missing_namespace, + "missing namespace"); + + std::string app_message_missing_session_id = R"({ + "type": "app_message", + "clientId": "12345", + "sequenceNumber": 999, + "message": { + "namespaceName": "urn:x-cast:com.google.foo", + "message": { "foo": "bar" } + } + })"; + ExpectInvalidCastInternalMessage(app_message_missing_session_id, + "missing session ID"); + + std::string app_message_missing_message = R"({ + "type": "app_message", + "clientId": "12345", + "sequenceNumber": 999, + "message": { + "namespaceName": "urn:x-cast:com.google.foo", + "sessionId": "sessionId" + } + })"; + ExpectInvalidCastInternalMessage(app_message_missing_message, + "missing app message"); +} + +TEST(CastInternalMessageUtilTest, CastSessionFromReceiverStatusNoStatusText) { + MediaSinkInternal sink = CreateCastSink(1); + std::string receiver_status_str = R"({ + "applications": [{ + "appId": "ABCDEFGH", + "displayName": "App display name", + "namespaces": [ + {"name": "urn:x-cast:com.google.cast.media"}, + {"name": "urn:x-cast:com.google.foo"} + ], + "sessionId": "sessionId", + "transportId":"transportId" + }] + })"; + auto receiver_status = base::JSONReader::Read(receiver_status_str); + ASSERT_TRUE(receiver_status); + auto session = CastSession::From(sink, kReceiverIdToken, *receiver_status); + ASSERT_TRUE(session); + EXPECT_EQ("sessionId", session->session_id); + EXPECT_EQ("ABCDEFGH", session->app_id); + EXPECT_EQ("transportId", session->transport_id); + base::flat_set<std::string> message_namespaces = { + "urn:x-cast:com.google.cast.media", "urn:x-cast:com.google.foo"}; + EXPECT_EQ(message_namespaces, session->message_namespaces); + EXPECT_TRUE(session->value.is_dict()); + EXPECT_EQ("App display name", CastSession::GetRouteDescription(*session)); +} + +TEST(CastInternalMessageUtilTest, CastSessionFromInvalidReceiverStatuses) { + MediaSinkInternal sink = CreateCastSink(1); + std::string missing_app_id = R"({ + "applications": [{ + "displayName": "App display name", + "namespaces": [ + {"name": "urn:x-cast:com.google.cast.media"}, + {"name": "urn:x-cast:com.google.foo"} + ], + "sessionId": "sessionId", + "statusText":"App status", + "transportId":"transportId" + }] + })"; + ExpectNoCastSession(sink, missing_app_id, "missing app id"); + + std::string missing_display_name = R"({ + "applications": [{ + "appId": "ABCDEFGH", + "namespaces": [ + {"name": "urn:x-cast:com.google.cast.media"}, + {"name": "urn:x-cast:com.google.foo"} + ], + "sessionId": "sessionId", + "statusText":"App status", + "transportId":"transportId" + }] + })"; + ExpectNoCastSession(sink, missing_display_name, "missing display name"); + + std::string missing_namespaces = R"({ + "applications": [{ + "appId": "ABCDEFGH", + "displayName": "App display name", + "namespaces": [], + "sessionId": "sessionId", + "statusText":"App status", + "transportId":"transportId" + }] + })"; + ExpectNoCastSession(sink, missing_namespaces, "missing namespaces"); + + std::string missing_session_id = R"({ + "applications": [{ + "appId": "ABCDEFGH", + "displayName": "App display name", + "namespaces": [ + {"name": "urn:x-cast:com.google.cast.media"}, + {"name": "urn:x-cast:com.google.foo"} + ], + "statusText":"App status", + "transportId":"transportId" + }] + })"; + ExpectNoCastSession(sink, missing_session_id, "missing session id"); + + std::string missing_transport_id = R"({ + "applications": [{ + "appId": "ABCDEFGH", + "displayName": "App display name", + "namespaces": [ + {"name": "urn:x-cast:com.google.cast.media"}, + {"name": "urn:x-cast:com.google.foo"} + ], + "sessionId": "sessionId", + "statusText":"App status" + }] + })"; + ExpectNoCastSession(sink, missing_transport_id, "missing transport id"); +} + +TEST(CastInternalMessageUtilTest, CreateReceiverActionCastMessage) { + std::string client_id = "clientId"; + MediaSinkInternal sink = CreateCastSink(1); + std::string expected_message = R"({ + "clientId": "clientId", + "message": { + "action": "cast", + "receiver": { + "capabilities": [ "video_out", "audio_out" ], + "displayStatus": null, + "friendlyName": "friendly name 1", + "isActiveInput": null, + "label": "yYH_HCL9CKJFmvKJ9m3Une2cS8s", + "receiverType": "cast", + "volume": null + } + }, + "sequenceNumber": -1, + "timeoutMillis": 0, + "type": "receiver_action" + })"; + + auto message = + CreateReceiverActionCastMessage(client_id, sink, kReceiverIdToken); + ExpectJSONMessagesEqual(expected_message, message->get_message()); +} + +TEST(CastInternalMessageUtilTest, CreateReceiverActionStopMessage) { + std::string client_id = "clientId"; + MediaSinkInternal sink = CreateCastSink(1); + std::string expected_message = R"({ + "clientId": "clientId", + "message": { + "action": "stop", + "receiver": { + "capabilities": [ "video_out", "audio_out" ], + "displayStatus": null, + "friendlyName": "friendly name 1", + "isActiveInput": null, + "label": "yYH_HCL9CKJFmvKJ9m3Une2cS8s", + "receiverType": "cast", + "volume": null + } + }, + "sequenceNumber": -1, + "timeoutMillis": 0, + "type": "receiver_action" + })"; + + auto message = + CreateReceiverActionStopMessage(client_id, sink, kReceiverIdToken); + ExpectJSONMessagesEqual(expected_message, message->get_message()); +} + +TEST(CastInternalMessageUtilTest, CreateNewSessionMessage) { + MediaSinkInternal sink = CreateCastSink(1); + std::string client_id = "clientId"; + auto receiver_status = ReceiverStatus(); + ASSERT_TRUE(receiver_status); + auto session = CastSession::From(sink, kReceiverIdToken, *receiver_status); + ASSERT_TRUE(session); + + std::string expected_message = R"({ + "clientId": "clientId", + "message": { + "appId": "ABCDEFGH", + "appImages": [ ], + "displayName": "App display name", + "namespaces": [ { + "name": "urn:x-cast:com.google.cast.media" + }, { + "name": "urn:x-cast:com.google.foo" + } ], + "receiver": { + "capabilities": [ "video_out", "audio_out" ], + "displayStatus": null, + "friendlyName": "friendly name 1", + "isActiveInput": null, + "label": "yYH_HCL9CKJFmvKJ9m3Une2cS8s", + "receiverType": "cast", + "volume": null + }, + "senderApps": [ ], + "sessionId": "sessionId", + "statusText": "App status", + "transportId": "transportId" + }, + "sequenceNumber": -1, + "timeoutMillis": 0, + "type": "new_session" + })"; + + auto message = CreateNewSessionMessage(*session, client_id); + ExpectJSONMessagesEqual(expected_message, message->get_message()); +} + +TEST(CastInternalMessageUtilTest, CreateAppMessageAck) { + std::string client_id = "clientId"; + int sequence_number = 12345; + + std::string expected_message = R"({ + "clientId": "clientId", + "message": null, + "sequenceNumber": 12345, + "timeoutMillis": 0, + "type": "app_message" + })"; + + auto message = CreateAppMessageAck(client_id, sequence_number); + ExpectJSONMessagesEqual(expected_message, message->get_message()); +} + +TEST(CastInternalMessageUtilTest, CreateAppMessage) { + std::string session_id = "sessionId"; + std::string client_id = "clientId"; + base::Value message_body(base::Value::Type::DICTIONARY); + message_body.SetKey("foo", base::Value("bar")); + cast_channel::CastMessage cast_message = cast_channel::CreateCastMessage( + "urn:x-cast:com.google.foo", message_body, "sourceId", "destinationId"); + + std::string expected_message = R"({ + "clientId": "clientId", + "message": { + "message": "{\"foo\":\"bar\"}", + "namespaceName": "urn:x-cast:com.google.foo", + "sessionId": "sessionId" + }, + "sequenceNumber": -1, + "timeoutMillis": 0, + "type": "app_message" + })"; + + auto message = CreateAppMessage(session_id, client_id, cast_message); + ExpectJSONMessagesEqual(expected_message, message->get_message()); +} + +} // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc index b32a575..28ee791e 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
@@ -64,7 +64,7 @@ EXPECT_CALL(app_discovery_service_, DoStartObservingMediaSinks(_)).Times(0); provider_->StartObservingMediaSinks(non_cast_source); - MediaSource::Id cast_source("cast:ABCDEFGH"); + MediaSource::Id cast_source("cast:ABCDEFGH?clientId=123"); EXPECT_CALL(app_discovery_service_, DoStartObservingMediaSinks(_)); provider_->StartObservingMediaSinks(cast_source); EXPECT_FALSE(app_discovery_service_.callbacks().empty()); @@ -78,6 +78,7 @@ media_sink_service_.AddOrUpdateSink(CreateCastSink(2)); MediaSource::Id source_id( "cast:ABCDEFAB?capabilities=video_out,audio_out" + "&clientId=123" "&broadcastNamespace=namespace" "&broadcastMessage=message");
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc index bcb86de..581135e 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc
@@ -162,9 +162,17 @@ // while destruction took place, thereby avoiding endless attempts to upload // the same file. - // |network_connection_tracker_| might already have posted a task back to us, - // but it will not run, because |task_runner_| has already been stopped. - network_connection_tracker_->RemoveNetworkConnectionObserver(this); + if (network_connection_tracker_) { + // * |network_connection_tracker_| might already have posted a task back + // to us, but it will not run, because |task_runner_| has already been + // stopped. + // * RemoveNetworkConnectionObserver() should generally be called on the + // same thread as AddNetworkConnectionObserver(), but in this case it's + // okay to remove on a separate thread, because this only happens during + // Chrome shutdown, when no others tasks are running; there can be no + // concurrently executing notification from the tracker. + network_connection_tracker_->RemoveNetworkConnectionObserver(this); + } } void WebRtcRemoteEventLogManager::SetNetworkConnectionTracker(
diff --git a/chrome/browser/metrics/subprocess_metrics_provider_unittest.cc b/chrome/browser/metrics/subprocess_metrics_provider_unittest.cc index 7330132..9bb0117 100644 --- a/chrome/browser/metrics/subprocess_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/subprocess_metrics_provider_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> #include <string> +#include <vector> #include "base/metrics/histogram.h" #include "base/metrics/histogram_flattener.h" @@ -14,8 +15,12 @@ #include "base/metrics/persistent_memory_allocator.h" #include "base/metrics/statistics_recorder.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::UnorderedElementsAre; +using ::testing::IsEmpty; + namespace { const uint32_t TEST_MEMORY_SIZE = 64 << 10; // 64 KiB @@ -74,7 +79,7 @@ std::string(), false)); } - size_t GetSnapshotHistogramCount() { + std::vector<std::string> GetSnapshotHistogramNames() { // Merge the data from the allocator into the StatisticsRecorder. provider_.MergeHistogramDeltas(); @@ -85,7 +90,7 @@ base::StatisticsRecorder::PrepareDeltas(true, base::Histogram::kNoFlags, base::Histogram::kNoFlags, &snapshot_manager); - return flattener.GetRecordedDeltaHistogramNames().size(); + return flattener.GetRecordedDeltaHistogramNames(); } void EnableRecording() { provider_.OnRecordingEnabled(); } @@ -113,8 +118,7 @@ DISALLOW_COPY_AND_ASSIGN(SubprocessMetricsProviderTest); }; -// Temporarily disabled until someone can troubleshoot http://crbug.com/863262 -TEST_F(SubprocessMetricsProviderTest, DISABLED_SnapshotMetrics) { +TEST_F(SubprocessMetricsProviderTest, SnapshotMetrics) { base::HistogramBase* foo = base::Histogram::FactoryGet("foo", 1, 100, 10, 0); base::HistogramBase* bar = base::Histogram::FactoryGet("bar", 1, 100, 10, 0); base::HistogramBase* baz = base::Histogram::FactoryGet("baz", 1, 100, 10, 0); @@ -130,25 +134,26 @@ CreateDuplicateAllocator(global_allocator.get())); // Recording should find the two histograms created in persistent memory. - EXPECT_EQ(2U, GetSnapshotHistogramCount()); + EXPECT_THAT(GetSnapshotHistogramNames(), UnorderedElementsAre("foo", "bar")); // A second run should have nothing to produce. - EXPECT_EQ(0U, GetSnapshotHistogramCount()); + EXPECT_THAT(GetSnapshotHistogramNames(), IsEmpty()); // Create a new histogram and update existing ones. Should now report 3 items. baz->Add(1969); foo->Add(10); bar->Add(20); - EXPECT_EQ(3U, GetSnapshotHistogramCount()); + EXPECT_THAT(GetSnapshotHistogramNames(), + UnorderedElementsAre("foo", "bar", "baz")); // Ensure that deregistering does a final merge of the data. foo->Add(10); bar->Add(20); DeregisterSubprocessAllocator(123); - EXPECT_EQ(2U, GetSnapshotHistogramCount()); + EXPECT_THAT(GetSnapshotHistogramNames(), UnorderedElementsAre("foo", "bar")); // Further snapshots should be empty even if things have changed. foo->Add(10); bar->Add(20); - EXPECT_EQ(0U, GetSnapshotHistogramCount()); + EXPECT_THAT(GetSnapshotHistogramNames(), IsEmpty()); }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 86696fb..6f62c20 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -1084,7 +1084,10 @@ PasswordAccessoryController::FromWebContents(web_contents()); if (!accessory) return; // No accessory needs change here. - accessory->RefreshSuggestionsForField(is_fillable, is_password_field); + accessory->RefreshSuggestionsForField( + password_manager_driver_bindings_.GetCurrentTargetFrame() + ->GetLastCommittedOrigin(), + is_fillable, is_password_field); #endif // defined(OS_ANDROID) }
diff --git a/chrome/browser/password_manager/password_accessory_controller.cc b/chrome/browser/password_manager/password_accessory_controller.cc index 6f5c332..11d7906 100644 --- a/chrome/browser/password_manager/password_accessory_controller.cc +++ b/chrome/browser/password_manager/password_accessory_controller.cc
@@ -8,7 +8,6 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/android/preferences/preferences_launcher.h" -#include "chrome/browser/password_manager/password_accessory_view_interface.h" #include "chrome/browser/password_manager/password_generation_dialog_view_interface.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/grit/generated_resources.h" @@ -22,8 +21,6 @@ #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" -#include "chrome/browser/android/preferences/preferences_launcher.h" - using autofill::PasswordForm; using Item = PasswordAccessoryViewInterface::AccessoryItem; @@ -210,10 +207,15 @@ } void PasswordAccessoryController::RefreshSuggestionsForField( + const url::Origin& origin, bool is_fillable, bool is_password_field) { // TODO(crbug/853766): Record CTR metric. - SendViewItems(is_password_field); + view_->OnItemsAvailable( + CreateViewItems(origin, + is_fillable ? origin_suggestions_[origin] + : std::vector<SuggestionElementData>(), + is_password_field)); } gfx::NativeView PasswordAccessoryController::container_view() const { @@ -224,13 +226,11 @@ return web_contents_->GetTopLevelNativeWindow(); } -void PasswordAccessoryController::SendViewItems(bool is_password_field) { - DCHECK(view_); - last_focused_field_was_for_passwords_ = is_password_field; - const url::Origin& origin = - web_contents_->GetFocusedFrame()->GetLastCommittedOrigin(); - const std::vector<SuggestionElementData>& suggestions = - origin_suggestions_[origin]; +// static +std::vector<Item> PasswordAccessoryController::CreateViewItems( + const url::Origin& origin, + const std::vector<SuggestionElementData>& suggestions, + bool is_password_field) { std::vector<Item> items; base::string16 passwords_title_str; @@ -266,7 +266,5 @@ IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK); items.emplace_back(manage_passwords_title, manage_passwords_title, false, Item::Type::OPTION); - - // Notify the view about all just created elements. - view_->OnItemsAvailable(items); + return items; }
diff --git a/chrome/browser/password_manager/password_accessory_controller.h b/chrome/browser/password_manager/password_accessory_controller.h index 9830285..2231d353 100644 --- a/chrome/browser/password_manager/password_accessory_controller.h +++ b/chrome/browser/password_manager/password_accessory_controller.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" +#include "chrome/browser/password_manager/password_accessory_view_interface.h" #include "components/autofill/core/common/filling_status.h" #include "components/autofill/core/common/password_generation_util.h" #include "content/public/browser/web_contents_user_data.h" @@ -28,7 +29,6 @@ class PasswordManagerDriver; } // namespace password_manager -class PasswordAccessoryViewInterface; class PasswordGenerationDialogViewInterface; // The controller for the view located below the keyboard accessory. @@ -91,8 +91,11 @@ void OnFilledIntoFocusedField(autofill::FillingStatus status); // Makes sure, that all shown suggestions are appropriate for the currently - // focused field. - void RefreshSuggestionsForField(bool is_fillable, bool is_password_field); + // focused field and for fields that lost the focus. If a field lost focus, + // |is_fillable| will be false. + void RefreshSuggestionsForField(const url::Origin& origin, + bool is_fillable, + bool is_password_field); // The web page view containing the focused field. gfx::NativeView container_view() const; @@ -129,10 +132,12 @@ std::unique_ptr<PasswordAccessoryViewInterface> view, CreateDialogFactory create_dialog_callback); - // Creates the view items based on the |origin_suggestions_| and sends them to - // the view. If |is_password_field| is false, password suggestions won't be - // interactive. - void SendViewItems(bool is_password_field); + // Creates the view items based on the given |suggestions|. + // If |is_password_field| is false, password suggestions won't be interactive. + static std::vector<PasswordAccessoryViewInterface::AccessoryItem> + CreateViewItems(const url::Origin& origin, + const std::vector<SuggestionElementData>& suggestions, + bool is_password_field); // Contains the last set of credentials by origin. std::map<url::Origin, std::vector<SuggestionElementData>> origin_suggestions_;
diff --git a/chrome/browser/password_manager/password_accessory_controller_unittest.cc b/chrome/browser/password_manager/password_accessory_controller_unittest.cc index 4d7ee08..c5603a5 100644 --- a/chrome/browser/password_manager/password_accessory_controller_unittest.cc +++ b/chrome/browser/password_manager/password_accessory_controller_unittest.cc
@@ -245,7 +245,6 @@ std::make_unique<StrictMock<MockPasswordAccessoryView>>(), mock_dialog_factory_.Get()); NavigateAndCommit(GURL("https://example.com")); - FocusWebContentsOnMainFrame(); } PasswordAccessoryController* controller() { @@ -287,8 +286,10 @@ controller()->SavePasswordsForOrigin({CreateEntry("Ben", "S3cur3").first}, url::Origin::Create(GURL(kExampleSite))); - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_password_field=*/false); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/false); } TEST_F(PasswordAccessoryControllerTest, HintsToEmptyUserNames) { @@ -304,8 +305,10 @@ controller()->SavePasswordsForOrigin({CreateEntry("", "S3cur3").first}, url::Origin::Create(GURL(kExampleSite))); - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_password_field=*/false); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/false); } TEST_F(PasswordAccessoryControllerTest, SortsAlphabeticalDuringTransform) { @@ -338,8 +341,10 @@ {CreateEntry("Ben", "S3cur3").first, CreateEntry("Zebra", "M3h").first, CreateEntry("Alf", "PWD").first, CreateEntry("Cat", "M1@u").first}, url::Origin::Create(GURL(kExampleSite))); - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_password_field=*/false); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/false); } TEST_F(PasswordAccessoryControllerTest, RepeatsSuggestionsForSameFrame) { @@ -357,8 +362,10 @@ url::Origin::Create(GURL(kExampleSite))); // Pretend that any input in the same frame was focused. - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_fillable=*/false); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_fillable=*/false); } TEST_F(PasswordAccessoryControllerTest, ProvidesEmptySuggestionsMessage) { @@ -370,8 +377,10 @@ controller()->SavePasswordsForOrigin({}, url::Origin::Create(GURL(kExampleSite))); - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_password_field=*/false); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/false); } TEST_F(PasswordAccessoryControllerTest, RelaysAutomaticGenerationAvailable) { @@ -439,8 +448,10 @@ // This should result in the non-interactive suggestion expected above. controller()->SavePasswordsForOrigin({CreateEntry("Ben", "S3cur3").first}, url::Origin::Create(GURL(kExampleSite))); - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_password_field=*/false); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/false); // Pretend that we focus a password field now: By triggering a refresh with // |is_password_field| set to true, all suggestions should become interactive. @@ -452,8 +463,10 @@ MatchesItem(ASCIIToUTF16("S3cur3"), password_for_str("Ben"), true, ItemType::SUGGESTION), IsDivider(), MatchesOption(manage_passwords_str())))); - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_password_field=*/true); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/true); } TEST_F(PasswordAccessoryControllerTest, CachesIsReplacedByNewPasswords) { @@ -467,8 +480,10 @@ IsDivider(), MatchesOption(manage_passwords_str())))); controller()->SavePasswordsForOrigin({CreateEntry("Ben", "S3cur3").first}, url::Origin::Create(GURL(kExampleSite))); - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_password_field=*/false); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/false); EXPECT_CALL(*view(), OnItemsAvailable(ElementsAre( @@ -480,6 +495,38 @@ IsDivider(), MatchesOption(manage_passwords_str())))); controller()->SavePasswordsForOrigin({CreateEntry("Alf", "M3lm4k").first}, url::Origin::Create(GURL(kExampleSite))); - controller()->RefreshSuggestionsForField(/*is_fillable=*/true, - /*is_password_field=*/false); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/false); +} + +TEST_F(PasswordAccessoryControllerTest, UnfillableFieldClearsSuggestions) { + EXPECT_CALL(*view(), + OnItemsAvailable(ElementsAre( + MatchesLabel(passwords_title_str(kExampleDomain)), + MatchesItem(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false, + ItemType::SUGGESTION), + MatchesItem(ASCIIToUTF16("S3cur3"), password_for_str("Ben"), + true, ItemType::NON_INTERACTIVE_SUGGESTION), + IsDivider(), MatchesOption(manage_passwords_str())))); + // Set any, non-empty password list and pretend a username field was focused. + // This should result in the non-emtpy suggestions expected above. + controller()->SavePasswordsForOrigin({CreateEntry("Ben", "S3cur3").first}, + url::Origin::Create(GURL(kExampleSite))); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/true, + /*is_password_field=*/false); + + // Pretend that the focus was lost or moved to an unfillable field. Now, only + // the empty state message should be sent. + EXPECT_CALL(*view(), + OnItemsAvailable(ElementsAre( + MatchesLabel(passwords_empty_str(kExampleDomain)), + IsDivider(), MatchesOption(manage_passwords_str())))); + controller()->RefreshSuggestionsForField( + url::Origin::Create(GURL(kExampleSite)), + /*is_fillable=*/false, + /*is_password_field=*/false); // Unused. }
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc index 8b46523..5ad7d13e 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -916,4 +916,27 @@ #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) +// Tests that the Picture-in-Picture state is properly updated when the window +// is closed at a system level. +IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, + CloseWindowNotifiesController) { + LoadTabAndEnterPictureInPicture(browser()); + + content::WebContents* active_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>( + window_controller()->GetWindowForTesting()); + ASSERT_TRUE(overlay_window); + ASSERT_TRUE(overlay_window->IsVisible()); + + // Simulate closing from the system. + overlay_window->OnNativeWidgetDestroyed(); + + bool in_picture_in_picture = false; + ASSERT_TRUE(ExecuteScriptAndExtractBool( + active_web_contents, "isInPictureInPicture();", &in_picture_in_picture)); + EXPECT_FALSE(in_picture_in_picture); +} + #endif // !defined(OS_ANDROID)
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 18f059e..2d0e643 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -794,11 +794,9 @@ #endif #if !defined(OS_ANDROID) -#if !defined(OS_CHROMEOS) { key::kRelaunchNotification, prefs::kRelaunchNotification, base::Value::Type::INTEGER }, -#endif // !defined(OS_CHROMEOS) { key::kRelaunchNotificationPeriod, prefs::kRelaunchNotificationPeriod, base::Value::Type::INTEGER },
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 083de60..29745cd 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -28,6 +28,7 @@ #include "chrome/browser/media/media_device_id_salt.h" #include "chrome/browser/media/media_engagement_service.h" #include "chrome/browser/media/media_storage_id_salt.h" +#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/media/webrtc/media_stream_devices_controller.h" #include "chrome/browser/metrics/chrome_metrics_service_client.h" @@ -651,6 +652,7 @@ InstantService::RegisterProfilePrefs(registry); gcm::GCMChannelStatusSyncer::RegisterProfilePrefs(registry); gcm::RegisterProfilePrefs(registry); + media_router::RegisterProfilePrefs(registry); ntp_tiles::CustomLinksManagerImpl::RegisterProfilePrefs(registry); StartupBrowserCreator::RegisterProfilePrefs(registry); #endif
diff --git a/chrome/browser/profiles/gaia_info_update_service.cc b/chrome/browser/profiles/gaia_info_update_service.cc index c15d673..ec2e2e2 100644 --- a/chrome/browser/profiles/gaia_info_update_service.cc +++ b/chrome/browser/profiles/gaia_info_update_service.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_metrics.h" #include "chrome/browser/profiles/profiles_state.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_tracker_service.h" @@ -39,9 +39,9 @@ GAIAInfoUpdateService::GAIAInfoUpdateService(Profile* profile) : profile_(profile) { - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfile(profile_); - signin_manager->AddObserver(this); + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile_); + identity_manager->AddObserver(this); PrefService* prefs = profile_->GetPrefs(); last_updated_ = base::Time::FromInternalValue( @@ -55,9 +55,9 @@ void GAIAInfoUpdateService::Update() { // The user must be logged in. - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfile(profile_); - if (!signin_manager->IsAuthenticated()) + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile_); + if (!identity_manager->HasPrimaryAccount()) return; if (profile_image_downloader_) @@ -173,9 +173,9 @@ void GAIAInfoUpdateService::Shutdown() { timer_.Stop(); profile_image_downloader_.reset(); - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfile(profile_); - signin_manager->RemoveObserver(this); + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile_); + identity_manager->RemoveObserver(this); // OK to reset |profile_| pointer here because GAIAInfoUpdateService will not // access it again. This pointer is also used to implement the delegate for @@ -208,12 +208,12 @@ timer_.Start(FROM_HERE, delta, this, &GAIAInfoUpdateService::Update); } -void GAIAInfoUpdateService::GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) { - OnUsernameChanged(username); +void GAIAInfoUpdateService::OnPrimaryAccountSet( + const AccountInfo& primary_account_info) { + OnUsernameChanged(primary_account_info.gaia); } -void GAIAInfoUpdateService::GoogleSignedOut(const std::string& account_id, - const std::string& username) { +void GAIAInfoUpdateService::OnPrimaryAccountCleared( + const AccountInfo& previous_primary_account_info) { OnUsernameChanged(std::string()); }
diff --git a/chrome/browser/profiles/gaia_info_update_service.h b/chrome/browser/profiles/gaia_info_update_service.h index 5c84e89d..4128577 100644 --- a/chrome/browser/profiles/gaia_info_update_service.h +++ b/chrome/browser/profiles/gaia_info_update_service.h
@@ -14,7 +14,7 @@ #include "chrome/browser/profiles/profile_downloader.h" #include "chrome/browser/profiles/profile_downloader_delegate.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/signin/core/browser/signin_manager.h" +#include "services/identity/public/cpp/identity_manager.h" class Profile; class ProfileDownloader; @@ -23,7 +23,7 @@ // The results are saved in the profile info cache. class GAIAInfoUpdateService : public KeyedService, public ProfileDownloaderDelegate, - public SigninManagerBase::Observer { + public identity::IdentityManager::Observer { public: explicit GAIAInfoUpdateService(Profile* profile); ~GAIAInfoUpdateService() override; @@ -54,11 +54,10 @@ void OnUsernameChanged(const std::string& username); void ScheduleNextUpdate(); - // Overridden from SigninManagerBase::Observer: - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override; - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override; + // Overridden from identity::IdentityManager::Observer: + void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override; + void OnPrimaryAccountCleared( + const AccountInfo& previous_primary_account_info) override; Profile* profile_; std::unique_ptr<ProfileDownloader> profile_image_downloader_;
diff --git a/chrome/browser/profiles/gaia_info_update_service_factory.cc b/chrome/browser/profiles/gaia_info_update_service_factory.cc index 9edd14cd..b607b97 100644 --- a/chrome/browser/profiles/gaia_info_update_service_factory.cc +++ b/chrome/browser/profiles/gaia_info_update_service_factory.cc
@@ -6,7 +6,7 @@ #include "chrome/browser/profiles/gaia_info_update_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/common/pref_names.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -15,7 +15,7 @@ : BrowserContextKeyedServiceFactory( "GAIAInfoUpdateService", BrowserContextDependencyManager::GetInstance()) { - DependsOn(SigninManagerFactory::GetInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); } GAIAInfoUpdateServiceFactory::~GAIAInfoUpdateServiceFactory() {}
diff --git a/chrome/browser/profiles/gaia_info_update_service_unittest.cc b/chrome/browser/profiles/gaia_info_update_service_unittest.cc index c4bda264..ed21e6c5 100644 --- a/chrome/browser/profiles/gaia_info_update_service_unittest.cc +++ b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/test_signin_client_builder.h" #include "chrome/common/pref_names.h" @@ -29,6 +30,7 @@ #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/signin_pref_names.h" #include "components/sync_preferences/pref_service_syncable.h" +#include "services/identity/public/cpp/identity_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_unittest_util.h" @@ -87,9 +89,9 @@ Profile* CreateProfile(const std::string& name) { TestingProfile::TestingFactories testing_factories; - testing_factories.push_back(std::make_pair( - ChromeSigninClientFactory::GetInstance(), - signin::BuildTestSigninClient)); + testing_factories.push_back( + std::make_pair(ChromeSigninClientFactory::GetInstance(), + signin::BuildTestSigninClient)); Profile* profile = testing_profile_manager_.CreateTestingProfile( name, std::unique_ptr<sync_preferences::PrefServiceSyncable>(), base::UTF8ToUTF16(name), 0, std::string(), testing_factories); @@ -301,9 +303,9 @@ #if !defined(OS_CHROMEOS) TEST_F(GAIAInfoUpdateServiceTest, LogOut) { - SigninManager* signin_manager = - SigninManagerFactory::GetForProfile(profile()); - signin_manager->SetAuthenticatedAccountInfo("gaia_id", "pat@example.com"); + identity::SetPrimaryAccount(SigninManagerFactory::GetForProfile(profile()), + IdentityManagerFactory::GetForProfile(profile()), + "pat@example.com"); base::string16 gaia_name = base::UTF8ToUTF16("Pat Foo"); ASSERT_EQ(1u, storage()->GetNumberOfProfiles()); @@ -319,8 +321,9 @@ EXPECT_FALSE(service()->GetCachedPictureURL().empty()); // Log out. - signin_manager->SignOut(signin_metrics::SIGNOUT_TEST, - signin_metrics::SignoutDelete::IGNORE_METRIC); + identity::ClearPrimaryAccount( + SigninManagerFactory::GetForProfile(profile()), + IdentityManagerFactory::GetForProfile(profile())); // Verify that the GAIA name and picture, and picture URL are unset. EXPECT_TRUE(entry->GetGAIAName().empty()); EXPECT_EQ(nullptr, entry->GetGAIAPicture()); @@ -330,11 +333,9 @@ TEST_F(GAIAInfoUpdateServiceTest, LogIn) { // Log in. EXPECT_CALL(*service(), Update()); - AccountTrackerServiceFactory::GetForProfile(profile()) - ->SeedAccountInfo("gaia_id", "pat@example.com"); - SigninManager* signin_manager = - SigninManagerFactory::GetForProfile(profile()); - signin_manager->OnExternalSigninCompleted("pat@example.com"); + identity::SetPrimaryAccount(SigninManagerFactory::GetForProfile(profile()), + IdentityManagerFactory::GetForProfile(profile()), + "pat@example.com"); } #endif
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index e8f837f..5e93376 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -273,7 +273,12 @@ bool Profile::IsSyncAllowed() { if (ProfileSyncServiceFactory::HasProfileSyncService(this)) { - return ProfileSyncServiceFactory::GetForProfile(this)->IsSyncAllowed(); + browser_sync::ProfileSyncService* sync_service = + ProfileSyncServiceFactory::GetForProfile(this); + return !sync_service->HasDisableReason( + syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE) && + !sync_service->HasDisableReason( + syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY); } // No ProfileSyncService created yet - we don't want to create one, so just
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc index 69270d03..deec95b 100644 --- a/chrome/browser/profiles/profile_browsertest.cc +++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -9,6 +9,8 @@ #include <memory> #include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_path_watcher.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/json/json_reader.h" @@ -20,6 +22,7 @@ #include "base/sequenced_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/task_scheduler/task_scheduler.h" +#include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "base/values.h" @@ -35,6 +38,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_features.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -846,3 +850,157 @@ net::LOAD_ONLY_FROM_CACHE); url_fetcher_delegate3.WaitForCompletion(); } + +namespace { + +// Watches for the destruction of the specified path (Which, in the tests that +// use it, is typically a directory), and expects the parent directory not to be +// deleted. +// +// This is used the the media cache deletion tests, so handles all the possible +// orderings of events that could happen: +// +// * In PRE_* tests, the media cache could deleted before the test completes, by +// the task posted on Profile / isolated app URLRequestContext creation. +// +// * In the followup test, the media cache could be deleted by the off-thread +// delete media cache task before the FileDestructionWatcher starts watching for +// deletion, or even before it's created. +// +// * In the followup test, the media cache could be deleted after the +// FileDestructionWatcher starts watching. +// +// It also may be possible to get a notification of the media cache being +// created from the the previous test, so this allows multiple watch events to +// happen, before the path is actually deleted. +// +// The public methods are called on the UI thread, the private ones called on a +// separate SequencedTaskRunner. +class FileDestructionWatcher { + public: + explicit FileDestructionWatcher(const base::FilePath& watched_file_path) + : watched_file_path_(watched_file_path) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + } + + void WaitForDestruction() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(!watcher_); + base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}) + ->PostTask(FROM_HERE, + base::BindOnce(&FileDestructionWatcher::StartWatchingPath, + base::Unretained(this))); + run_loop_.Run(); + // The watcher should be destroyed before quitting the run loop, once the + // file has been destroyed. + DCHECK(!watcher_); + + // Double check that the file was destroyed, and that the parent directory + // was not. + base::ScopedAllowBlockingForTesting allow_blocking; + EXPECT_FALSE(base::PathExists(watched_file_path_)); + EXPECT_TRUE(base::PathExists(watched_file_path_.DirName())); + } + + private: + void StartWatchingPath() { + DCHECK(!watcher_); + watcher_ = std::make_unique<base::FilePathWatcher>(); + // Start watching before checking if the file exists, as the file could be + // destroyed between the existence check and when we start watching, if the + // order were reversed. + EXPECT_TRUE(watcher_->Watch( + watched_file_path_, false /* recursive */, + base::BindRepeating(&FileDestructionWatcher::OnPathChanged, + base::Unretained(this)))); + CheckIfPathExists(); + } + + void OnPathChanged(const base::FilePath& path, bool error) { + EXPECT_EQ(watched_file_path_, path); + EXPECT_FALSE(error); + CheckIfPathExists(); + } + + // Checks if the path exists, and if so, destroys the watcher and quits + // |run_loop_|. + void CheckIfPathExists() { + if (!base::PathExists(watched_file_path_)) { + watcher_.reset(); + run_loop_.Quit(); + return; + } + } + + base::RunLoop run_loop_; + const base::FilePath watched_file_path_; + + // Created and destroyed off of the UI thread, on the sequence used to watch + // for changes. + std::unique_ptr<base::FilePathWatcher> watcher_; + + DISALLOW_COPY_AND_ASSIGN(FileDestructionWatcher); +}; + +} // namespace + +// Create a media cache file, and make sure it's deleted by the time the next +// test runs. +IN_PROC_BROWSER_TEST_F(ProfileWithoutMediaCacheBrowserTest, + PRE_DeleteMediaCache) { + base::FilePath media_cache_path = + browser()->profile()->GetPath().Append(chrome::kMediaCacheDirname); + + base::ScopedAllowBlockingForTesting allow_blocking; + EXPECT_TRUE(base::CreateDirectory(media_cache_path)); + std::string data = "foo"; + base::WriteFile(media_cache_path.AppendASCII("foo"), data.c_str(), + data.size()); +} + +IN_PROC_BROWSER_TEST_F(ProfileWithoutMediaCacheBrowserTest, DeleteMediaCache) { + base::FilePath media_cache_path = + browser()->profile()->GetPath().Append(chrome::kMediaCacheDirname); + + base::ScopedAllowBlockingForTesting allow_blocking; + + FileDestructionWatcher destruction_watcher(media_cache_path); + destruction_watcher.WaitForDestruction(); +} + +// Create a media cache file, and make sure it's deleted by initializing an +// extension browser context. +IN_PROC_BROWSER_TEST_F(ProfileWithoutMediaCacheBrowserTest, + PRE_DeleteIsolatedAppMediaCache) { + scoped_refptr<const extensions::Extension> app = + BuildTestApp(browser()->profile()); + content::StoragePartition* extension_partition = + content::BrowserContext::GetStoragePartitionForSite( + browser()->profile(), + extensions::Extension::GetBaseURLFromExtensionId(app->id())); + + base::FilePath extension_media_cache_path = + extension_partition->GetPath().Append(chrome::kMediaCacheDirname); + + base::ScopedAllowBlockingForTesting allow_blocking; + EXPECT_TRUE(base::CreateDirectory(extension_media_cache_path)); + std::string data = "foo"; + base::WriteFile(extension_media_cache_path.AppendASCII("foo"), data.c_str(), + data.size()); +} + +IN_PROC_BROWSER_TEST_F(ProfileWithoutMediaCacheBrowserTest, + DeleteIsolatedAppMediaCache) { + scoped_refptr<const extensions::Extension> app = + BuildTestApp(browser()->profile()); + content::StoragePartition* extension_partition = + content::BrowserContext::GetStoragePartitionForSite( + browser()->profile(), + extensions::Extension::GetBaseURLFromExtensionId(app->id())); + + base::FilePath extension_media_cache_path = + extension_partition->GetPath().Append(chrome::kMediaCacheDirname); + + FileDestructionWatcher destruction_watcher(extension_media_cache_path); + destruction_watcher.WaitForDestruction(); +}
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 6dd54b7..b8c9017 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -12,6 +12,8 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/feature_list.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" #include "base/macros.h" #include "base/metrics/field_trial.h" @@ -19,6 +21,7 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/task_scheduler/post_task.h" +#include "base/task_scheduler/task_traits.h" #include "base/time/default_clock.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -113,6 +116,19 @@ return net::CACHE_BACKEND_DEFAULT; } +void MaybeDeleteMediaCache(const base::FilePath& media_cache_path) { + if (!base::FeatureList::IsEnabled(features::kUseSameCacheForMedia) || + media_cache_path.empty()) { + return; + } + base::PostTaskWithTraits( + FROM_HERE, + {base::TaskPriority::BACKGROUND, base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(base::IgnoreResult(&base::DeleteFile), media_cache_path, + true /* recursive */)); +} + } // namespace using content::BrowserThread; @@ -522,6 +538,8 @@ InitializeExtensionsRequestContext(profile_params); #endif + MaybeDeleteMediaCache(lazy_params_->media_cache_path); + // Create a media request context based on the main context, but using a // media cache. It shares the same job factory as the main context. StoragePartitionDescriptor details(profile_path_, false); @@ -555,6 +573,11 @@ protocol_handler_interceptor, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) const { + if (!partition_descriptor.in_memory) { + MaybeDeleteMediaCache( + partition_descriptor.path.Append(chrome::kMediaCacheDirname)); + } + // Copy most state from the main context. AppRequestContext* context = new AppRequestContext(); context->CopyFrom(main_context);
diff --git a/chrome/browser/resources/print_preview/new/destination_dialog.html b/chrome/browser/resources/print_preview/new/destination_dialog.html index 02ea28f..eaf8b76 100644 --- a/chrome/browser/resources/print_preview/new/destination_dialog.html +++ b/chrome/browser/resources/print_preview/new/destination_dialog.html
@@ -85,29 +85,35 @@ width: 24px; } - :host #cloudprintPromo .close-button { + :host #cloudprintPromo button { -webkit-margin-start: 12px; + background-color: #f5f5f5; background-image: -webkit-image-set( url(chrome://theme/IDR_CLOSE_DIALOG) 1x, url(chrome://theme/IDR_CLOSE_DIALOG@2x) 2x); background-repeat: no-repeat; background-size: 14px; - height: 14px; - width: 14px; + border: none; + box-shadow: none; + min-height: 14px; + min-width: 14px; + outline: none; + padding: 0; } - :host #cloudprintPromo .close-button:hover { - background-image: -webkit-image-set( - url(chrome://theme/IDR_CLOSE_DIALOG_H) 1x, - url(chrome://theme/IDR_CLOSE_DIALOG_H@2x) 2x); - } - - :host #cloudprintPromo .close-button:active { + :host #cloudprintPromo button:active { background-image: -webkit-image-set( url(chrome://theme/IDR_CLOSE_DIALOG_P) 1x, url(chrome://theme/IDR_CLOSE_DIALOG_P@2x) 2x); } + :host #cloudprintPromo button:focus, + :host #cloudprintPromo button:hover { + background-image: -webkit-image-set( + url(chrome://theme/IDR_CLOSE_DIALOG_H) 1x, + url(chrome://theme/IDR_CLOSE_DIALOG_H@2x) 2x); + } + :host #invitationPromo { flex-direction: column; } @@ -176,7 +182,7 @@ hidden$="[[!showCloudPrintPromo]]"> <img src="../images/cloud.png" class="icon" alt=""> <div class="promo-text"></div> - <div class="close-button"></div> + <button on-click="onCloudPrintPromoDismissed_"></button> </div> <div class="promo" id="invitationPromo" hidden="[[!invitation_]]"> <div inner-h-t-m-l="[[getInvitationText_(invitation_)]]"></div>
diff --git a/chrome/browser/resources/print_preview/new/destination_dialog.js b/chrome/browser/resources/print_preview/new/destination_dialog.js index 3a526c5..4cf257b 100644 --- a/chrome/browser/resources/print_preview/new/destination_dialog.js +++ b/chrome/browser/resources/print_preview/new/destination_dialog.js
@@ -100,9 +100,6 @@ attached: function() { this.tracker_.add( assert(this.$$('.sign-in')), 'click', this.onSignInClick_.bind(this)); - this.tracker_.add( - assert(this.$$('#cloudprintPromo > .close-button')), 'click', - this.onCloudPrintPromoDismissed_.bind(this)); }, /**
diff --git a/chrome/browser/resources/ukm/BUILD.gn b/chrome/browser/resources/ukm/BUILD.gn deleted file mode 100644 index 4fe10b1..0000000 --- a/chrome/browser/resources/ukm/BUILD.gn +++ /dev/null
@@ -1,18 +0,0 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//third_party/closure_compiler/compile_js.gni") - -js_type_check("closure_compile") { - deps = [ - ":ukm_internals", - ] -} - -js_library("ukm_internals") { - deps = [ - "//ui/webui/resources/js:cr", - "//ui/webui/resources/js:util", - ] -}
diff --git a/chrome/browser/resources/ukm/ukm_internals.js b/chrome/browser/resources/ukm/ukm_internals.js deleted file mode 100644 index 9449c73..0000000 --- a/chrome/browser/resources/ukm/ukm_internals.js +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * Fetches data from the Ukm service and updates the DOM to display it as a - * list. - */ -function updateUkmData() { - cr.sendWithPromise('requestUkmData').then((ukmData) => { - $('state').innerText = ukmData.state ? 'True' : 'False'; - $('clientid').innerText = ukmData.client_id; - $('sessionid').innerText = ukmData.session_id; - - sourceDiv = $('sources'); - for (const source of ukmData.sources) { - const sourceElement = document.createElement('h3'); - if (source.url !== undefined) - sourceElement.innerText = `Id: ${source.id} Url: ${source.url}`; - else - sourceElement.innerText = `Id: ${source.id}`; - sourceDiv.appendChild(sourceElement); - - for (const entry of source.entries) { - const entryElement = document.createElement('h4'); - entryElement.innerText = `Entry: ${entry.name}`; - sourceDiv.appendChild(entryElement); - - if (entry.metrics === undefined) - continue; - for (const metric of entry.metrics) { - const metricElement = document.createElement('h5'); - metricElement.innerText = - `Metric: ${metric.name} Value: ${metric.value}`; - sourceDiv.appendChild(metricElement); - } - } - } - }); -} - -updateUkmData();
diff --git a/chrome/browser/search/ntp_icon_source.cc b/chrome/browser/search/ntp_icon_source.cc index e013f4f..15f5e59 100644 --- a/chrome/browser/search/ntp_icon_source.cc +++ b/chrome/browser/search/ntp_icon_source.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_number_conversions.h" #include "cc/paint/skia_paint_canvas.h" #include "chrome/browser/favicon/favicon_service_factory.h" +#include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/instant_io_context.h" #include "chrome/browser/search/suggestions/image_decoder_impl.h" @@ -24,6 +25,7 @@ #include "components/favicon/core/fallback_url_util.h" #include "components/favicon/core/favicon_service.h" #include "components/favicon_base/favicon_types.h" +#include "components/history/core/browser/top_sites.h" #include "components/image_fetcher/core/image_fetcher_impl.h" #include "components/suggestions/proto/suggestions.pb.h" #include "components/suggestions/suggestions_service.h" @@ -34,6 +36,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkPaint.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" #include "ui/base/webui/web_ui_util.h" #include "ui/gfx/canvas.h" #include "ui/gfx/codec/png_codec.h" @@ -255,18 +258,35 @@ const ParsedNtpIconPath parsed = ParseNtpIconPath(path); if (parsed.url.is_valid()) { + int icon_size_in_pixels = + std::ceil(parsed.size_in_dip * parsed.device_scale_factor); + NtpIconRequest request(callback, parsed.url, icon_size_in_pixels, + parsed.device_scale_factor); + + // Check if the requested URL is part of the prepopulated pages (currently, + // only the Web Store). + scoped_refptr<history::TopSites> top_sites = + TopSitesFactory::GetForProfile(profile_); + if (top_sites) { + for (const auto& prepopulated_page : top_sites->GetPrepopulatedPages()) { + if (parsed.url == prepopulated_page.most_visited.url) { + gfx::Image& image = + ui::ResourceBundle::GetSharedInstance().GetImageNamed( + prepopulated_page.favicon_id); + ReturnRenderedIconForRequest(request, image.AsBitmap()); + return; + } + } + } + // This will query for a local favicon. If not found, will take alternative // action in OnLocalFaviconAvailable. const bool fallback_to_host = true; - int icon_size_in_pixels = - std::ceil(parsed.size_in_dip * parsed.device_scale_factor); favicon_service->GetRawFaviconForPageURL( parsed.url, {favicon_base::IconType::kFavicon}, icon_size_in_pixels, fallback_to_host, base::Bind(&NtpIconSource::OnLocalFaviconAvailable, - weak_ptr_factory_.GetWeakPtr(), - NtpIconRequest(callback, parsed.url, icon_size_in_pixels, - parsed.device_scale_factor)), + weak_ptr_factory_.GetWeakPtr(), request), &cancelable_task_tracker_); } else { callback.Run(nullptr);
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 62fa3cb..60b26cfa 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -48,6 +48,7 @@ #include "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h" #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.h" +#include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h" #include "components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/common/autofill_features.h" @@ -597,6 +598,17 @@ profile_web_data_service_.get()) ->change_processor() ->GetControllerDelegateOnUIThread(); + case syncer::AUTOFILL_WALLET_DATA: { + // TODO(feuunk): This doesn't allow switching which database to use at + // runtime. This should be fixed as part of the USS migration for + // payments. + auto service = account_web_data_service_ ? account_web_data_service_ + : profile_web_data_service_; + return autofill::AutofillWalletSyncBridge::FromWebDataService( + service.get()) + ->change_processor() + ->GetControllerDelegateOnUIThread(); + } #if defined(OS_CHROMEOS) case syncer::PRINTERS: return chromeos::SyncedPrintersManagerFactory::GetForBrowserContext(
diff --git a/chrome/browser/themes/increased_contrast_theme_supplier.cc b/chrome/browser/themes/increased_contrast_theme_supplier.cc index 700cbe0a..b403cab6 100644 --- a/chrome/browser/themes/increased_contrast_theme_supplier.cc +++ b/chrome/browser/themes/increased_contrast_theme_supplier.cc
@@ -22,11 +22,10 @@ *color = SK_ColorWHITE; return true; case ThemeProperties::COLOR_FRAME_INACTIVE: + case ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE: *color = SK_ColorGRAY; return true; case ThemeProperties::COLOR_FRAME: - *color = SK_ColorDKGRAY; - return true; case ThemeProperties::COLOR_FRAME_INCOGNITO: *color = SK_ColorDKGRAY; return true;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 2e5deaba4..82df345 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -425,14 +425,6 @@ "cocoa/one_click_signin_dialog_controller.mm", "cocoa/one_click_signin_view_controller.h", "cocoa/one_click_signin_view_controller.mm", - "cocoa/page_info/page_info_bubble_controller.h", - "cocoa/page_info/page_info_bubble_controller.mm", - "cocoa/page_info/page_info_utils_cocoa.h", - "cocoa/page_info/page_info_utils_cocoa.mm", - "cocoa/page_info/permission_selector_button.h", - "cocoa/page_info/permission_selector_button.mm", - "cocoa/page_info/split_block_button.h", - "cocoa/page_info/split_block_button.mm", "cocoa/password_reuse_warning_dialog_cocoa.h", "cocoa/password_reuse_warning_dialog_cocoa.mm", "cocoa/password_reuse_warning_view_controller.h", @@ -551,8 +543,6 @@ "cocoa/touchbar/web_textfield_touch_bar_controller.mm", "cocoa/translate/translate_bubble_bridge_views.h", "cocoa/translate/translate_bubble_bridge_views.mm", - "cocoa/translate/translate_bubble_controller.h", - "cocoa/translate/translate_bubble_controller.mm", "cocoa/url_drop_target.h", "cocoa/url_drop_target.mm", "cocoa/vertical_gradient_view.h", @@ -2622,8 +2612,6 @@ "cocoa/importer/import_lock_dialog_cocoa.mm", "cocoa/login_handler_cocoa.h", "cocoa/login_handler_cocoa.mm", - "cocoa/page_info/page_info_bubble_controller.h", - "cocoa/page_info/page_info_bubble_controller.mm", "cocoa/password_reuse_warning_dialog_cocoa.h", "cocoa/password_reuse_warning_dialog_cocoa.mm", "cocoa/password_reuse_warning_view_controller.h", @@ -3046,6 +3034,12 @@ "views/permission_bubble/chooser_bubble_ui.h", "views/permission_bubble/permission_prompt_impl.cc", "views/permission_bubble/permission_prompt_impl.h", + "views/relaunch_notification/relaunch_notification_controller.cc", + "views/relaunch_notification/relaunch_notification_controller.h", + "views/relaunch_notification/relaunch_recommended_bubble_view.cc", + "views/relaunch_notification/relaunch_recommended_bubble_view.h", + "views/relaunch_notification/relaunch_required_dialog_view.cc", + "views/relaunch_notification/relaunch_required_dialog_view.h", "views/safe_browsing/password_reuse_modal_warning_dialog.cc", "views/safe_browsing/password_reuse_modal_warning_dialog.h", "views/session_crashed_bubble_view.cc", @@ -3498,22 +3492,17 @@ if (!is_chromeos) { sources += [ - "views/relaunch_notification/relaunch_notification_controller.cc", - "views/relaunch_notification/relaunch_notification_controller.h", - "views/relaunch_notification/relaunch_recommended_bubble_view.cc", - "views/relaunch_notification/relaunch_recommended_bubble_view.h", - "views/relaunch_notification/relaunch_required_dialog_view.cc", - "views/relaunch_notification/relaunch_required_dialog_view.h", "views/screen_capture_notification_ui_views.cc", ] - if (is_mac) { - sources += [ - "views/policy/enterprise_startup_dialog_mac_util.h", - "views/policy/enterprise_startup_dialog_mac_util.mm", - "views/relaunch_notification/get_app_menu_anchor_point.h", - "views/relaunch_notification/get_app_menu_anchor_point.mm", - ] - } + } + + if (is_mac) { + sources += [ + "views/policy/enterprise_startup_dialog_mac_util.h", + "views/policy/enterprise_startup_dialog_mac_util.mm", + "views/relaunch_notification/get_app_menu_anchor_point.h", + "views/relaunch_notification/get_app_menu_anchor_point.mm", + ] } if (is_chrome_branded) {
diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc index a6bf7f2..edb6476 100644 --- a/chrome/browser/ui/browser_ui_prefs.cc +++ b/chrome/browser/ui/browser_ui_prefs.cc
@@ -39,9 +39,7 @@ registry->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true); #if !defined(OS_ANDROID) -#if !defined(OS_CHROMEOS) registry->RegisterIntegerPref(prefs::kRelaunchNotification, 0); -#endif // !defined(OS_CHROMEOS) registry->RegisterIntegerPref( prefs::kRelaunchNotificationPeriod, base::saturated_cast<int>(
diff --git a/chrome/browser/ui/cocoa/app_menu/app_menu_controller.mm b/chrome/browser/ui/cocoa/app_menu/app_menu_controller.mm index c50f112..e5ed7c24 100644 --- a/chrome/browser/ui/cocoa/app_menu/app_menu_controller.mm +++ b/chrome/browser/ui/cocoa/app_menu/app_menu_controller.mm
@@ -367,6 +367,9 @@ return; // Remove and re-add menu item so menu gets the correct size. + // |removeItemAtIndex:| can trigger an eager dealloc, so retain it + // in the meantime. + base::scoped_nsobject<NSMenuItem> menuItem([browserActionsMenuItem_ retain]); NSInteger index = [[self menu] indexOfItem:browserActionsMenuItem_]; [[self menu] removeItemAtIndex:index]; [[self menu] insertItem:browserActionsMenuItem_ atIndex:index];
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index 1662cbf..5bf172eb 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -57,7 +57,6 @@ @class TabStripControllerCocoa; @class TabStripView; @class ToolbarController; -@class TranslateBubbleController; namespace content { class WebContents; @@ -109,8 +108,6 @@ BOOL initializing_; // YES while we are currently in initWithBrowser: BOOL ownsBrowser_; // Only ever NO when testing - TranslateBubbleController* translateBubbleController_; // Weak. - // The total amount by which we've grown the window up or down (to display a // bookmark bar and/or download shelf), respectively; reset to 0 when moved // away from the bottom/top or resized (or zoomed).
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 6739d09..534764a 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -79,7 +79,6 @@ #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" #import "chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller.h" #include "chrome/browser/ui/cocoa/translate/translate_bubble_bridge_views.h" -#import "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -1599,54 +1598,8 @@ step:(translate::TranslateStep)step errorType:(translate::TranslateErrors::Type) errorType { - if (chrome::ShowAllDialogsWithViewsToolkit()) { - ShowTranslateBubbleViews([self window], [self locationBarBridge], contents, - step, errorType, true); - return; - } - // TODO(hajimehoshi): The similar logic exists at TranslateBubbleView:: - // ShowBubble. This should be unified. - if (translateBubbleController_) { - // When the user reads the advanced setting panel, the bubble should not be - // changed because they are focusing on the bubble. - if (translateBubbleController_.webContents == contents && - translateBubbleController_.model->GetViewState() == - TranslateBubbleModel::VIEW_STATE_ADVANCED) { - return; - } - if (step != translate::TRANSLATE_STEP_TRANSLATE_ERROR) { - TranslateBubbleModel::ViewState viewState = - TranslateBubbleModelImpl::TranslateStepToViewState(step); - [translateBubbleController_ switchView:viewState]; - } else { - [translateBubbleController_ switchToErrorView:errorType]; - } - return; - } - - std::string sourceLanguage; - std::string targetLanguage; - ChromeTranslateClient::GetTranslateLanguages( - contents, &sourceLanguage, &targetLanguage); - - std::unique_ptr<translate::TranslateUIDelegate> uiDelegate( - new translate::TranslateUIDelegate( - ChromeTranslateClient::GetManagerFromWebContents(contents) - ->GetWeakPtr(), - sourceLanguage, targetLanguage)); - std::unique_ptr<TranslateBubbleModel> model( - new TranslateBubbleModelImpl(step, std::move(uiDelegate))); - translateBubbleController_ = - [[TranslateBubbleController alloc] initWithParentWindow:self - model:std::move(model) - webContents:contents]; - [translateBubbleController_ showWindow:nil]; - - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center addObserver:self - selector:@selector(translateBubbleWindowWillClose:) - name:NSWindowWillCloseNotification - object:[translateBubbleController_ window]]; + ShowTranslateBubbleViews([self window], [self locationBarBridge], contents, + step, errorType, true); } - (void)dismissPermissionBubble { @@ -1655,17 +1608,6 @@ delegate->Closing(); } -// Nil out the weak translate bubble controller reference. -- (void)translateBubbleWindowWillClose:(NSNotification*)notification { - DCHECK_EQ([notification object], [translateBubbleController_ window]); - - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center removeObserver:self - name:NSWindowWillCloseNotification - object:[translateBubbleController_ window]]; - translateBubbleController_ = nil; -} - // If the browser is in incognito mode or has multi-profiles, install the image // view to decorate the window at the upper right. Use the same base y // coordinate as the tab strip.
diff --git a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.h b/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.h deleted file mode 100644 index 3abc77d..0000000 --- a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.h +++ /dev/null
@@ -1,160 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_COCOA_PAGE_INFO_PAGE_INFO_BUBBLE_CONTROLLER_H_ -#define CHROME_BROWSER_UI_COCOA_PAGE_INFO_PAGE_INFO_BUBBLE_CONTROLLER_H_ - -#import <Cocoa/Cocoa.h> - -#include <memory> - -#include "base/mac/scoped_nsobject.h" -#include "base/macros.h" -#import "chrome/browser/ui/cocoa/base_bubble_controller.h" -#include "chrome/browser/ui/page_info/page_info_ui.h" -#include "content/public/browser/web_contents_observer.h" - -class LocationBarDecoration; -class PageInfoUIBridge; -@class InspectLinkView; - -namespace content { -class WebContents; -} - -namespace net { -class X509Certificate; -} - -// This NSWindowController subclass manages the InfoBubbleWindow and view that -// are displayed when the user clicks the omnibox security indicator icon. -@interface PageInfoBubbleController : BaseBubbleController { - @private - content::WebContents* webContents_; - - base::scoped_nsobject<NSView> contentView_; - - // The main content view for the Permissions tab. - NSView* securitySectionView_; - - // Displays the short security summary for the page - // (private/not private/etc.). - NSTextField* securitySummaryField_; - - // Displays a longer explanation of the page's security state, and how the - // user should treat it. - NSTextField* securityDetailsField_; - - // The link button for opening a Chrome Help Center page explaining connection - // security. - NSButton* connectionHelpButton_; - - // URL of the page for which the bubble is shown. - GURL url_; - - // Displays a paragraph to accompany the reset decisions button, explaining - // that the user has made a decision to trust an invalid security certificate - // for the current site. - // This field only shows when there is an acrive certificate exception. - NSTextField* resetDecisionsField_; - - // The link button for revoking certificate decisions. - // This link only shows when there is an active certificate exception. - NSButton* resetDecisionsButton_; - - // The server certificate from the identity info. This should always be - // non-null on a cryptographic connection, and null otherwise. - scoped_refptr<net::X509Certificate> certificate_; - - // Separator line. - NSView* separatorAfterSecuritySection_; - - // Container for the site settings section. - NSView* siteSettingsSectionView_; - - // Container for certificate info in the site settings section. - InspectLinkView* certificateView_; - - // Container for cookies info in the site settings section. - InspectLinkView* cookiesView_; - - // Container for permission info in the site settings section. - NSView* permissionsView_; - - // The link button for showing site settings. - NSButton* siteSettingsButton_; - - // The UI translates user actions to specific events and forwards them to the - // |presenter_|. The |presenter_| handles these events and updates the UI. - std::unique_ptr<PageInfo> presenter_; - - // Bridge which implements the PageInfoUI interface and forwards - // methods on to this class. - std::unique_ptr<PageInfoUIBridge> bridge_; - - // The omnibox icon the bubble is anchored to. The icon is set as active - // when the bubble is opened, and inactive when the bubble is closed. - // Usually we would override OmniboxDecorationBubbleController but the page - // info icon has a race condition where it might switch between - // LocationIconDecoration and SecurityStateBubbleDecoration. - LocationBarDecoration* decoration_; // Weak. - - // The button for changing password decisions. - // This button only shows when there is an password reuse event. - NSButton* changePasswordButton_; - - // The button for whitelisting password reuse decisions. - // This button only shows when there is an password reuse event. - NSButton* whitelistPasswordReuseButton_; -} - -// Designated initializer. The controller will release itself when the bubble -// is closed. |parentWindow| cannot be nil. |webContents| may be nil for -// testing purposes. -- (id)initWithParentWindow:(NSWindow*)parentWindow - pageInfoUIBridge:(PageInfoUIBridge*)bridge - webContents:(content::WebContents*)webContents - url:(const GURL&)url; - -// Return the default width of the window. It may be wider to fit the content. -// This may be overriden by a subclass for testing purposes. -- (CGFloat)defaultWindowWidth; - -@end - -// Provides a bridge between the PageInfoUI C++ interface and the Cocoa -// implementation in PageInfoBubbleController. -class PageInfoUIBridge : public content::WebContentsObserver, - public PageInfoUI { - public: - explicit PageInfoUIBridge(content::WebContents* web_contents); - ~PageInfoUIBridge() override; - - void set_bubble_controller(PageInfoBubbleController* bubble_controller); - - // WebContentsObserver implementation. - void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; - - // PageInfoUI implementations. - void SetCookieInfo(const CookieInfoList& cookie_info_list) override; - void SetPermissionInfo(const PermissionInfoList& permission_info_list, - ChosenObjectInfoList chosen_object_info_list) override; - void SetIdentityInfo(const IdentityInfo& identity_info) override; - - protected: - // WebContentsObserver implementation. - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; - - private: - // The WebContents the bubble UI is attached to. - content::WebContents* web_contents_; - - // The Cocoa controller for the bubble UI. - PageInfoBubbleController* bubble_controller_; - - DISALLOW_COPY_AND_ASSIGN(PageInfoUIBridge); -}; - -#endif // CHROME_BROWSER_UI_COCOA_PAGE_INFO_PAGE_INFO_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm b/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm deleted file mode 100644 index 87f5d3f..0000000 --- a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm +++ /dev/null
@@ -1,1540 +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. - -#import "chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.h" - -#import <AppKit/AppKit.h> - -#include <cmath> - -#include "base/bind.h" -#include "base/i18n/rtl.h" -#include "base/mac/foundation_util.h" -#include "base/mac/mac_util.h" -#include "base/strings/sys_string_conversions.h" -#import "chrome/browser/certificate_viewer.h" -#include "chrome/browser/infobars/infobar_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/cocoa/browser_dialogs_views_mac.h" -#import "chrome/browser/ui/cocoa/browser_window_controller.h" -#include "chrome/browser/ui/cocoa/bubble_anchor_helper.h" -#import "chrome/browser/ui/cocoa/info_bubble_view.h" -#import "chrome/browser/ui/cocoa/info_bubble_window.h" -#include "chrome/browser/ui/cocoa/key_equivalent_constants.h" -#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" -#import "chrome/browser/ui/cocoa/location_bar/page_info_bubble_decoration.h" -#import "chrome/browser/ui/cocoa/page_info/permission_selector_button.h" -#include "chrome/browser/ui/page_info/page_info_dialog.h" -#include "chrome/browser/ui/page_info/permission_menu_model.h" -#import "chrome/browser/ui/tab_dialogs.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/theme_resources.h" -#include "components/content_settings/core/browser/content_settings_registry.h" -#include "components/strings/grit/components_chromium_strings.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/page_navigator.h" -#include "content/public/browser/ssl_host_state_delegate.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/url_constants.h" -#include "extensions/common/constants.h" -#include "skia/ext/skia_utils_mac.h" -#import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h" -#import "ui/base/cocoa/a11y_util.h" -#include "ui/base/cocoa/cocoa_base_utils.h" -#import "ui/base/cocoa/controls/button_utils.h" -#import "ui/base/cocoa/controls/hyperlink_button_cell.h" -#import "ui/base/cocoa/flipped_view.h" -#import "ui/base/cocoa/hover_image_button.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/color_palette.h" -#include "ui/gfx/image/image_skia_util_mac.h" -#import "ui/gfx/mac/coordinate_conversion.h" -#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" -#include "ui/resources/grit/ui_resources.h" - -using ChosenObjectInfoPtr = std::unique_ptr<PageInfoUI::ChosenObjectInfo>; -using ChosenObjectDeleteCallback = - base::Callback<void(const PageInfoUI::ChosenObjectInfo&)>; - -namespace { - -// General --------------------------------------------------------------------- - -// The default width of the window, in view coordinates. It may be larger to -// fit the content. -constexpr CGFloat kDefaultWindowWidth = 320; - -// Padding around each section -constexpr CGFloat kSectionVerticalPadding = 20; -constexpr CGFloat kSectionHorizontalPadding = 16; - -// Links are buttons with invisible padding, so we need to move them back to -// align with other text. -constexpr CGFloat kLinkButtonXAdjustment = 1; - -// Built-in margin for NSButton to take into account. -constexpr CGFloat kNSButtonBuiltinMargin = 4; - -// Security Section ------------------------------------------------------------ - -// Spacing between security summary, security details, and cert decisions text. -constexpr CGFloat kSecurityParagraphSpacing = 12; - -// Site Settings Section ------------------------------------------------------- - -// Square size of the permission images. -constexpr CGFloat kPermissionImageSize = 16; - -// Spacing between a permission image and the text. -constexpr CGFloat kPermissionImageSpacing = 6; - -// Minimum distance between the label and its corresponding menu. -constexpr CGFloat kMinSeparationBetweenLabelAndMenu = 16; - -// Square size of the permission delete button image. -constexpr CGFloat kPermissionDeleteImageSize = 16; - -// The spacing between individual permissions. -constexpr CGFloat kPermissionsVerticalSpacing = 16; - -// Spacing to add after a permission label, either directly on top of -// kPermissionsVerticalSpacing, or before additional text (e.g. "X in use" for -// cookies). -constexpr CGFloat kPermissionLabelBottomPadding = 4; - -// Amount to lower each permission icon to align the icon baseline with the -// label text. -constexpr CGFloat kPermissionIconYAdjustment = 1; - -// Amount to lower each permission popup button to make its text align with the -// permission label. -constexpr CGFloat kPermissionPopupButtonYAdjustment = 3; - -// Internal Page Bubble -------------------------------------------------------- - -// Padding between the window frame and content for the internal page bubble. -constexpr CGFloat kInternalPageFramePadding = 10; - -// Spacing between the image and text for internal pages. -constexpr CGFloat kInternalPageImageSpacing = 10; - -// ----------------------------------------------------------------------------- - -// A unique tag given to chosen object views (e.g. to show a site has access to -// a USB/Bluetooth device) in order to repopulate them on permissions updates. -// This number must not be the same as any permission in ContentSettingsType. -constexpr int kChosenObjectTag = CONTENT_SETTINGS_NUM_TYPES; - -// NOTE: This assumes that there will never be more than one page info -// bubble shown, and that the one that is shown is associated with the current -// window. This matches the behaviour in Views: see PageInfoBubbleView. -PageInfoBubbleController* g_page_info_bubble = nullptr; - -// Takes in the parent window, which should be a BrowserWindow, and gets the -// proper anchor point for the bubble. The returned point is in screen -// coordinates. -NSPoint AnchorPointForWindow(NSWindow* parent) { - Browser* browser = chrome::FindBrowserWithWindow(parent); - DCHECK(browser); - return GetPageInfoAnchorPointForBrowser(browser); -} - -NSImage* GetNSImageFromImageSkia(const gfx::ImageSkia& image) { - return NSImageFromImageSkiaWithColorSpace(image, - base::mac::GetSRGBColorSpace()); -} - -SkColor GetRelatedTextColor() { - return skia::NSDeviceColorToSkColor( - [[NSColor textColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace]); -} - -} // namespace - -// The |InspectLinkView| objects are used to show the Cookie and Certificate -// status and a link to inspect the underlying data. -@interface InspectLinkView : FlippedView -@end - -@implementation InspectLinkView { - NSButton* actionLink_; -} - -- (id)initWithFrame:(NSRect)frame { - if (self = [super initWithFrame:frame]) { - [self setAutoresizingMask:NSViewWidthSizable]; - } - return self; -} - -- (void)setActionLink:(NSButton*)actionLink { - actionLink_ = actionLink; -} - -- (void)setLinkText:(NSString*)linkText { - [actionLink_ setTitle:linkText]; - [GTMUILocalizerAndLayoutTweaker sizeToFitView:actionLink_]; -} - -- (void)setLinkToolTip:(NSString*)linkToolTip { - [actionLink_ setToolTip:linkToolTip]; -} - -- (void)setLinkTarget:(NSObject*)target withAction:(SEL)action { - [actionLink_ setTarget:target]; - [actionLink_ setAction:action]; -} -@end - -@interface ChosenObjectDeleteButton : HoverImageButton { - @private - ChosenObjectInfoPtr objectInfo_; - ChosenObjectDeleteCallback callback_; -} - -// Designated initializer. Takes ownership of |objectInfo|. -- (instancetype)initWithChosenObject:(ChosenObjectInfoPtr)objectInfo - atPoint:(NSPoint)point - withCallback:(ChosenObjectDeleteCallback)callback; - -// Action when the button is clicked. -- (void)deleteClicked:(id)sender; - -@end - -@implementation ChosenObjectDeleteButton - -- (instancetype)initWithChosenObject:(ChosenObjectInfoPtr)objectInfo - atPoint:(NSPoint)point - withCallback:(ChosenObjectDeleteCallback)callback { - NSRect frame = NSMakeRect(point.x, point.y, kPermissionDeleteImageSize, - kPermissionDeleteImageSize); - if (self = [super initWithFrame:frame]) { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - [self setDefaultImage:rb.GetNativeImageNamed(IDR_CLOSE_2).ToNSImage()]; - [self setHoverImage:rb.GetNativeImageNamed(IDR_CLOSE_2_H).ToNSImage()]; - [self setPressedImage:rb.GetNativeImageNamed(IDR_CLOSE_2_P).ToNSImage()]; - [self setBordered:NO]; - [self setToolTip:l10n_util::GetNSString( - objectInfo->ui_info.delete_tooltip_string_id)]; - [self setTarget:self]; - [self setAction:@selector(deleteClicked:)]; - objectInfo_ = std::move(objectInfo); - callback_ = callback; - } - return self; -} - -- (void)deleteClicked:(id)sender { - callback_.Run(*objectInfo_); -} - -@end - -@implementation PageInfoBubbleController - -+ (PageInfoBubbleController*)getPageInfoBubbleForTest { - return g_page_info_bubble; -} - -- (CGFloat)defaultWindowWidth { - return kDefaultWindowWidth; -} - -bool IsInternalURL(const GURL& url) { - return url.SchemeIs(content::kChromeUIScheme) || - url.SchemeIs(content::kChromeDevToolsScheme) || - url.SchemeIs(extensions::kExtensionScheme) || - url.SchemeIs(content::kViewSourceScheme); -} - -- (id)initWithParentWindow:(NSWindow*)parentWindow - pageInfoUIBridge:(PageInfoUIBridge*)bridge - webContents:(content::WebContents*)webContents - url:(const GURL&)url { - DCHECK(parentWindow); - - webContents_ = webContents; - url_ = url; - - // Use an arbitrary height; it will be changed in performLayout. - NSRect contentRect = NSMakeRect(0, 0, [self defaultWindowWidth], 1); - // Create an empty window into which content is placed. - base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] - initWithContentRect:contentRect - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:NO]); - - if ((self = [super initWithWindow:window.get() - parentWindow:parentWindow - anchoredAt:NSZeroPoint])) { - [[self bubble] setArrowLocation:info_bubble::kTopLeading]; - - // Create the container view that uses flipped coordinates. - NSRect contentFrame = NSMakeRect(0, 0, [self defaultWindowWidth], 300); - contentView_.reset([[FlippedView alloc] initWithFrame:contentFrame]); - - // Replace the window's content. - [[[self window] contentView] - setSubviews:[NSArray arrayWithObject:contentView_.get()]]; - - if (IsInternalURL(url_)) { - [self initializeContentsForInternalPage:url_]; - } else { - [self initializeContents]; - } - - bridge_.reset(bridge); - bridge_->set_bubble_controller(self); - } - return self; -} - -- (void)showWindow:(id)sender { - BrowserWindowController* controller = [BrowserWindowController - browserWindowControllerForWindow:[self parentWindow]]; - LocationBarViewMac* locationBar = [controller locationBarBridge]; - if (locationBar) { - decoration_ = locationBar->page_info_decoration(); - decoration_->SetActive(true); - } - - [super showWindow:sender]; -} - -- (void)close { - if (decoration_) { - decoration_->SetActive(false); - decoration_ = nullptr; - } - - [super close]; -} - -- (Profile*)profile { - return Profile::FromBrowserContext(webContents_->GetBrowserContext()); -} - -- (void)windowWillClose:(NSNotification*)notification { - if (presenter_.get()) - presenter_->OnUIClosing(); - presenter_.reset(); - [super windowWillClose:notification]; -} - -- (void)setPresenter:(PageInfo*)presenter { - presenter_.reset(presenter); -} - -// Create the subviews for the bubble for internal Chrome pages. -- (void)initializeContentsForInternalPage:(const GURL&)url { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - - int text = IDS_PAGE_INFO_INTERNAL_PAGE; - int icon = IDR_PRODUCT_LOGO_16; - if (url.SchemeIs(extensions::kExtensionScheme)) { - text = IDS_PAGE_INFO_EXTENSION_PAGE; - icon = IDR_PLUGINS_FAVICON; - } else if (url.SchemeIs(content::kViewSourceScheme)) { - text = IDS_PAGE_INFO_VIEW_SOURCE_PAGE; - // view-source scheme uses the same icon as chrome:// pages. - icon = IDR_PRODUCT_LOGO_16; - } else if (!url.SchemeIs(content::kChromeUIScheme) && - !url.SchemeIs(content::kChromeDevToolsScheme)) { - NOTREACHED(); - } - - NSPoint controlOrigin = - NSMakePoint(kInternalPageFramePadding, - kInternalPageFramePadding + info_bubble::kBubbleArrowHeight); - NSImage* productLogoImage = rb.GetNativeImageNamed(icon).ToNSImage(); - NSImageView* imageView = [self addImageWithSize:[productLogoImage size] - toView:contentView_ - atPoint:controlOrigin]; - [imageView setImage:productLogoImage]; - - NSRect imageFrame = [imageView frame]; - controlOrigin.x += NSWidth(imageFrame) + kInternalPageImageSpacing; - NSTextField* textField = [self addText:l10n_util::GetStringUTF16(text) - withSize:[NSFont smallSystemFontSize] - bold:NO - toView:contentView_ - atPoint:controlOrigin]; - // Center the image vertically with the text. Previously this code centered - // the text vertically while holding the image in place. That produced correct - // results when the image, at 26x26, was taller than (or just slightly - // shorter) than the text, but produced incorrect results once the icon - // shrank to 16x16. The icon should now always be shorter than the text. - // See crbug.com/572044 . - NSRect textFrame = [textField frame]; - imageFrame.origin.y += (NSHeight(textFrame) - NSHeight(imageFrame)) / 2; - [imageView setFrame:imageFrame]; - - // Adjust the contentView to fit everything. - CGFloat maxY = std::max(NSMaxY(imageFrame), NSMaxY(textFrame)); - [contentView_ setFrame:NSMakeRect(0, 0, [self defaultWindowWidth], - maxY + kInternalPageFramePadding)]; - - [self sizeAndPositionWindow]; -} - -// Create the subviews for the page info bubble. -- (void)initializeContents { - securitySectionView_ = [self addSecuritySectionToView:contentView_]; - separatorAfterSecuritySection_ = [self addSeparatorToView:contentView_]; - siteSettingsSectionView_ = [self addSiteSettingsSectionToView:contentView_]; - - [self performLayout]; -} - -// Create and return a subview for the security section and add it to the given -// |superview|. |superview| retains the new view. -- (NSView*)addSecuritySectionToView:(NSView*)superview { - base::scoped_nsobject<NSView> securitySectionView( - [[FlippedView alloc] initWithFrame:[superview frame]]); - [superview addSubview:securitySectionView]; - - // Create a controlOrigin to place the text fields. The y value doesn't - // matter, because the correct value is calculated in -performLayout. - NSPoint controlOrigin = NSMakePoint(kSectionHorizontalPadding, 0); - - // Create a text field for the security summary (private/not private/etc.). - securitySummaryField_ = [self addText:base::string16() - withSize:[NSFont systemFontSize] - bold:NO - toView:securitySectionView - atPoint:controlOrigin]; - - securityDetailsField_ = [self addText:base::string16() - withSize:[NSFont smallSystemFontSize] - bold:NO - toView:securitySectionView - atPoint:controlOrigin]; - - // These will be created only if necessary. - resetDecisionsField_ = nil; - resetDecisionsButton_ = nil; - changePasswordButton_ = nil; - whitelistPasswordReuseButton_ = nil; - - NSString* connectionHelpButtonText = l10n_util::GetNSString(IDS_LEARN_MORE); - connectionHelpButton_ = [self addLinkButtonWithText:connectionHelpButtonText - toView:securitySectionView]; - [connectionHelpButton_ setTarget:self]; - [connectionHelpButton_ setAction:@selector(openConnectionHelp:)]; - - if (base::i18n::IsRTL()) { - securitySummaryField_.alignment = NSRightTextAlignment; - securityDetailsField_.alignment = NSRightTextAlignment; - } - - return securitySectionView.get(); -} - -// Create and return a subview for the site settings and add it to the given -// |superview|. |superview| retains the new view. -- (NSView*)addSiteSettingsSectionToView:(NSView*)superview { - base::scoped_nsobject<NSView> siteSettingsSectionView( - [[FlippedView alloc] initWithFrame:[superview frame]]); - [superview addSubview:siteSettingsSectionView]; - - permissionsView_ = - [[[FlippedView alloc] initWithFrame:[superview frame]] autorelease]; - [siteSettingsSectionView addSubview:permissionsView_]; - - // The certificate section is created on demand. - certificateView_ = nil; - - // Initialize the two containers that hold the controls. The initial frames - // are arbitrary, and will be adjusted after the controls are laid out. - PageInfoUI::PermissionInfo info; - info.type = CONTENT_SETTINGS_TYPE_COOKIES; - info.setting = CONTENT_SETTING_ALLOW; - cookiesView_ = [self - addInspectLinkToView:siteSettingsSectionView - sectionIcon:GetNSImageFromImageSkia( - PageInfoUI::GetPermissionIcon( - info, GetRelatedTextColor())) - sectionTitle:l10n_util::GetStringUTF16(IDS_PAGE_INFO_COOKIES) - linkText:l10n_util::GetPluralNSStringF( - IDS_PAGE_INFO_NUM_COOKIES, 0)]; - [cookiesView_ setLinkTarget:self - withAction:@selector(showCookiesAndSiteData:)]; - - // Create the link button to view site settings. Its position will be set in - // performLayout. - NSString* siteSettingsButtonText = - l10n_util::GetNSString(IDS_PAGE_INFO_SITE_SETTINGS_LINK); - siteSettingsButton_ = [self addButtonWithText:siteSettingsButtonText - toView:siteSettingsSectionView]; - [GTMUILocalizerAndLayoutTweaker sizeToFitView:siteSettingsButton_]; - - [siteSettingsButton_ setTarget:self]; - [siteSettingsButton_ setAction:@selector(showSiteSettingsData:)]; - - return siteSettingsSectionView.get(); -} - -- (InspectLinkView*)addInspectLinkToView:(NSView*)superview - sectionIcon:(NSImage*)imageIcon - sectionTitle:(const base::string16&)titleText - linkText:(NSString*)linkText { - // Create the subview. - base::scoped_nsobject<InspectLinkView> newView( - [[InspectLinkView alloc] initWithFrame:[superview frame]]); - [superview addSubview:newView]; - - bool isRTL = base::i18n::IsRTL(); - NSPoint controlOrigin = NSMakePoint(kSectionHorizontalPadding, 0); - - CGFloat viewWidth = NSWidth([newView frame]); - - // Reset X for the icon. - if (isRTL) { - controlOrigin.x = - viewWidth - kPermissionImageSize - kSectionHorizontalPadding; - } - - NSImageView* imageView = [self addImageWithSize:[imageIcon size] - toView:newView - atPoint:controlOrigin]; - [imageView setImage:imageIcon]; - - NSButton* actionLink = [self addLinkButtonWithText:linkText toView:newView]; - [newView setActionLink:actionLink]; - - if (isRTL) { - controlOrigin.x -= kPermissionImageSpacing; - NSTextField* sectionTitle = [self addText:titleText - withSize:[NSFont systemFontSize] - bold:NO - toView:newView - atPoint:controlOrigin]; - [sectionTitle sizeToFit]; - - NSPoint sectionTitleOrigin = [sectionTitle frame].origin; - sectionTitleOrigin.x -= NSWidth([sectionTitle frame]); - [sectionTitle setFrameOrigin:sectionTitleOrigin]; - - // Align the icon with the text. - [self alignPermissionIcon:imageView withTextField:sectionTitle]; - - controlOrigin.y += - NSHeight([sectionTitle frame]) + kPermissionLabelBottomPadding; - controlOrigin.x -= NSWidth([actionLink frame]) - kLinkButtonXAdjustment; - [actionLink setFrameOrigin:controlOrigin]; - } else { - controlOrigin.x += kPermissionImageSize + kPermissionImageSpacing; - NSTextField* sectionTitle = [self addText:titleText - withSize:[NSFont systemFontSize] - bold:NO - toView:newView - atPoint:controlOrigin]; - [sectionTitle sizeToFit]; - - // Align the icon with the text. - [self alignPermissionIcon:imageView withTextField:sectionTitle]; - - controlOrigin.y += - NSHeight([sectionTitle frame]) + kPermissionLabelBottomPadding; - controlOrigin.x -= kLinkButtonXAdjustment; - [actionLink setFrameOrigin:controlOrigin]; - } - - controlOrigin.y += NSHeight([actionLink frame]); - [newView setFrameSize:NSMakeSize(NSWidth([newView frame]), controlOrigin.y)]; - - return newView.get(); -} - -// Handler for the link button below the list of cookies. -- (void)showCookiesAndSiteData:(id)sender { - DCHECK(webContents_); - DCHECK(presenter_); - presenter_->RecordPageInfoAction(PageInfo::PAGE_INFO_COOKIES_DIALOG_OPENED); - TabDialogs::FromWebContents(webContents_)->ShowCollectedCookies(); -} - -// Handler for the site settings button below the list of permissions. -- (void)showSiteSettingsData:(id)sender { - DCHECK(webContents_); - DCHECK(presenter_); - presenter_->OpenSiteSettingsView(); -} - -- (void)openConnectionHelp:(id)sender { - DCHECK(webContents_); - DCHECK(presenter_); - presenter_->RecordPageInfoAction(PageInfo::PAGE_INFO_CONNECTION_HELP_OPENED); - webContents_->OpenURL(content::OpenURLParams( - GURL(chrome::kPageInfoHelpCenterURL), content::Referrer(), - WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, - false)); -} - -// Handler for the link button to show certificate information. -- (void)showCertificateInfo:(id)sender { - DCHECK(certificate_.get()); - DCHECK(presenter_); - presenter_->RecordPageInfoAction( - PageInfo::PAGE_INFO_CERTIFICATE_DIALOG_OPENED); - ShowCertificateViewer(webContents_, [self parentWindow], certificate_.get()); -} - -// Handler for the link button to revoke user certificate decisions. -- (void)resetCertificateDecisions:(id)sender { - DCHECK(resetDecisionsButton_); - presenter_->OnRevokeSSLErrorBypassButtonPressed(); - [self close]; -} - -// Handler for the button to change password decisions. -- (void)changePasswordDecisions:(id)sender { - DCHECK(changePasswordButton_); - presenter_->OnChangePasswordButtonPressed(webContents_); - [self close]; -} - -// Handler for the button to whitelist password reuse decisions. -- (void)whitelistPasswordReuseDecisions:(id)sender { - DCHECK(whitelistPasswordReuseButton_); - presenter_->OnWhitelistPasswordReuseButtonPressed(webContents_); - [self close]; -} - -- (CGFloat)layoutViewAtRTLStart:(NSView*)view withYPosition:(CGFloat)yPos { - CGFloat xPos; - if (base::i18n::IsRTL()) { - xPos = kDefaultWindowWidth - kSectionHorizontalPadding - - NSWidth([view frame]) + kNSButtonBuiltinMargin; - } else { - xPos = kSectionHorizontalPadding - kNSButtonBuiltinMargin; - } - [view setFrameOrigin:NSMakePoint(xPos, yPos - kNSButtonBuiltinMargin)]; - return yPos + NSHeight([view frame]) - kNSButtonBuiltinMargin; -} - -// Set the Y position of |view| to the given position, and return the position -// of its bottom edge. -- (CGFloat)setYPositionOfView:(NSView*)view to:(CGFloat)position { - NSRect frame = [view frame]; - frame.origin.y = position; - [view setFrame:frame]; - return position + NSHeight(frame); -} - -- (void)setWidthOfView:(NSView*)view to:(CGFloat)width { - [view setFrameSize:NSMakeSize(width, NSHeight([view frame]))]; -} - -- (void)setHeightOfView:(NSView*)view to:(CGFloat)height { - [view setFrameSize:NSMakeSize(NSWidth([view frame]), height)]; -} - -// Layout all of the controls in the window. This should be called whenever -// the content has changed. -- (void)performLayout { - // Skip layout if the bubble is closing. - InfoBubbleWindow* bubbleWindow = - base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]); - if ([bubbleWindow isClosing]) - return; - - // Make the content at least as wide as the permissions view. - CGFloat contentWidth = - std::max([self defaultWindowWidth], NSWidth([permissionsView_ frame])); - - // Set the width of the content view now, so that all the text fields will - // be sized to fit before their heights and vertical positions are adjusted. - [self setWidthOfView:contentView_ to:contentWidth]; - [self setWidthOfView:securitySectionView_ to:contentWidth]; - [self setWidthOfView:siteSettingsSectionView_ to:contentWidth]; - - CGFloat yPos = 0; - - [self layoutSecuritySection]; - yPos = [self setYPositionOfView:securitySectionView_ to:yPos]; - - yPos = [self setYPositionOfView:separatorAfterSecuritySection_ to:yPos]; - - [self layoutSiteSettingsSection]; - yPos = [self setYPositionOfView:siteSettingsSectionView_ to:yPos]; - - [contentView_ setFrame:NSMakeRect(0, 0, NSWidth([contentView_ frame]), yPos)]; - - [self sizeAndPositionWindow]; -} - -- (void)layoutSecuritySection { - // Margins are handled by the caller. - CGFloat yPos = 0; - - [self sizeTextFieldHeightToFit:securitySummaryField_]; - yPos = [self setYPositionOfView:securitySummaryField_ - to:yPos + kSectionVerticalPadding]; - - [self sizeTextFieldHeightToFit:securityDetailsField_]; - yPos = [self setYPositionOfView:securityDetailsField_ - to:yPos + kSecurityParagraphSpacing]; - - // A common anchor point for link elements - CGFloat linkY = kSectionHorizontalPadding - kLinkButtonXAdjustment; - - NSPoint helpOrigin = NSMakePoint(linkY, yPos); - if (base::i18n::IsRTL()) { - helpOrigin.x = NSWidth([contentView_ frame]) - helpOrigin.x - - NSWidth(connectionHelpButton_.frame); - } - [connectionHelpButton_ setFrameOrigin:helpOrigin]; - yPos = NSMaxY([connectionHelpButton_ frame]); - - if (resetDecisionsButton_) { - DCHECK(resetDecisionsField_); - yPos = [self setYPositionOfView:resetDecisionsField_ - to:yPos + kSecurityParagraphSpacing]; - - NSPoint resetOrigin = NSMakePoint(linkY, yPos); - if (base::i18n::IsRTL()) { - resetOrigin.x = NSWidth([contentView_ frame]) - resetOrigin.x - - NSWidth(resetDecisionsButton_.frame); - } - [resetDecisionsButton_ setFrameOrigin:resetOrigin]; - yPos = NSMaxY([resetDecisionsButton_ frame]); - } - - if (changePasswordButton_) { - NSPoint changePasswordButtonOrigin; - NSPoint whitelistReuseButtonOrigin; - CGFloat viewWidth = NSWidth([contentView_ frame]); - CGFloat changePasswordButtonWidth = NSWidth([changePasswordButton_ frame]); - CGFloat whitelistReuseButtonWidth = - NSWidth([whitelistPasswordReuseButton_ frame]); - CGFloat horizontalPadding = - kSectionHorizontalPadding - kNSButtonBuiltinMargin; - bool canFitInOneLine = changePasswordButtonWidth + - whitelistReuseButtonWidth + - 2 * horizontalPadding <= - viewWidth; - bool isRTL = base::i18n::IsRTL(); - // Buttons are left-aligned for LTR languages, and are right aligned for - // RTL languages. Button order follows OSX convention. - if (canFitInOneLine) { - whitelistReuseButtonOrigin.y = changePasswordButtonOrigin.y = - yPos + kSecurityParagraphSpacing; - if (isRTL) { - whitelistReuseButtonOrigin.x = - viewWidth - whitelistReuseButtonWidth - horizontalPadding; - changePasswordButtonOrigin.x = - whitelistReuseButtonOrigin.x - changePasswordButtonWidth; - } else { - whitelistReuseButtonOrigin.x = horizontalPadding; - changePasswordButtonOrigin.x = - whitelistReuseButtonOrigin.x + whitelistReuseButtonWidth; - } - } else { - // If these buttons cannot fit in one line, stack them vertically. - CGFloat buttonWidth = viewWidth - 2 * horizontalPadding; - whitelistReuseButtonOrigin.x = horizontalPadding; - whitelistReuseButtonOrigin.y = yPos + kSecurityParagraphSpacing; - [whitelistPasswordReuseButton_ - setFrameSize:NSMakeSize( - buttonWidth, - NSHeight([whitelistPasswordReuseButton_ frame]))]; - changePasswordButtonOrigin.x = horizontalPadding; - changePasswordButtonOrigin.y = - yPos + kSecurityParagraphSpacing + - NSHeight([whitelistPasswordReuseButton_ frame]); - [changePasswordButton_ - setFrameSize:NSMakeSize(buttonWidth, - NSHeight([changePasswordButton_ frame]))]; - } - [changePasswordButton_ setFrameOrigin:changePasswordButtonOrigin]; - [whitelistPasswordReuseButton_ setFrameOrigin:whitelistReuseButtonOrigin]; - yPos = NSMaxY([changePasswordButton_ frame]) - kNSButtonBuiltinMargin; - } - - // Resize the height based on contents. - [self setHeightOfView:securitySectionView_ to:yPos + kSectionVerticalPadding]; -} - -- (void)layoutSiteSettingsSection { - // Margins are handled by the caller. - CGFloat yPos = 0; - - yPos = [self setYPositionOfView:permissionsView_ to:yPos] + - kPermissionsVerticalSpacing; - - if (certificateView_) { - yPos = [self setYPositionOfView:certificateView_ to:yPos] + - kPermissionsVerticalSpacing; - } - - yPos = - [self setYPositionOfView:cookiesView_ to:yPos] + kSectionVerticalPadding; - - yPos = [self layoutViewAtRTLStart:siteSettingsButton_ withYPosition:yPos] + - kSectionVerticalPadding; - - // Resize the height based on contents. - [self setHeightOfView:siteSettingsSectionView_ to:yPos]; -} - -// Adjust the size of the window to match the size of the content, and position -// the bubble anchor appropriately. -- (void)sizeAndPositionWindow { - NSRect windowFrame = [contentView_ frame]; - windowFrame.size = - [[[self window] contentView] convertSize:windowFrame.size toView:nil]; - // Adjust the origin by the difference in height. - windowFrame.origin = [[self window] frame].origin; - windowFrame.origin.y -= - NSHeight(windowFrame) - NSHeight([[self window] frame]); - - // Resize the window. Only animate if the window is visible, otherwise it - // could be "growing" while it's opening, looking awkward. - [[self window] setFrame:windowFrame - display:YES - animate:[[self window] isVisible]]; - - // Adjust the anchor for the bubble. - [self setAnchorPoint:AnchorPointForWindow([self parentWindow])]; -} - -// Sets properties on the given |field| to act as the title or description -// labels in the bubble. -- (void)configureTextFieldAsLabel:(NSTextField*)textField { - [textField setEditable:NO]; - [textField setSelectable:YES]; - [textField setDrawsBackground:NO]; - [textField setBezeled:NO]; -} - -// Adjust the height of the given text field to match its text. -- (void)sizeTextFieldHeightToFit:(NSTextField*)textField { - NSRect frame = [textField frame]; - frame.size.height += - [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:textField]; - [textField setFrame:frame]; -} - -// Create a new text field and add it to the given array of subviews. -// The array will retain a reference to the object. -- (NSTextField*)addText:(const base::string16&)text - withSize:(CGFloat)fontSize - bold:(BOOL)bold - toView:(NSView*)view - atPoint:(NSPoint)point { - // Size the text to take up the full available width, with some padding. - // The height is arbitrary as it will be adjusted later. - CGFloat width = NSWidth([view frame]) - point.x - kSectionHorizontalPadding; - NSRect frame = NSMakeRect(point.x, point.y, width, 100); - base::scoped_nsobject<NSTextField> textField( - [[NSTextField alloc] initWithFrame:frame]); - [self configureTextFieldAsLabel:textField.get()]; - [textField setStringValue:base::SysUTF16ToNSString(text)]; - NSFont* font = bold ? [NSFont boldSystemFontOfSize:fontSize] - : [NSFont systemFontOfSize:fontSize]; - [textField setFont:font]; - [self sizeTextFieldHeightToFit:textField]; - [textField setAutoresizingMask:NSViewWidthSizable]; - [view addSubview:textField.get()]; - return textField.get(); -} - -// Add an image as a subview of the given view, placed at a pre-determined x -// position and the given y position. The image is not in the accessibility -// order, since the image is always accompanied by text in this bubble. Return -// the new NSImageView. -- (NSImageView*)addImageWithSize:(NSSize)size - toView:(NSView*)view - atPoint:(NSPoint)point { - NSRect frame = NSMakeRect(point.x, point.y, size.width, size.height); - base::scoped_nsobject<NSImageView> imageView( - [[NSImageView alloc] initWithFrame:frame]); - ui::a11y_util::HideImageFromAccessibilityOrder(imageView); - [imageView setImageFrameStyle:NSImageFrameNone]; - [view addSubview:imageView.get()]; - return imageView.get(); -} - -// Add a separator as a subview of the given view. Return the new view. -- (NSView*)addSeparatorToView:(NSView*)view { - // Use an arbitrary position; it will be adjusted in performLayout. - NSBox* spacer = [self - horizontalSeparatorWithFrame:NSMakeRect(0, 0, NSWidth([view frame]), 0)]; - [view addSubview:spacer]; - return spacer; -} - -// Add a link button with the given text to |view|. -- (NSButton*)addLinkButtonWithText:(NSString*)text toView:(NSView*)view { - // Frame size is arbitrary; it will be adjusted by the layout tweaker. - NSRect frame = NSMakeRect(kSectionHorizontalPadding, 0, 100, 10); - base::scoped_nsobject<NSButton> button( - [[NSButton alloc] initWithFrame:frame]); - base::scoped_nsobject<HyperlinkButtonCell> cell( - [[HyperlinkButtonCell alloc] initTextCell:text]); - [cell setControlSize:NSSmallControlSize]; - [button setCell:cell.get()]; - [button setButtonType:NSMomentaryPushInButton]; - [button setBezelStyle:NSRegularSquareBezelStyle]; - [view addSubview:button.get()]; - - [GTMUILocalizerAndLayoutTweaker sizeToFitView:button.get()]; - return button.get(); -} - -// Create and return a button with the specified text and add it to the given -// |view|. |view| retains the new button. -- (NSButton*)addButtonWithText:(NSString*)text toView:(NSView*)view { - NSRect containerFrame = [view frame]; - // Frame size is arbitrary; it will be adjusted by the layout tweaker. - NSRect frame = NSMakeRect(kSectionHorizontalPadding, 0, 100, 10); - base::scoped_nsobject<NSButton> button( - [[NSButton alloc] initWithFrame:frame]); - - // Determine the largest possible size for this button. The size is the width - // of the connection section minus the padding on both sides minus the - // connection image size and spacing. - CGFloat maxTitleWidth = - containerFrame.size.width - kSectionHorizontalPadding * 2; - - base::scoped_nsobject<NSButtonCell> cell( - [[NSButtonCell alloc] initTextCell:text]); - [button setCell:cell.get()]; - [GTMUILocalizerAndLayoutTweaker sizeToFitView:button.get()]; - - // Ensure the containing view is large enough to contain the button with its - // widest possible title. - NSRect buttonFrame = [button frame]; - buttonFrame.size.width = maxTitleWidth; - - [button setFrame:buttonFrame]; - [button setButtonType:NSMomentaryPushInButton]; - [button setBezelStyle:NSRegularSquareBezelStyle]; - [view addSubview:button.get()]; - - return button.get(); -} - -// Set the content of the identity and identity status fields, and add the -// Certificate view or password reuse buttons if applicable. -- (void)setIdentityInfo:(const PageInfoUI::IdentityInfo&)identityInfo { - std::unique_ptr<PageInfoUI::SecurityDescription> security_description = - identityInfo.GetSecurityDescription(); - [securitySummaryField_ - setStringValue:base::SysUTF16ToNSString(security_description->summary)]; - - [securityDetailsField_ - setStringValue:base::SysUTF16ToNSString(security_description->details)]; - - certificate_ = identityInfo.certificate; - - if (certificate_) { - if (identityInfo.show_ssl_decision_revoke_button) { - resetDecisionsField_ = - [self addText:base::string16() - withSize:[NSFont smallSystemFontSize] - bold:NO - toView:securitySectionView_ - atPoint:NSMakePoint(kSectionHorizontalPadding, 0)]; - [resetDecisionsField_ - setStringValue:l10n_util::GetNSString( - IDS_PAGE_INFO_INVALID_CERTIFICATE_DESCRIPTION)]; - [self sizeTextFieldHeightToFit:resetDecisionsField_]; - - resetDecisionsButton_ = [self - addLinkButtonWithText: - l10n_util::GetNSString( - IDS_PAGE_INFO_RESET_INVALID_CERTIFICATE_DECISIONS_BUTTON) - toView:securitySectionView_]; - [resetDecisionsButton_ setTarget:self]; - [resetDecisionsButton_ setAction:@selector(resetCertificateDecisions:)]; - - if (base::i18n::IsRTL()) { - resetDecisionsField_.alignment = NSRightTextAlignment; - } - } - - // Show information about the page's certificate. - bool isValid = - (identityInfo.identity_status != PageInfo::SITE_IDENTITY_STATUS_ERROR); - NSString* linkText = l10n_util::GetNSString( - isValid ? IDS_PAGE_INFO_CERTIFICATE_VALID_LINK - : IDS_PAGE_INFO_CERTIFICATE_INVALID_LINK); - - certificateView_ = - [self addInspectLinkToView:siteSettingsSectionView_ - sectionIcon:NSImageFromImageSkia( - PageInfoUI::GetCertificateIcon( - GetRelatedTextColor())) - sectionTitle:l10n_util::GetStringUTF16( - IDS_PAGE_INFO_CERTIFICATE) - linkText:linkText]; - if (isValid) { - [certificateView_ - setLinkToolTip:l10n_util::GetNSStringF( - IDS_PAGE_INFO_CERTIFICATE_VALID_LINK_TOOLTIP, - base::UTF8ToUTF16( - certificate_->issuer().GetDisplayName()))]; - } else { - [certificateView_ - setLinkToolTip:l10n_util::GetNSString( - IDS_PAGE_INFO_CERTIFICATE_INVALID_LINK_TOOLTIP)]; - } - - [certificateView_ setLinkTarget:self - withAction:@selector(showCertificateInfo:)]; - } - if (identityInfo.show_change_password_buttons) { - whitelistPasswordReuseButton_ = [ButtonUtils - buttonWithTitle:l10n_util::GetNSString( - IDS_PAGE_INFO_WHITELIST_PASSWORD_REUSE_BUTTON) - action:@selector(whitelistPasswordReuseDecisions:) - target:self]; - [whitelistPasswordReuseButton_ sizeToFit]; - [whitelistPasswordReuseButton_ setKeyEquivalent:kKeyEquivalentEscape]; - [securitySectionView_ addSubview:whitelistPasswordReuseButton_]; - changePasswordButton_ = - [ButtonUtils buttonWithTitle:l10n_util::GetNSString( - IDS_PAGE_INFO_CHANGE_PASSWORD_BUTTON) - action:@selector(changePasswordDecisions:) - target:self]; - [changePasswordButton_ sizeToFit]; - [changePasswordButton_ setKeyEquivalent:kKeyEquivalentReturn]; - [securitySectionView_ addSubview:changePasswordButton_]; - } - - [self performLayout]; -} - -// Add a pop-up button for |permissionInfo| to the given view. -- (NSPopUpButton*)addPopUpButtonForPermission: - (const PageInfoUI::PermissionInfo&)permissionInfo - toView:(NSView*)view - atPoint:(NSPoint)point { - GURL url = webContents_ ? webContents_->GetURL() : GURL(); - __block PageInfoBubbleController* weakSelf = self; - PermissionMenuModel::ChangeCallback callback = base::BindRepeating( - base::RetainBlock(^(const PageInfoUI::PermissionInfo& permission) { - [weakSelf onPermissionChanged:permission.type to:permission.setting]; - })); - base::scoped_nsobject<PermissionSelectorButton> button( - [[PermissionSelectorButton alloc] initWithPermissionInfo:permissionInfo - forURL:url - withCallback:callback - profile:[self profile]]); - - // Determine the largest possible size for this button. - CGFloat maxTitleWidth = - [button maxTitleWidthForContentSettingsType:permissionInfo.type - withDefaultSetting:permissionInfo.default_setting - profile:[self profile]]; - - // Ensure the containing view is large enough to contain the button with its - // widest possible title. - NSRect containerFrame = [view frame]; - containerFrame.size.width = - std::max(NSWidth(containerFrame), - point.x + maxTitleWidth + kSectionHorizontalPadding); - [view setFrame:containerFrame]; - [view addSubview:button.get()]; - - // Tag the button with the permission type so it can be updated later. - [button setTag:permissionInfo.type]; - return button.get(); -} - -// Add a delete button for |objectInfo| to the given view. -- (NSButton*)addDeleteButtonForChosenObject:(ChosenObjectInfoPtr)objectInfo - toView:(NSView*)view - atPoint:(NSPoint)point { - __block PageInfoBubbleController* weakSelf = self; - auto callback = base::BindRepeating( - base::RetainBlock(^(const PageInfoUI::ChosenObjectInfo& objectInfo) { - [weakSelf onChosenObjectDeleted:objectInfo]; - })); - base::scoped_nsobject<ChosenObjectDeleteButton> button( - [[ChosenObjectDeleteButton alloc] - initWithChosenObject:std::move(objectInfo) - atPoint:point - withCallback:callback]); - - // Ensure the containing view is large enough to contain the button. - NSRect containerFrame = [view frame]; - containerFrame.size.width = - std::max(NSWidth(containerFrame), point.x + kPermissionDeleteImageSize + - kSectionHorizontalPadding); - [view setFrame:containerFrame]; - [view addSubview:button.get()]; - [button setTag:kChosenObjectTag]; - return button.get(); -} - -// Called when the user changes the setting of a permission. -- (void)onPermissionChanged:(ContentSettingsType)permissionType - to:(ContentSetting)newSetting { - if (presenter_) - presenter_->OnSitePermissionChanged(permissionType, newSetting); -} - -// Called when the user revokes permission for a previously chosen object. -- (void)onChosenObjectDeleted:(const PageInfoUI::ChosenObjectInfo&)info { - if (presenter_) - presenter_->OnSiteChosenObjectDeleted(info.ui_info, *info.object); -} - -// Adds a new row to the UI listing the permissions. Returns the NSPoint of the -// last UI element added (either the permission button, in LTR, or the text -// label, in RTL). -- (NSPoint)addPermission:(const PageInfoUI::PermissionInfo&)permissionInfo - toView:(NSView*)view - atPoint:(NSPoint)point { - base::string16 labelText = - PageInfoUI::PermissionTypeToUIString(permissionInfo.type); - bool isRTL = base::i18n::IsRTL(); - base::scoped_nsobject<NSImage> image( - [GetNSImageFromImageSkia(PageInfoUI::GetPermissionIcon( - permissionInfo, GetRelatedTextColor())) retain]); - - NSPoint position; - NSImageView* imageView; - NSPopUpButton* button; - NSTextField* label; - - CGFloat viewWidth = NSWidth([view frame]); - - if (isRTL) { - point.x = NSWidth([view frame]) - kPermissionImageSize - - kSectionHorizontalPadding; - imageView = [self addImageWithSize:[image size] toView:view atPoint:point]; - [imageView setImage:image]; - point.x -= kPermissionImageSpacing; - - label = [self addText:labelText - withSize:[NSFont systemFontSize] - bold:NO - toView:view - atPoint:point]; - [label sizeToFit]; - point.x -= NSWidth([label frame]); - [label setFrameOrigin:point]; - - position = - NSMakePoint(point.x, point.y + kPermissionPopupButtonYAdjustment); - button = [self addPopUpButtonForPermission:permissionInfo - toView:view - atPoint:position]; - position.x -= NSWidth([button frame]); - [button setFrameOrigin:position]; - } else { - imageView = [self addImageWithSize:[image size] toView:view atPoint:point]; - [imageView setImage:image]; - point.x += kPermissionImageSize + kPermissionImageSpacing; - - label = [self addText:labelText - withSize:[NSFont systemFontSize] - bold:NO - toView:view - atPoint:point]; - [label sizeToFit]; - - position = NSMakePoint(NSMaxX([label frame]), - point.y + kPermissionPopupButtonYAdjustment); - - button = [self addPopUpButtonForPermission:permissionInfo - toView:view - atPoint:position]; - } - [label setToolTip:base::SysUTF16ToNSString(labelText)]; - - [view setFrameSize:NSMakeSize(viewWidth, NSHeight([view frame]))]; - - // Adjust the vertical position of the button so that its title text is - // aligned with the label. Assumes that the text is the same size in both. - // Also adjust the horizontal position to remove excess space due to the - // invisible bezel. - NSRect titleRect = [[button cell] titleRectForBounds:[button bounds]]; - if (isRTL) { - position.x = kSectionHorizontalPadding; - } else { - position.x = kDefaultWindowWidth - kSectionHorizontalPadding - - [button frame].size.width; - } - position.y -= titleRect.origin.y; - [button setFrameOrigin:position]; - - // Truncate the label if it's too wide. - // This is a workaround for https://crbug.com/654268 until MacViews ships. - NSRect labelFrame = [label frame]; - if (isRTL) { - CGFloat maxLabelWidth = NSMaxX(labelFrame) - NSMaxX([button frame]) - - kMinSeparationBetweenLabelAndMenu; - if (NSWidth(labelFrame) > maxLabelWidth) { - labelFrame.origin.x = NSMaxX(labelFrame) - maxLabelWidth; - labelFrame.size.width = maxLabelWidth; - [label setFrame:labelFrame]; - [[label cell] setLineBreakMode:NSLineBreakByTruncatingTail]; - } - } else { - CGFloat maxLabelWidth = NSMinX([button frame]) - NSMinX(labelFrame) - - kMinSeparationBetweenLabelAndMenu; - if (NSWidth(labelFrame) > maxLabelWidth) { - labelFrame.size.width = maxLabelWidth; - [label setFrame:labelFrame]; - [[label cell] setLineBreakMode:NSLineBreakByTruncatingTail]; - } - } - - // Align the icon with the text. - [self alignPermissionIcon:imageView withTextField:label]; - - // Permissions specified by policy or an extension cannot be changed. - if (permissionInfo.source == content_settings::SETTING_SOURCE_EXTENSION || - permissionInfo.source == content_settings::SETTING_SOURCE_POLICY) { - [button setEnabled:NO]; - } - - // Update |point| to match the y of the bottomost UI element added (|button|). - NSRect buttonFrame = [button frame]; - point.y = NSMaxY(labelFrame) + kPermissionLabelBottomPadding; - - // Show the reason for the permission decision in a new row if it did not come - // from the user. - base::string16 reason = PageInfoUI::PermissionDecisionReasonToUIString( - [self profile], permissionInfo, url_); - if (!reason.empty()) { - // Do this even in RTL to make sure -addText sets the right width for the - // permission decision reason label. - point.x = kSectionHorizontalPadding + kPermissionImageSize + - kPermissionImageSpacing; - - label = [self addText:reason - withSize:[NSFont smallSystemFontSize] - bold:NO - toView:view - atPoint:point]; - if (isRTL) { - [label setAlignment:NSRightTextAlignment]; - // Shift the reason left to align the permission label and the permission - // decision reason's right edges. - point.x -= (kPermissionImageSize + kPermissionImageSpacing); - [label setFrameOrigin:point]; - } - - label.textColor = - skia::SkColorToSRGBNSColor(PageInfoUI::GetSecondaryTextColor()); - point.y += NSHeight(label.frame); - } - - return NSMakePoint(NSMaxX(buttonFrame), point.y); -} - -// Adds a new row to the UI listing the permissions. Returns the NSPoint of the -// last UI element added (either the permission button, in LTR, or the text -// label, in RTL). -- (NSPoint)addChosenObject:(ChosenObjectInfoPtr)objectInfo - toView:(NSView*)view - atPoint:(NSPoint)point { - base::string16 labelText = l10n_util::GetStringFUTF16( - objectInfo->ui_info.label_string_id, - PageInfoUI::ChosenObjectToUIString(*objectInfo)); - bool isRTL = base::i18n::IsRTL(); - base::scoped_nsobject<NSImage> image( - [GetNSImageFromImageSkia(PageInfoUI::GetChosenObjectIcon( - *objectInfo, false, GetRelatedTextColor())) retain]); - - NSPoint position; - NSImageView* imageView; - NSButton* button; - NSTextField* label; - - CGFloat viewWidth = NSWidth([view frame]); - - if (isRTL) { - point.x = NSWidth([view frame]) - kPermissionImageSize - - kPermissionImageSpacing - kSectionHorizontalPadding; - imageView = [self addImageWithSize:[image size] toView:view atPoint:point]; - [imageView setImage:image]; - point.x -= kPermissionImageSpacing; - - label = [self addText:labelText - withSize:[NSFont systemFontSize] - bold:NO - toView:view - atPoint:point]; - [label sizeToFit]; - point.x -= NSWidth([label frame]); - [label setFrameOrigin:point]; - - position = NSMakePoint(point.x, point.y); - button = [self addDeleteButtonForChosenObject:std::move(objectInfo) - toView:view - atPoint:position]; - position.x -= NSWidth([button frame]); - [button setFrameOrigin:position]; - } else { - imageView = [self addImageWithSize:[image size] toView:view atPoint:point]; - [imageView setImage:image]; - point.x += kPermissionImageSize + kPermissionImageSpacing; - - label = [self addText:labelText - withSize:[NSFont systemFontSize] - bold:NO - toView:view - atPoint:point]; - [label sizeToFit]; - - position = NSMakePoint(NSMaxX([label frame]), point.y); - button = [self addDeleteButtonForChosenObject:std::move(objectInfo) - toView:view - atPoint:position]; - } - [imageView setTag:kChosenObjectTag]; - [label setTag:kChosenObjectTag]; - - [view setFrameSize:NSMakeSize(viewWidth, NSHeight([view frame]))]; - - // Adjust the vertical position of the button so that its title text is - // aligned with the label. Assumes that the text is the same size in both. - // Also adjust the horizontal position to remove excess space due to the - // invisible bezel. - NSRect titleRect = [[button cell] titleRectForBounds:[button bounds]]; - position.y -= titleRect.origin.y; - [button setFrameOrigin:position]; - - // Align the icon with the text. - [self alignPermissionIcon:imageView withTextField:label]; - - NSRect buttonFrame = [button frame]; - return NSMakePoint(NSMaxX(buttonFrame), NSMaxY(buttonFrame)); -} - -// Align an image with a text field by vertically centering the image on -// the cap height of the first line of text. -- (void)alignPermissionIcon:(NSImageView*)imageView - withTextField:(NSTextField*)textField { - NSRect frame = [imageView frame]; - frame.origin.y += kPermissionIconYAdjustment; - [imageView setFrame:frame]; -} - -- (void)setCookieInfo:(const CookieInfoList&)cookieInfoList { - // |cookieInfoList| should only ever have 2 items: first- and third-party - // cookies. - DCHECK_EQ(cookieInfoList.size(), 2u); - - int totalAllowed = 0; - for (const auto& i : cookieInfoList) { - totalAllowed += i.allowed; - } - - [cookiesView_ setLinkText:l10n_util::GetPluralNSStringF( - IDS_PAGE_INFO_NUM_COOKIES, totalAllowed)]; - [self performLayout]; -} - -- (void)setPermissionInfo:(const PermissionInfoList&)permissionInfoList - andChosenObjects:(ChosenObjectInfoList)chosenObjectInfoList { - NSPoint controlOrigin = NSMakePoint(kSectionHorizontalPadding, 0); - - // If |permissionsView_| is already populated, just handle updates to - // permissions made by the user here. This will avoid removing/adding new - // views (and thus breaking the responder chain), and also avoid immediately - // removing permissions set back to the default, which could be user error. - // Note that "update" means setPermissionInfo will only change the title of - // the permission |PermissionSelectorButton|. This is OK because it is not - // possible for the following to occur without closing the Page Info bubble: - // - a permission gets changed away from the factory default (and thus needs - // to be shown in Page Info) - // - a permission's source changes (and becomes disabled / needs to show a - // reason). - if ([permissionsView_ subviews].count != 0) { - NSView* view = nil; - // Remove all the chosen object views. They will be repopulated if the site - // still has access to them. - while ((view = [permissionsView_ viewWithTag:kChosenObjectTag])) - [view removeFromSuperview]; - - for (view in [permissionsView_ subviews]) { - // Skip views that don't need to be modified (default tags are -1 or 0). - if ([view tag] <= 0) - continue; - - ContentSettingsType permissionType = - static_cast<ContentSettingsType>([view tag]); - - PermissionSelectorButton* button = - base::mac::ObjCCastStrict<PermissionSelectorButton>(view); - const int yOrigin = [button frame].origin.y; - // Permissions set back to the factory default setting will disappear from - // |permissionInfoList|, so use |updated| to keep track of whether - // |button| has been updated with its new permission value yet. - bool updated = false; - for (const auto& permission : permissionInfoList) { - if (permissionType != permission.type) - continue; - - updated = true; - [button setButtonTitle:permission profile:[self profile]]; - break; - } - - if (!updated) { - // Permissions that are no longer in |permissionInfoList| have been set - // back to factory default settings. - PageInfoUI::PermissionInfo default_info; - default_info.type = permissionType; - default_info.setting = CONTENT_SETTING_DEFAULT; - default_info.default_setting = - content_settings::ContentSettingsRegistry::GetInstance() - ->Get(permissionType) - ->GetInitialDefaultSetting(); - default_info.source = content_settings::SETTING_SOURCE_USER; - default_info.is_incognito = [self profile]->IsOffTheRecord(); - [button setButtonTitle:default_info profile:[self profile]]; - } - - // Updating the text might have changed the width of the - // |PermissionSelectorRow|, so reposition here. - if (base::i18n::IsRTL()) { - [button setFrameOrigin:NSMakePoint(kSectionHorizontalPadding, yOrigin)]; - } else { - [button setFrameOrigin:NSMakePoint(NSWidth([permissionsView_ frame]) - - kSectionHorizontalPadding - - NSWidth([button frame]), - yOrigin)]; - } - } - if ([[permissionsView_ subviews] count] != 0) { - controlOrigin.y = - NSMaxY([[[permissionsView_ subviews] lastObject] frame]); - } - } else { - // Creates permissions views (if any) for the first time. - for (const auto& permission : permissionInfoList) { - controlOrigin.y += kPermissionsVerticalSpacing; - NSPoint rowBottomRight = [self addPermission:permission - toView:permissionsView_ - atPoint:controlOrigin]; - controlOrigin.y = rowBottomRight.y; - } - } - - for (auto& object : chosenObjectInfoList) { - controlOrigin.y += kPermissionsVerticalSpacing; - NSPoint rowBottomRight = [self addChosenObject:std::move(object) - toView:permissionsView_ - atPoint:controlOrigin]; - controlOrigin.y = rowBottomRight.y; - } - - // |permissionsView_| was updated here, so make sure keyboard access still - // works by updating the responder chain. - [[self window] recalculateKeyViewLoop]; - - [permissionsView_ setFrameSize:NSMakeSize(NSWidth([permissionsView_ frame]), - controlOrigin.y)]; - [self performLayout]; -} - -@end - -PageInfoUIBridge::PageInfoUIBridge(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents), - web_contents_(web_contents), - bubble_controller_(nil) { - DCHECK(!g_page_info_bubble); -} - -PageInfoUIBridge::~PageInfoUIBridge() { - DCHECK(g_page_info_bubble); - g_page_info_bubble = nullptr; -} - -void PageInfoUIBridge::set_bubble_controller( - PageInfoBubbleController* controller) { - bubble_controller_ = controller; - g_page_info_bubble = controller; -} - -void PageInfoUIBridge::SetIdentityInfo( - const PageInfoUI::IdentityInfo& identity_info) { - [bubble_controller_ setIdentityInfo:identity_info]; -} - -void PageInfoUIBridge::RenderFrameDeleted( - content::RenderFrameHost* render_frame_host) { - if (render_frame_host == web_contents_->GetMainFrame()) { - [bubble_controller_ close]; - } -} - -void PageInfoUIBridge::SetCookieInfo(const CookieInfoList& cookie_info_list) { - [bubble_controller_ setCookieInfo:cookie_info_list]; -} - -void PageInfoUIBridge::SetPermissionInfo( - const PermissionInfoList& permission_info_list, - ChosenObjectInfoList chosen_object_info_list) { - [bubble_controller_ setPermissionInfo:permission_info_list - andChosenObjects:std::move(chosen_object_info_list)]; -} - -void PageInfoUIBridge::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - if (!navigation_handle->IsInMainFrame() || - !navigation_handle->HasCommitted()) { - return; - } - // If the browser navigates to another page, close the bubble. - [bubble_controller_ close]; -} - -void ShowPageInfoDialogImpl(Browser* browser, - content::WebContents* web_contents, - const GURL& virtual_url, - const security_state::SecurityInfo& security_info, - bubble_anchor_util::Anchor anchor) { - if (chrome::ShowAllDialogsWithViewsToolkit()) { - chrome::ShowPageInfoBubbleViews(browser, web_contents, virtual_url, - security_info, anchor); - return; - } - - // Don't show the bubble if it's already being shown. Since this method is - // called each time the location icon is clicked, each click toggles the - // bubble in and out. - if (g_page_info_bubble) - return; - - // Create the bridge. This will be owned by the bubble controller. - PageInfoUIBridge* bridge = new PageInfoUIBridge(web_contents); - NSWindow* parent = browser->window()->GetNativeWindow(); - - // Create the bubble controller. It will dealloc itself when it closes, - // resetting |g_page_info_bubble|. - PageInfoBubbleController* bubble_controller = - [[PageInfoBubbleController alloc] initWithParentWindow:parent - pageInfoUIBridge:bridge - webContents:web_contents - url:virtual_url]; - - if (!IsInternalURL(virtual_url)) { - // Initialize the presenter, which holds the model and controls the UI. - // This is also owned by the bubble controller. - PageInfo* presenter = - new PageInfo(bridge, browser->profile(), - TabSpecificContentSettings::FromWebContents(web_contents), - web_contents, virtual_url, security_info); - [bubble_controller setPresenter:presenter]; - } - - [bubble_controller showWindow:nil]; -}
diff --git a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller_unittest.mm deleted file mode 100644 index ef88c91..0000000 --- a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller_unittest.mm +++ /dev/null
@@ -1,369 +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. - -#import "chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.h" - -#include <stddef.h> - -#include "base/i18n/rtl.h" -#include "base/macros.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/cocoa/browser_window_controller.h" -#include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" -#import "chrome/browser/ui/cocoa/location_bar/page_info_bubble_decoration.h" -#import "chrome/browser/ui/cocoa/test/cocoa_profile_test.h" -#include "content/public/test/test_web_contents_factory.h" -#include "net/test/test_certificate_data.h" -#include "testing/gtest_mac.h" - -@interface PageInfoBubbleController (ExposedForTesting) -- (NSView*)permissionsView; -- (NSButton*)resetDecisionsButton; -- (NSButton*)connectionHelpButton; -@end - -@implementation PageInfoBubbleController (ExposedForTesting) -- (NSView*)permissionsView { - return permissionsView_; -} -- (NSButton*)resetDecisionsButton { - return resetDecisionsButton_; -} -- (NSButton*)connectionHelpButton { - return connectionHelpButton_; -} -- (NSButton*)changePasswordButton { - return changePasswordButton_; -} -- (NSButton*)whitelistPasswordReuseButton { - return whitelistPasswordReuseButton_; -} -@end - -@interface PageInfoBubbleControllerForTesting : PageInfoBubbleController { - @private - CGFloat defaultWindowWidth_; -} -@end - -@implementation PageInfoBubbleControllerForTesting -- (void)setDefaultWindowWidth:(CGFloat)width { - defaultWindowWidth_ = width; -} -- (CGFloat)defaultWindowWidth { - // If |defaultWindowWidth_| is 0, use the superclass implementation. - return defaultWindowWidth_ ? defaultWindowWidth_ : [super defaultWindowWidth]; -} -@end - -namespace { - -// Indices of the menu items in the permission menu. -enum PermissionMenuIndices { - kMenuIndexContentSettingAllow = 0, - kMenuIndexContentSettingBlock, - kMenuIndexContentSettingDefault -}; - -const ContentSettingsType kTestPermissionTypes[] = { - CONTENT_SETTINGS_TYPE_IMAGES, - CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, - CONTENT_SETTINGS_TYPE_JAVASCRIPT, - CONTENT_SETTINGS_TYPE_PLUGINS, - CONTENT_SETTINGS_TYPE_POPUPS, - CONTENT_SETTINGS_TYPE_GEOLOCATION, - CONTENT_SETTINGS_TYPE_NOTIFICATIONS, - CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC}; - -const ContentSetting kTestSettings[] = { - CONTENT_SETTING_DEFAULT, CONTENT_SETTING_DEFAULT, CONTENT_SETTING_DEFAULT, - CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW, - CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK}; - -const ContentSetting kTestDefaultSettings[] = { - CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, CONTENT_SETTING_ASK}; - -const content_settings::SettingSource kTestSettingSources[] = { - content_settings::SETTING_SOURCE_USER, - content_settings::SETTING_SOURCE_USER, - content_settings::SETTING_SOURCE_USER, - content_settings::SETTING_SOURCE_USER, - content_settings::SETTING_SOURCE_USER, - content_settings::SETTING_SOURCE_POLICY, - content_settings::SETTING_SOURCE_POLICY, - content_settings::SETTING_SOURCE_EXTENSION}; - -class PageInfoBubbleControllerTest : public CocoaProfileTest { - public: - PageInfoBubbleControllerTest() { controller_ = nil; } - - void TearDown() override { - [controller_ close]; - CocoaProfileTest::TearDown(); - } - - protected: - PageInfoUIBridge* bridge_; // Weak, owned by controller. - - enum MatchType { TEXT_EQUAL = 0, TEXT_NOT_EQUAL }; - - // Creates a new page info bubble, with the given default width. - // If |default_width| is 0, the *default* default width will be used. - void CreateBubbleWithWidth(CGFloat default_width) { - bridge_ = new PageInfoUIBridge(nullptr); - - // The controller cleans up after itself when the window closes. - controller_ = [PageInfoBubbleControllerForTesting alloc]; - [controller_ setDefaultWindowWidth:default_width]; - [controller_ initWithParentWindow:browser()->window()->GetNativeWindow() - pageInfoUIBridge:bridge_ - webContents:web_contents_factory_.CreateWebContents( - browser()->profile()) - url:GURL("https://www.google.com")]; - window_ = [controller_ window]; - [controller_ showWindow:nil]; - } - - void CreateBubble() { CreateBubbleWithWidth(0.0); } - - // Return a pointer to the first NSTextField found that either matches, or - // doesn't match, the given text. - NSTextField* FindTextField(MatchType match_type, NSString* text) { - // The window's only immediate child is an invisible view that has a flipped - // coordinate origin. It is into this that all views get placed. - NSArray* window_subviews = [[window_ contentView] subviews]; - EXPECT_EQ(1U, [window_subviews count]); - NSArray* bubble_subviews = [[window_subviews lastObject] subviews]; - NSArray* security_section_subviews = - [[bubble_subviews firstObject] subviews]; - - /** - *Expect 3 views: - * - the identity - * - identity status - * - security details link - */ - EXPECT_EQ(3U, [security_section_subviews count]); - - bool desired_result = match_type == TEXT_EQUAL; - for (NSView* view in security_section_subviews) { - if ([view isKindOfClass:[NSTextField class]]) { - NSTextField* text_field = static_cast<NSTextField*>(view); - if ([[text_field stringValue] isEqual:text] == desired_result) - return text_field; - } - } - return nil; - } - - NSMutableArray* FindAllSubviewsOfClass(NSView* parent_view, Class a_class) { - NSMutableArray* views = [NSMutableArray array]; - for (NSView* view in [parent_view subviews]) { - if ([view isKindOfClass:a_class]) - [views addObject:view]; - } - return views; - } - - // Sets up the dialog with some test permission settings. - void SetTestPermissions() { - // Create a list of 5 different permissions, corresponding to all the - // possible settings: - // - [allow, block, ask] by default - // - [block, allow] * by user - PermissionInfoList permission_info_list; - PageInfoUI::PermissionInfo info; - for (size_t i = 0; i < arraysize(kTestPermissionTypes); ++i) { - info.type = kTestPermissionTypes[i]; - info.setting = kTestSettings[i]; - if (info.setting == CONTENT_SETTING_DEFAULT) - info.default_setting = kTestDefaultSettings[i]; - info.source = kTestSettingSources[i]; - info.is_incognito = false; - permission_info_list.push_back(info); - } - ChosenObjectInfoList chosen_object_info_list; - bridge_->SetPermissionInfo(permission_info_list, - std::move(chosen_object_info_list)); - } - - int NumSettingsNotSetByUser() const { - int num_non_user_settings = 0; - for (size_t i = 0; i < arraysize(kTestSettingSources); ++i) { - num_non_user_settings += - (kTestSettingSources[i] != content_settings::SETTING_SOURCE_USER) ? 1 - : 0; - } - return num_non_user_settings; - } - - content::TestWebContentsFactory web_contents_factory_; - - PageInfoBubbleControllerForTesting* controller_; // Weak, owns self. - NSWindow* window_; // Weak, owned by controller. -}; - -TEST_F(PageInfoBubbleControllerTest, ConnectionHelpButton) { - PageInfoUI::IdentityInfo info; - info.site_identity = std::string("example.com"); - info.identity_status = PageInfo::SITE_IDENTITY_STATUS_UNKNOWN; - - CreateBubble(); - - bridge_->SetIdentityInfo(const_cast<PageInfoUI::IdentityInfo&>(info)); - - EXPECT_EQ([[controller_ connectionHelpButton] action], - @selector(openConnectionHelp:)); -} - -TEST_F(PageInfoBubbleControllerTest, ResetDecisionsButton) { - PageInfoUI::IdentityInfo info; - info.site_identity = std::string("example.com"); - info.identity_status = PageInfo::SITE_IDENTITY_STATUS_UNKNOWN; - - CreateBubble(); - - // Set identity info, specifying that the button should not be shown. - info.show_ssl_decision_revoke_button = false; - bridge_->SetIdentityInfo(const_cast<PageInfoUI::IdentityInfo&>(info)); - EXPECT_EQ([controller_ resetDecisionsButton], nil); - - // Set identity info, specifying that the button should be shown. - info.certificate = net::X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der)); - ASSERT_TRUE(info.certificate); - info.show_ssl_decision_revoke_button = true; - bridge_->SetIdentityInfo(const_cast<PageInfoUI::IdentityInfo&>(info)); - EXPECT_NE([controller_ resetDecisionsButton], nil); - - // Check that clicking the button calls the right selector. - EXPECT_EQ([[controller_ resetDecisionsButton] action], - @selector(resetCertificateDecisions:)); - - // Since the bubble is only created once per identity, we only need to check - // the button is *added* when needed. So we don't check that it's removed - // when we set an identity with `show_ssl_decision_revoke_button == false` - // again. -} - -TEST_F(PageInfoBubbleControllerTest, SetPermissionInfo) { - CreateBubble(); - SetTestPermissions(); - - // There should be three subviews per permission. - NSArray* subviews = [[controller_ permissionsView] subviews]; - EXPECT_EQ(arraysize(kTestPermissionTypes) * 3, - [subviews count] - NumSettingsNotSetByUser()); - - // Ensure that there is a label for each permission. - NSMutableArray* permission_labels = [NSMutableArray array]; - for (NSView* view in subviews) { - if ([view isKindOfClass:[NSTextField class]]) - [permission_labels - addObject:[static_cast<NSTextField*>(view) stringValue]]; - } - EXPECT_EQ(arraysize(kTestPermissionTypes), - [permission_labels count] - NumSettingsNotSetByUser()); - - // Ensure that the button labels are distinct, and look for the correct - // number of disabled buttons. - int disabled_count = 0; - NSMutableSet* button_labels = [NSMutableSet set]; - for (NSView* view in subviews) { - if ([view isKindOfClass:[NSPopUpButton class]]) { - NSPopUpButton* button = static_cast<NSPopUpButton*>(view); - [button_labels addObject:[[button selectedCell] title]]; - - if (![button isEnabled]) - ++disabled_count; - } - } - EXPECT_EQ(5UL, [button_labels count]); - - // Permissions with a setting source of SETTING_SOURCE_POLICY or - // SETTING_SOURCE_EXTENSION should have their buttons disabled. - EXPECT_EQ(NumSettingsNotSetByUser(), disabled_count); -} - -TEST_F(PageInfoBubbleControllerTest, WindowWidth) { - const CGFloat kBigEnoughBubbleWidth = 310; - // Creating a window that should fit everything. - CreateBubbleWithWidth(kBigEnoughBubbleWidth); - SetTestPermissions(); - - CGFloat window_width = NSWidth([[controller_ window] frame]); - - // Check the window was made bigger to fit the content. - EXPECT_EQ(kBigEnoughBubbleWidth, window_width); - - // Check that the window is wider than the right edge of all the permission - // popup buttons (LTR locales) or wider than the left edge (RTL locales). - bool is_rtl = base::i18n::IsRTL(); - for (NSView* view in [[controller_ permissionsView] subviews]) { - if (is_rtl) { - if ([view isKindOfClass:[NSPopUpButton class]]) { - NSPopUpButton* button = static_cast<NSPopUpButton*>(view); - EXPECT_GT(NSMinX([button frame]), 0); - } - if ([view isKindOfClass:[NSImageView class]]) { - NSImageView* icon = static_cast<NSImageView*>(view); - EXPECT_LT(NSMaxX([icon frame]), window_width); - } - } else { - if ([view isKindOfClass:[NSImageView class]]) { - NSImageView* icon = static_cast<NSImageView*>(view); - EXPECT_GT(NSMinX([icon frame]), 0); - } - if ([view isKindOfClass:[NSPopUpButton class]]) { - NSPopUpButton* button = static_cast<NSPopUpButton*>(view); - EXPECT_LT(NSMaxX([button frame]), window_width); - } - } - } -} - -// Tests the page icon decoration's active state. -TEST_F(PageInfoBubbleControllerTest, PageIconDecorationActiveState) { - NSWindow* window = browser()->window()->GetNativeWindow(); - BrowserWindowController* controller = - [BrowserWindowController browserWindowControllerForWindow:window]; - LocationBarDecoration* decoration = - [controller locationBarBridge]->page_info_decoration(); - - CreateBubble(); - EXPECT_TRUE([[controller_ window] isVisible]); - EXPECT_TRUE(decoration->active()); - - [controller_ close]; - EXPECT_FALSE(decoration->active()); -} - -TEST_F(PageInfoBubbleControllerTest, PasswordReuseButtons) { - PageInfoUI::IdentityInfo info; - info.site_identity = std::string("example.com"); - info.identity_status = PageInfo::SITE_IDENTITY_STATUS_UNKNOWN; - - CreateBubble(); - - // Set identity info, specifying that buttons should not be shown. - info.show_change_password_buttons = false; - bridge_->SetIdentityInfo(const_cast<PageInfoUI::IdentityInfo&>(info)); - EXPECT_EQ([controller_ changePasswordButton], nil); - EXPECT_EQ([controller_ whitelistPasswordReuseButton], nil); - - // Set identity info, specifying that buttons should be shown. - info.show_change_password_buttons = true; - bridge_->SetIdentityInfo(const_cast<PageInfoUI::IdentityInfo&>(info)); - EXPECT_NE([controller_ changePasswordButton], nil); - EXPECT_NE([controller_ whitelistPasswordReuseButton], nil); - - // Check that clicking the button calls the right selector. - EXPECT_EQ([[controller_ changePasswordButton] action], - @selector(changePasswordDecisions:)); - EXPECT_EQ([[controller_ whitelistPasswordReuseButton] action], - @selector(whitelistPasswordReuseDecisions:)); -} - -} // namespace
diff --git a/chrome/browser/ui/cocoa/page_info/page_info_bubble_views_mac_browsertest.mm b/chrome/browser/ui/cocoa/page_info/page_info_bubble_views_mac_browsertest.mm index 83921dac..212a2ae 100644 --- a/chrome/browser/ui/cocoa/page_info/page_info_bubble_views_mac_browsertest.mm +++ b/chrome/browser/ui/cocoa/page_info/page_info_bubble_views_mac_browsertest.mm
@@ -66,19 +66,13 @@ access_manager->fullscreen_controller(); fullscreen_controller->ToggleBrowserFullscreenMode(); - if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { - views::BubbleDialogDelegateView* page_info = - PageInfoBubbleView::GetPageInfoBubble(); - EXPECT_TRUE(page_info); - views::Widget* page_info_bubble = page_info->GetWidget(); - EXPECT_TRUE(page_info_bubble); - EXPECT_EQ(GetParam().bubble_type, PageInfoBubbleView::GetShownBubbleType()); - EXPECT_TRUE(page_info_bubble->IsVisible()); - } else { - EXPECT_TRUE([PageInfoBubbleController getPageInfoBubbleForTest]); - // In Cocoa, the crash occurs when the bubble tries to re-layout. - [[PageInfoBubbleController getPageInfoBubbleForTest] performLayout]; - } + views::BubbleDialogDelegateView* page_info = + PageInfoBubbleView::GetPageInfoBubble(); + EXPECT_TRUE(page_info); + views::Widget* page_info_bubble = page_info->GetWidget(); + EXPECT_TRUE(page_info_bubble); + EXPECT_EQ(GetParam().bubble_type, PageInfoBubbleView::GetShownBubbleType()); + EXPECT_TRUE(page_info_bubble->IsVisible()); // There should be no crash here from re-anchoring the Page Info bubble while // transitioning into full screen.
diff --git a/chrome/browser/ui/cocoa/page_info/page_info_utils_cocoa.h b/chrome/browser/ui/cocoa/page_info/page_info_utils_cocoa.h deleted file mode 100644 index 4b09b80..0000000 --- a/chrome/browser/ui/cocoa/page_info/page_info_utils_cocoa.h +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_COCOA_PAGE_INFO_PAGE_INFO_UTILS_COCOA_H_ -#define CHROME_BROWSER_UI_COCOA_PAGE_INFO_PAGE_INFO_UTILS_COCOA_H_ - -#import <Cocoa/Cocoa.h> - -NSSize SizeForPageInfoButtonTitle(NSPopUpButton* button, NSString* title); - -#endif // CHROME_BROWSER_UI_COCOA_PAGE_INFO_PAGE_INFO_UTILS_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/page_info/page_info_utils_cocoa.mm b/chrome/browser/ui/cocoa/page_info/page_info_utils_cocoa.mm deleted file mode 100644 index 1dbf9567..0000000 --- a/chrome/browser/ui/cocoa/page_info/page_info_utils_cocoa.mm +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/cocoa/page_info/page_info_utils_cocoa.h" - -namespace { -// The amount of horizontal space between the button's title and its arrow icon. -const CGFloat kButtonTitleRightPadding = 4.0f; -} - -// Determine the size of a popup button with the given title. -NSSize SizeForPageInfoButtonTitle(NSPopUpButton* button, NSString* title) { - NSDictionary* textAttributes = - [[button attributedTitle] attributesAtIndex:0 effectiveRange:NULL]; - NSSize titleSize = [title sizeWithAttributes:textAttributes]; - - NSRect frame = [button frame]; - NSRect titleRect = [[button cell] titleRectForBounds:frame]; - CGFloat width = titleSize.width + NSWidth(frame) - NSWidth(titleRect); - - return NSMakeSize(width + kButtonTitleRightPadding, NSHeight(frame)); -}
diff --git a/chrome/browser/ui/cocoa/page_info/permission_selector_button.h b/chrome/browser/ui/cocoa/page_info/permission_selector_button.h deleted file mode 100644 index a613e0a..0000000 --- a/chrome/browser/ui/cocoa/page_info/permission_selector_button.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_COCOA_PAGE_INFO_PERMISSION_SELECTOR_BUTTON_H_ -#define CHROME_BROWSER_UI_COCOA_PAGE_INFO_PERMISSION_SELECTOR_BUTTON_H_ - -#import <Cocoa/Cocoa.h> - -#include <memory> - -#include "base/mac/scoped_nsobject.h" -#include "chrome/browser/ui/page_info/permission_menu_model.h" -#include "components/content_settings/core/common/content_settings.h" - -@class MenuControllerCocoa; - -class Profile; - -@interface PermissionSelectorButton : NSPopUpButton { - @private - std::unique_ptr<PermissionMenuModel> menuModel_; - base::scoped_nsobject<MenuControllerCocoa> menuController_; -} - -// Designated initializer. -- (id)initWithPermissionInfo:(const PageInfoUI::PermissionInfo&)permissionInfo - forURL:(const GURL&)url - withCallback:(PermissionMenuModel::ChangeCallback)callback - profile:(Profile*)profile; - -// Returns the largest possible size given all of the items in the menu. -- (CGFloat)maxTitleWidthForContentSettingsType:(ContentSettingsType)type - withDefaultSetting:(ContentSetting)defaultSetting - profile:(Profile*)profile; - -// Updates the title of the NSPopUpButton and resizes it to fit the new text. -- (void)setButtonTitle:(const PageInfoUI::PermissionInfo&)permissionInfo - profile:(Profile*)profile; - -@end - -#endif // CHROME_BROWSER_UI_COCOA_PAGE_INFO_PERMISSION_SELECTOR_BUTTON_H_
diff --git a/chrome/browser/ui/cocoa/page_info/permission_selector_button.mm b/chrome/browser/ui/cocoa/page_info/permission_selector_button.mm deleted file mode 100644 index 0ec3193..0000000 --- a/chrome/browser/ui/cocoa/page_info/permission_selector_button.mm +++ /dev/null
@@ -1,81 +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. - -#import "chrome/browser/ui/cocoa/page_info/permission_selector_button.h" - -#include "base/strings/sys_string_conversions.h" -#include "chrome/browser/ui/cocoa/page_info/page_info_utils_cocoa.h" -#include "chrome/browser/ui/page_info/page_info_ui.h" -#import "ui/base/cocoa/menu_controller.h" - -@implementation PermissionSelectorButton - -- (id)initWithPermissionInfo:(const PageInfoUI::PermissionInfo&)permissionInfo - forURL:(const GURL&)url - withCallback:(PermissionMenuModel::ChangeCallback)callback - profile:(Profile*)profile { - if (self = [super initWithFrame:NSMakeRect(0, 0, 1, 1) pullsDown:NO]) { - [self setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [self setBordered:NO]; - [[self cell] setControlSize:NSSmallControlSize]; - - menuModel_.reset( - new PermissionMenuModel(profile, url, permissionInfo, callback)); - - menuController_.reset([[MenuControllerCocoa alloc] - initWithModel:menuModel_.get() - useWithPopUpButtonCell:NO]); - [self setMenu:[menuController_ menu]]; - [self selectItemWithTag:permissionInfo.setting]; - - [self setButtonTitle:permissionInfo profile:profile]; - - NSString* description = base::SysUTF16ToNSString( - PageInfoUI::PermissionTypeToUIString(permissionInfo.type)); - [[self cell] - accessibilitySetOverrideValue:description - forAttribute:NSAccessibilityDescriptionAttribute]; - } - return self; -} - -- (CGFloat)maxTitleWidthForContentSettingsType:(ContentSettingsType)type - withDefaultSetting:(ContentSetting)defaultSetting - profile:(Profile*)profile { - // Determine the largest possible size for this button. - CGFloat maxTitleWidth = 0; - for (NSMenuItem* item in [self itemArray]) { - NSString* title = - base::SysUTF16ToNSString(PageInfoUI::PermissionActionToUIString( - profile, type, static_cast<ContentSetting>([item tag]), - defaultSetting, content_settings::SETTING_SOURCE_USER)); - NSSize size = SizeForPageInfoButtonTitle(self, title); - maxTitleWidth = std::max(maxTitleWidth, size.width); - } - return maxTitleWidth; -} - -// Accessor function for testing only. -- (NSMenu*)permissionMenu { - return [menuController_ menu]; -} - -- (void)setButtonTitle:(const PageInfoUI::PermissionInfo&)permissionInfo - profile:(Profile*)profile { - // Set the button title. - base::scoped_nsobject<NSMenuItem> titleItem([[NSMenuItem alloc] init]); - base::string16 buttonTitle = PageInfoUI::PermissionActionToUIString( - profile, permissionInfo.type, permissionInfo.setting, - permissionInfo.default_setting, permissionInfo.source); - [titleItem setTitle:base::SysUTF16ToNSString(buttonTitle)]; - [[self cell] setUsesItemFromMenu:NO]; - [[self cell] setMenuItem:titleItem]; - // Although the frame is reset, below, this sizes the cell properly. - [self sizeToFit]; - - // Size the button to just fit the visible title - not all of its items. - [self setFrameSize:SizeForPageInfoButtonTitle(self, [self title])]; -} - -@end
diff --git a/chrome/browser/ui/cocoa/page_info/permission_selector_button_unittest.mm b/chrome/browser/ui/cocoa/page_info/permission_selector_button_unittest.mm deleted file mode 100644 index 63188c3..0000000 --- a/chrome/browser/ui/cocoa/page_info/permission_selector_button_unittest.mm +++ /dev/null
@@ -1,74 +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. - -#import "chrome/browser/ui/cocoa/page_info/permission_selector_button.h" - -#include "base/mac/scoped_nsobject.h" -#include "base/test/scoped_feature_list.h" -#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" -#include "chrome/browser/ui/page_info/page_info_ui.h" -#include "chrome/test/base/testing_profile.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "ui/base/ui_base_features.h" - -@interface PermissionSelectorButton (Testing) -- (NSMenu*)permissionMenu; -@end - -namespace { - -const ContentSettingsType kTestPermissionType = - CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC; - -class PermissionSelectorButtonTest : public CocoaTest { - public: - PermissionSelectorButtonTest() { - // This file only tests Cocoa UI and can be deleted when kSecondaryUiMd is - // default. - scoped_feature_list_.InitAndDisableFeature(features::kSecondaryUiMd); - - got_callback_ = false; - PageInfoUI::PermissionInfo test_info; - test_info.type = kTestPermissionType; - test_info.setting = CONTENT_SETTING_BLOCK; - test_info.source = content_settings::SETTING_SOURCE_USER; - test_info.is_incognito = false; - GURL test_url("http://www.google.com"); - PermissionMenuModel::ChangeCallback callback = base::Bind( - &PermissionSelectorButtonTest::Callback, base::Unretained(this)); - view_.reset([[PermissionSelectorButton alloc] - initWithPermissionInfo:test_info - forURL:test_url - withCallback:callback - profile:&profile_]); - [[test_window() contentView] addSubview:view_]; - } - - void Callback(const PageInfoUI::PermissionInfo& permission) { - EXPECT_TRUE(permission.type == kTestPermissionType); - got_callback_ = true; - } - - content::TestBrowserThreadBundle thread_bundle_; - TestingProfile profile_; - - bool got_callback_; - base::scoped_nsobject<PermissionSelectorButton> view_; - - private: - base::test::ScopedFeatureList scoped_feature_list_; - - DISALLOW_COPY_AND_ASSIGN(PermissionSelectorButtonTest); -}; - -TEST_VIEW(PermissionSelectorButtonTest, view_); - -TEST_F(PermissionSelectorButtonTest, Callback) { - NSMenu* menu = [view_ permissionMenu]; - NSMenuItem* item = [menu itemAtIndex:0]; - [[item target] performSelector:[item action] withObject:item]; - EXPECT_TRUE(got_callback_); -} - -} // namespace
diff --git a/chrome/browser/ui/cocoa/page_info/split_block_button.h b/chrome/browser/ui/cocoa/page_info/split_block_button.h deleted file mode 100644 index 689ae1a..0000000 --- a/chrome/browser/ui/cocoa/page_info/split_block_button.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_COCOA_PAGE_INFO_SPLIT_BLOCK_BUTTON_H_ -#define CHROME_BROWSER_UI_COCOA_PAGE_INFO_SPLIT_BLOCK_BUTTON_H_ - -#import <Cocoa/Cocoa.h> - -#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" -#include "ui/base/models/simple_menu_model.h" - -@class SplitButtonPopUpCell; -@class SplitButtonTitleCell; - -// Block ('deny') button for the permissions bubble. Subclassed from -// ConstrainedWindowButton, so that it shares styling, but contains two cells -// instead of just one. The left cell behaves as a normal button, and when -// clicked, calls the button's |action| on its |target|. The right cell behaves -// as a NSPopUpButtonCell, and implements a single-item menu. -@interface SplitBlockButton : ConstrainedWindowButton { - @private - base::scoped_nsobject<SplitButtonTitleCell> leftCell_; - base::scoped_nsobject<SplitButtonPopUpCell> rightCell_; - - ui::ScopedCrTrackingArea leftTrackingArea_; - ui::ScopedCrTrackingArea rightTrackingArea_; -} - -// Designated initializer. -- (id)initWithMenuDelegate:(ui::SimpleMenuModel::Delegate*)menuDelegate; - -@end - -#endif // CHROME_BROWSER_UI_COCOA_PAGE_INFO_SPLIT_BLOCK_BUTTON_H_
diff --git a/chrome/browser/ui/cocoa/page_info/split_block_button.mm b/chrome/browser/ui/cocoa/page_info/split_block_button.mm deleted file mode 100644 index de71ab0..0000000 --- a/chrome/browser/ui/cocoa/page_info/split_block_button.mm +++ /dev/null
@@ -1,339 +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. - -#import "chrome/browser/ui/cocoa/page_info/split_block_button.h" - -#include <cmath> - -#include "base/logging.h" -#include "base/mac/scoped_nsobject.h" -#include "chrome/grit/generated_resources.h" -#include "skia/ext/skia_utils_mac.h" -#import "ui/base/cocoa/menu_controller.h" -#include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/models/simple_menu_model.h" - -namespace { - -enum MouseLocation { - kInsideLeftCell, - kInsideRightCell, - kNotInside, -}; - -enum CornerType { - kRounded, - kAngled, -}; - -NSBezierPath* PathWithCornerStyles(NSRect frame, - CornerType leftCornerStyle, - CornerType rightCornerStyle) { - base::scoped_nsobject<NSBezierPath> path([[NSBezierPath bezierPath] retain]); - const CGFloat x0 = NSMinX(frame); - const CGFloat x1 = NSMaxX(frame); - const CGFloat y0 = NSMinY(frame); - const CGFloat y1 = NSMaxY(frame); - const CGFloat radius = 2; - - // Start at the center bottom. Draw left and up, including both left corners. - [path moveToPoint:NSMakePoint(std::floor((x1 - x0) * .5), y0)]; - if (leftCornerStyle == kAngled) { - [path lineToPoint:NSMakePoint(x0, y0)]; - [path lineToPoint:NSMakePoint(x0, y1)]; - } else { - [path appendBezierPathWithArcFromPoint:NSMakePoint(x0, y0) - toPoint:NSMakePoint(x0, y0 + radius) - radius:radius]; - [path appendBezierPathWithArcFromPoint:NSMakePoint(x0, y1) - toPoint:NSMakePoint(x0 + radius, y1) - radius:radius]; - } - // Draw through the upper right-hand and lower-right-hand corners. - if (rightCornerStyle == kAngled) { - [path lineToPoint:NSMakePoint(x1, y1)]; - [path lineToPoint:NSMakePoint(x1, y0)]; - } else { - [path appendBezierPathWithArcFromPoint:NSMakePoint(x1, y1) - toPoint:NSMakePoint(x1, y1 - radius) - radius:radius]; - [path appendBezierPathWithArcFromPoint:NSMakePoint(x1, y0) - toPoint:NSMakePoint(x1 - radius, y0) - radius:radius]; - } - return path.autorelease(); -} - -void DrawBezel(id<ConstrainedWindowButtonDrawableCell> cell, - CornerType leftCorners, - CornerType rightCorners, - NSRect frame, - NSView* view) { - if ([cell isMouseInside]) { - base::scoped_nsobject<NSBezierPath> path( - [PathWithCornerStyles(frame, leftCorners, rightCorners) retain]); - [ConstrainedWindowButton DrawBackgroundAndShadowForPath:path - withCell:cell - inView:view]; - [ConstrainedWindowButton DrawInnerHighlightForPath:path - withCell:cell - inView:view]; - } -} - -} // namespace - -// A button cell used by SplitBlockButton, containing the title. -@interface SplitButtonTitleCell : ConstrainedWindowButtonCell -- (NSRect)rect; -@end - -// A button cell used by SplitBlockButton, containing the popup menu. -@interface SplitButtonPopUpCell - : NSPopUpButtonCell<ConstrainedWindowButtonDrawableCell> { - @private - BOOL isMouseInside_; - base::scoped_nsobject<MenuControllerCocoa> menuController_; - std::unique_ptr<ui::SimpleMenuModel> menuModel_; -} - -// Designated initializer. -- (id)initWithMenuDelegate:(ui::SimpleMenuModel::Delegate*)menuDelegate; - -- (NSRect)rect; - -@end - -@implementation SplitBlockButton - -- (id)initWithMenuDelegate:(ui::SimpleMenuModel::Delegate*)menuDelegate { - if (self = [super initWithFrame:NSZeroRect]) { - leftCell_.reset([[SplitButtonTitleCell alloc] init]); - rightCell_.reset( - [[SplitButtonPopUpCell alloc] initWithMenuDelegate:menuDelegate]); - [leftCell_ setTitle:l10n_util::GetNSString(IDS_PERMISSION_DENY)]; - [leftCell_ setEnabled:YES]; - [rightCell_ setEnabled:YES]; - } - return self; -} - -+ (Class)cellClass { - return nil; -} - -- (NSString*)title { - return [leftCell_ title]; -} - -- (void)setAction:(SEL)action { - [leftCell_ setAction:action]; -} - -- (void)setTarget:(id)target { - [leftCell_ setTarget:target]; -} - -- (void)drawRect:(NSRect)rect { - // Copy the base class: inset to leave room for the shadow. - --rect.size.height; - - // This function assumes that |rect| is always the same as [self frame]. - // If that changes, the drawing functions will need to be adjusted. - const CGFloat radius = 2; - NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:rect - xRadius:radius - yRadius:radius]; - [ConstrainedWindowButton DrawBackgroundAndShadowForPath:path - withCell:nil - inView:self]; - - // Use intersection rects for the cell drawing, to ensure the height - // adjustment is honored. - [leftCell_ setControlView:self]; - [leftCell_ drawWithFrame:NSIntersectionRect(rect, [self leftCellRect]) - inView:self]; - - [rightCell_ setControlView:self]; - [rightCell_ drawWithFrame:NSIntersectionRect(rect, [self rightCellRect]) - inView:self]; - - // Draw the border. - path = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(rect, 0.5, 0.5) - xRadius:radius - yRadius:radius]; - [ConstrainedWindowButton DrawBorderForPath:path withCell:nil inView:self]; -} - -- (void)updateTrackingAreas { - [self updateTrackingArea:&leftTrackingArea_ - forCell:leftCell_ - withRect:[self leftCellRect]]; - - [self updateTrackingArea:&rightTrackingArea_ - forCell:rightCell_ - withRect:[self rightCellRect]]; -} - -- (void)updateTrackingArea:(ui::ScopedCrTrackingArea*)trackingArea - forCell:(id<ConstrainedWindowButtonDrawableCell>)cell - withRect:(NSRect)rect { - DCHECK(trackingArea); - NSTrackingAreaOptions options = - NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp; - [self removeTrackingArea:trackingArea->get()]; - trackingArea->reset([[CrTrackingArea alloc] initWithRect:rect - options:options - owner:self - userInfo:nil]); - [self addTrackingArea:trackingArea->get()]; -} - -- (void)mouseEntered:(NSEvent*)theEvent { - [self mouseMoved:theEvent]; -} - -- (void)mouseExited:(NSEvent*)theEvent { - [self mouseMoved:theEvent]; -} - -- (void)mouseMoved:(NSEvent*)theEvent { - MouseLocation location = [self mouseLocationForEvent:theEvent]; - [rightCell_ setIsMouseInside:NO]; - [leftCell_ setIsMouseInside:NO]; - if (location == kInsideLeftCell) - [leftCell_ setIsMouseInside:YES]; - else if (location == kInsideRightCell) - [rightCell_ setIsMouseInside:YES]; - [self setNeedsDisplay:YES]; -} - -- (void)mouseDown:(NSEvent*)theEvent { - MouseLocation downLocation = [self mouseLocationForEvent:theEvent]; - NSCell* focusCell = nil; - NSRect rect; - if (downLocation == kInsideLeftCell) { - focusCell = leftCell_.get(); - rect = [self leftCellRect]; - } else if (downLocation == kInsideRightCell) { - focusCell = rightCell_.get(); - rect = [self rightCellRect]; - } - - do { - MouseLocation location = [self mouseLocationForEvent:theEvent]; - if (location != kNotInside) { - [focusCell setHighlighted:YES]; - [self setNeedsDisplay:YES]; - - if ([focusCell trackMouse:theEvent - inRect:rect - ofView:self - untilMouseUp:NO]) { - [focusCell setState:![focusCell state]]; - [self setNeedsDisplay:YES]; - break; - } else { - // The above -trackMouse call returned NO, so we know that - // the mouse left the cell before a mouse up event occurred. - [focusCell setHighlighted:NO]; - [self setNeedsDisplay:YES]; - } - } - const NSUInteger mask = NSLeftMouseUpMask | NSLeftMouseDraggedMask; - theEvent = [[self window] nextEventMatchingMask:mask]; - } while ([theEvent type] != NSLeftMouseUp); -} - -- (MouseLocation)mouseLocationForEvent:(NSEvent*)theEvent { - MouseLocation location = kNotInside; - NSPoint mousePoint = - [self convertPoint:[theEvent locationInWindow] fromView:nil]; - if ([self mouse:mousePoint inRect:[leftCell_ rect]]) - location = kInsideLeftCell; - else if ([self mouse:mousePoint inRect:[self rightCellRect]]) - location = kInsideRightCell; - return location; -} - -- (void)sizeToFit { - NSSize leftSize = [leftCell_ cellSize]; - NSSize rightSize = [rightCell_ cellSize]; - NSSize size = NSMakeSize( - std::ceil(std::max(leftSize.width + rightSize.width, - constrained_window_button::kButtonMinWidth)), - std::ceil(std::max(leftSize.height, rightSize.height))); - [self setFrameSize:size]; -} - -- (NSRect)leftCellRect { - return [leftCell_ rect]; -} - -- (NSRect)rightCellRect { - NSRect leftFrame, rightFrame; - NSDivideRect([self bounds], &leftFrame, &rightFrame, - NSWidth([self leftCellRect]), NSMinXEdge); - return rightFrame; -} - -// Accessor for Testing. -- (NSMenu*)menu { - return [rightCell_ menu]; -} - -@end - -@implementation SplitButtonTitleCell - -- (void)drawBezelWithFrame:(NSRect)frame inView:(NSView*)controlView { - DrawBezel(self, kRounded, kAngled, frame, controlView); -} - -- (NSRect)rect { - NSSize size = [self cellSize]; - return NSMakeRect(0, 0, std::ceil(size.width), std::ceil(size.height)); -} - -@end - -@implementation SplitButtonPopUpCell - -@synthesize isMouseInside = isMouseInside_; - -- (id)initWithMenuDelegate:(ui::SimpleMenuModel::Delegate*)menuDelegate { - if (self = [super initTextCell:@"" pullsDown:YES]) { - [self setControlSize:NSSmallControlSize]; - [self setArrowPosition:NSPopUpArrowAtCenter]; - [self setBordered:NO]; - [self setBackgroundColor:[NSColor clearColor]]; - menuModel_.reset(new ui::SimpleMenuModel(menuDelegate)); - menuModel_->AddItemWithStringId(0, IDS_PERMISSION_CUSTOMIZE); - menuController_.reset([[MenuControllerCocoa alloc] - initWithModel:menuModel_.get() - useWithPopUpButtonCell:NO]); - [self setMenu:[menuController_ menu]]; - [self setUsesItemFromMenu:NO]; - } - return self; -} - -- (void)drawBorderAndBackgroundWithFrame:(NSRect)frame - inView:(NSView*)controlView { - // The arrow, which is what should be drawn by the base class, is drawn - // during -drawBezelWithFrame. The only way to draw our own border with - // the default arrow is to make the cell unbordered, and draw the border - // from -drawBorderAndBackgroundWithFrame, rather than simply overriding - // -drawBezelWithFrame. - DrawBezel(self, kAngled, kRounded, frame, controlView); - [super drawBorderAndBackgroundWithFrame:NSOffsetRect(frame, -4, 0) - inView:controlView]; -} - -- (NSRect)rect { - NSSize size = [self cellSize]; - return NSMakeRect(0, 0, std::ceil(size.width), std::ceil(size.height)); -} - -@end
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.h b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.h deleted file mode 100644 index be74fa2..0000000 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_COCOA_TRANSLATE_TRANSLATE_BUBBLE_CONTROLLER_H_ -#define CHROME_BROWSER_UI_COCOA_TRANSLATE_TRANSLATE_BUBBLE_CONTROLLER_H_ - -#import <Cocoa/Cocoa.h> - -#include <memory> - -#include "base/mac/scoped_nsobject.h" -#include "chrome/browser/translate/chrome_translate_client.h" -#import "chrome/browser/ui/cocoa/omnibox_decoration_bubble_controller.h" -#include "components/translate/core/common/translate_errors.h" - -@class BrowserWindowController; - -class TranslateBubbleModel; - -namespace content { -class WebContents; -} - -// Displays the Translate bubble. The Translate bubble is a bubble which -// pops up when clicking the Translate icon on Omnibox. This bubble -// allows us to translate a foreign page into user-selected language, -// revert this, and configure the translate setting. -@interface TranslateBubbleController - : OmniboxDecorationBubbleController<NSTextViewDelegate> { - // The views of each state. The keys are TranslateBubbleModel::ViewState, - // and the values are NSView*. - base::scoped_nsobject<NSDictionary<NSNumber*, NSView*>> views_; - - // The 'Try again' button on the error panel. - NSButton* tryAgainButton_; -} - -@property(readonly, nonatomic) const content::WebContents* webContents; -@property(readonly, nonatomic) const TranslateBubbleModel* model; - -- (id)initWithParentWindow:(BrowserWindowController*)controller - model:(std::unique_ptr<TranslateBubbleModel>)model - webContents:(content::WebContents*)webContents; -- (void)switchView:(TranslateBubbleModel::ViewState)viewState; -- (void)switchToErrorView:(translate::TranslateErrors::Type)errorType; - -@end - -// The methods on this category are used internally by the controller and are -// only exposed for testing purposes. DO NOT USE OTHERWISE. -@interface TranslateBubbleController (ExposedForTesting) -- (IBAction)handleCloseButtonPressed:(id)sender; -- (IBAction)handleTranslateButtonPressed:(id)sender; -@end - -#endif // CHROME_BROWSER_UI_COCOA_TRANSLATE_TRANSLATE_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm deleted file mode 100644 index 1ecb0ae..0000000 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm +++ /dev/null
@@ -1,962 +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. - -#import "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h" - -#include <utility> - -#include "base/mac/foundation_util.h" -#include "base/mac/scoped_nsobject.h" -#include "base/macros.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/sys_string_conversions.h" -#include "chrome/browser/ui/chrome_pages.h" -#import "chrome/browser/ui/cocoa/browser_window_controller.h" -#import "chrome/browser/ui/cocoa/bubble_combobox.h" -#include "chrome/browser/ui/cocoa/chrome_style.h" -#import "chrome/browser/ui/cocoa/hover_close_button.h" -#import "chrome/browser/ui/cocoa/info_bubble_view.h" -#import "chrome/browser/ui/cocoa/info_bubble_window.h" -#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" -#import "chrome/browser/ui/cocoa/location_bar/translate_decoration.h" -#include "chrome/browser/ui/translate/language_combobox_model.h" -#include "chrome/browser/ui/translate/translate_bubble_model.h" -#include "chrome/browser/ui/translate/translate_bubble_view_state_transition.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/grit/theme_resources.h" -#include "components/strings/grit/components_strings.h" -#include "components/translate/core/browser/translate_ui_delegate.h" -#include "content/public/browser/browser_context.h" -#include "content/public/common/referrer.h" -#include "skia/ext/skia_utils_mac.h" -#include "ui/base/cocoa/cocoa_base_utils.h" -#import "ui/base/cocoa/controls/hyperlink_button_cell.h" -#include "ui/base/cocoa/controls/hyperlink_text_view.h" -#import "ui/base/cocoa/window_size_constants.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/models/combobox_model.h" - -// TODO(hajimehoshi): This class is almost same as that of views. Refactor them. -class TranslateDenialComboboxModel : public ui::ComboboxModel { - public: - explicit TranslateDenialComboboxModel( - const base::string16& original_language_name) { - // Dummy menu item, which is shown on the top of a NSPopUpButton. The top - // text of the denial pop up menu should be IDS_TRANSLATE_BUBBLE_DENY, while - // it is impossible to use it here because NSPopUpButtons' addItemWithTitle - // removes a duplicated menu item. Instead, the title will be set later by - // NSMenuItem's setTitle. - items_.push_back(base::string16()); - - // Menu items in the drop down menu. - items_.push_back(l10n_util::GetStringFUTF16( - IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_LANG, - original_language_name)); - items_.push_back(l10n_util::GetStringUTF16( - IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_SITE)); - } - ~TranslateDenialComboboxModel() override {} - - private: - // ComboboxModel: - int GetItemCount() const override { return items_.size(); } - base::string16 GetItemAt(int index) override { return items_[index]; } - bool IsItemSeparatorAt(int index) override { return false; } - int GetDefaultIndex() const override { return 0; } - - std::vector<base::string16> items_; - - DISALLOW_COPY_AND_ASSIGN(TranslateDenialComboboxModel); -}; - -const CGFloat kTranslateBubbleIconWidth = 30; -const CGFloat kTranslateBubbleIconHeight = 30; -const CGFloat kTranslateBubbleIconPadding = 12; - -const CGFloat kTranslateBubbleWindowWidth = 320; - -// Padding between the window frame and content. -const CGFloat kTranslateBubbleFramePadding = 16; - -const CGFloat kTranslateBubbleRelatedControlHorizontalSpacing = -2; - -const CGFloat kTranslateBubbleRelatedControlVerticalSpacing = 8; -const CGFloat kTranslateBubbleUnrelatedControlVerticalSpacing = 20; - -const CGFloat kTranslateBubbleContentWidth = - kTranslateBubbleWindowWidth - 2 * kTranslateBubbleFramePadding; - -@interface TranslateBubbleController() - -- (void)performLayout; -- (NSView*)newBeforeTranslateView; -- (NSView*)newTranslatingView; -- (NSView*)newAfterTranslateView; -- (NSView*)newErrorView; -- (NSView*)newAdvancedView; -- (void)updateAdvancedView; -- (void)updateAlwaysCheckboxes; -- (NSImageView*)addIcon:(NSView*)view; -- (NSTextView*)addStyledTextView:(NSString*)message - toView:(NSView*)view - withRanges:(std::vector<NSRange>)ranges - delegate:(id<NSTextViewDelegate>)delegate; -- (NSTextField*)addText:(NSString*)text - toView:(NSView*)view; -- (NSButton*)addLinkButtonWithText:(NSString*)text - action:(SEL)action - toView:(NSView*)view; -- (NSButton*)addButton:(NSString*)title - action:(SEL)action - toView:(NSView*)view; -- (NSButton*)addCheckbox:(NSString*)title - action:(SEL)action - toView:(NSView*)view; -- (NSButton*)addCloseButton:(NSView*)view action:(SEL)action; -- (NSPopUpButton*)addPopUpButton:(ui::ComboboxModel*)model - action:(SEL)action - toView:(NSView*)view; -- (IBAction)handleAlwaysTranslateCheckboxPressed:(id)sender; -- (IBAction)handleDoneButtonPressed:(id)sender; -- (IBAction)handleCancelButtonPressed:(id)sender; -- (IBAction)handleCloseButtonPressed:(id)sender; -- (IBAction)handleShowOriginalButtonPressed:(id)sender; -- (IBAction)handleTryAgainButtonPressed:(id)sender; -- (IBAction)handleAdvancedLinkButtonPressed:(id)sender; -- (IBAction)handleLanguageSettingsLinkButtonPressed:(id)sender; -- (IBAction)handleDenialPopUpButtonNeverTranslateLanguageSelected:(id)sender; -- (IBAction)handleDenialPopUpButtonNeverTranslateSiteSelected:(id)sender; -- (IBAction)handleSourceLanguagePopUpButtonSelectedItemChanged:(id)sender; -- (IBAction)handleTargetLanguagePopUpButtonSelectedItemChanged:(id)sender; -- (BOOL)textView:(NSTextView*)aTextView - clickedOnLink:(id)link - atIndex:(NSUInteger)charIndex; -@end - -@implementation TranslateBubbleController { - @private - content::WebContents* webContents_; - std::unique_ptr<TranslateBubbleModel> model_; - - // The 'Done' or 'Translate' button on the advanced (option) panel. - NSButton* advancedDoneButton_; - - // The 'Cancel' button on the advanced (option) panel. - NSButton* advancedCancelButton_; - - // The 'Always translate' checkbox on the before panel. - // This is nil when the current WebContents is in an incognito window. - NSButton* beforeAlwaysTranslateCheckbox_; - - // The 'Always translate' checkbox on the advanced (option) panel. - // This is nil when the current WebContents is in an incognito window. - NSButton* advancedAlwaysTranslateCheckbox_; - - // The '[x]' close button on the upper right side of the before panel. - NSButton* closeButton_; - - // The combobox model which is used to deny translation at the view before - // translate. - std::unique_ptr<TranslateDenialComboboxModel> translateDenialComboboxModel_; - - // The combobox model for source languages on the advanced (option) panel. - std::unique_ptr<LanguageComboboxModel> sourceLanguageComboboxModel_; - - // The combobox model for target languages on the advanced (option) panel. - std::unique_ptr<LanguageComboboxModel> targetLanguageComboboxModel_; - - // Whether the translation is actually executed once at least. - BOOL translateExecuted_; - - // The state of the 'Always ...' checkboxes. - BOOL shouldAlwaysTranslate_; -} - -@synthesize webContents = webContents_; - -- (id)initWithParentWindow:(BrowserWindowController*)controller - model:(std::unique_ptr<TranslateBubbleModel>)model - webContents:(content::WebContents*)webContents { - NSWindow* parentWindow = [controller window]; - - // Use an arbitrary size; it will be changed in performLayout. - NSRect contentRect = ui::kWindowSizeDeterminedLater; - base::scoped_nsobject<InfoBubbleWindow> window( - [[InfoBubbleWindow alloc] initWithContentRect:contentRect - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:NO]); - - // Disable animations - otherwise, the window/controller will outlive the web - // contents it's associated with. - [window setAllowedAnimations:info_bubble::kAnimateNone]; - - if ((self = [super initWithWindow:window - parentWindow:parentWindow - anchoredAt:NSZeroPoint])) { - webContents_ = webContents; - model_ = std::move(model); - - shouldAlwaysTranslate_ = model_->ShouldAlwaysTranslate(); - if (!webContents_->GetBrowserContext()->IsOffTheRecord()) { - shouldAlwaysTranslate_ = - model_->ShouldAlwaysTranslateBeCheckedByDefault(); - } - - if (model_->GetViewState() != - TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) { - translateExecuted_ = YES; - } - - views_.reset([@{ - @(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE): - [self newBeforeTranslateView], - @(TranslateBubbleModel::VIEW_STATE_TRANSLATING): - [self newTranslatingView], - @(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE): - [self newAfterTranslateView], - @(TranslateBubbleModel::VIEW_STATE_ERROR): - [self newErrorView], - @(TranslateBubbleModel::VIEW_STATE_ADVANCED): - [self newAdvancedView], - } retain]); - - // The [X] Close Button. - closeButton_ = [self addCloseButton:[[self window] contentView] - action:@selector(handleCloseButtonPressed:)]; - - [self performLayout]; - translate::ReportUiAction(translate::BUBBLE_SHOWN); - } - return self; -} - -- (void)windowWillClose:(NSNotification*)notification { - model_->OnBubbleClosing(); - [super windowWillClose:notification]; -} - -- (NSView*)currentView { - NSNumber* key = @(model_->GetViewState()); - NSView* view = [views_ objectForKey:key]; - DCHECK(view); - return view; -} - -- (const TranslateBubbleModel*)model { - return model_.get(); -} - -- (void)showWindow:(id)sender { - BrowserWindowController* browserWindowController = [BrowserWindowController - browserWindowControllerForWindow:self.parentWindow]; - LocationBarViewMac* locationBar = [browserWindowController locationBarBridge]; - if (locationBar) { - NSPoint anchorPoint = - locationBar->GetBubblePointForDecoration([self decorationForBubble]); - anchorPoint = - ui::ConvertPointFromWindowToScreen([self parentWindow], anchorPoint); - [self setAnchorPoint:anchorPoint]; - } - [super showWindow:sender]; -} - -- (LocationBarDecoration*)decorationForBubble { - BrowserWindowController* browserWindowController = [BrowserWindowController - browserWindowControllerForWindow:self.parentWindow]; - LocationBarViewMac* locationBar = [browserWindowController locationBarBridge]; - return locationBar ? locationBar->translate_decoration() : nullptr; -} - -- (void)switchView:(TranslateBubbleModel::ViewState)viewState { - if (model_->GetViewState() == viewState) - return; - - model_->SetViewState(viewState); - [self performLayout]; -} - -- (void)switchToErrorView:(translate::TranslateErrors::Type)errorType { - [self switchView:TranslateBubbleModel::VIEW_STATE_ERROR]; - model_->ShowError(errorType); -} - -- (void)performLayout { - [self updateAlwaysCheckboxes]; - NSWindow* window = [self window]; - [[window contentView] setSubviews:@[ [self currentView], closeButton_ ]]; - - CGFloat height = NSHeight([[self currentView] frame]) + - 2 * kTranslateBubbleFramePadding + - info_bubble::kBubbleArrowHeight; - - NSRect windowFrame = [window contentRectForFrameRect:[[self window] frame]]; - NSRect newWindowFrame = [window - frameRectForContentRect:NSMakeRect(NSMinX(windowFrame), - NSMaxY(windowFrame) - height, - kTranslateBubbleWindowWidth, height)]; - - // Adjust the origin of closeButton. - CGFloat closeX = kTranslateBubbleWindowWidth - - chrome_style::kCloseButtonPadding - - chrome_style::GetCloseButtonSize(); - CGFloat closeY = height - kTranslateBubbleFramePadding - - chrome_style::kCloseButtonPadding - - info_bubble::kBubbleArrowHeight; - [closeButton_ setFrameOrigin:NSMakePoint(closeX, closeY)]; - - [window setFrame:newWindowFrame - display:YES - animate:[[self window] isVisible]]; -} - -- (NSView*)newBeforeTranslateView { - NSRect contentFrame = - NSMakeRect(kTranslateBubbleFramePadding, kTranslateBubbleFramePadding, - kTranslateBubbleContentWidth, 0); - NSView* view = [[NSView alloc] initWithFrame:contentFrame]; - - base::string16 originalLanguageName = - model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); - base::string16 targetLanguageName = - model_->GetLanguageNameAt(model_->GetTargetLanguageIndex()); - - std::vector<size_t> offsets; - NSString* message = l10n_util::GetNSStringF( - IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE_NEW, originalLanguageName, - targetLanguageName, &offsets); - std::vector<NSRange> ranges; - ranges.push_back(NSMakeRange(offsets[0], originalLanguageName.length())); - ranges.push_back(NSMakeRange(offsets[1], targetLanguageName.length())); - - NSTextView* textLabel = [self addStyledTextView:message - toView:view - withRanges:ranges - delegate:self]; - - NSString* title = - l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ACCEPT); - NSButton* translateButton = - [self addButton:title - action:@selector(handleTranslateButtonPressed:) - toView:view]; - [translateButton setKeyEquivalent:@"\r"]; - - // TODO(hajimehoshi): When TranslateDenialComboboxModel is factored out as a - // common model, ui::MenuModel will be used here. - translateDenialComboboxModel_.reset( - new TranslateDenialComboboxModel(originalLanguageName)); - NSPopUpButton* denyPopUpButton = - [self addPopUpButton:translateDenialComboboxModel_.get() - action:nil - toView:view]; - [denyPopUpButton setPullsDown:YES]; - [[denyPopUpButton itemAtIndex:1] setTarget:self]; - [[denyPopUpButton itemAtIndex:1] - setAction:@selector( - handleDenialPopUpButtonNeverTranslateLanguageSelected:)]; - [[denyPopUpButton itemAtIndex:2] setTarget:self]; - [[denyPopUpButton itemAtIndex:2] - setAction:@selector(handleDenialPopUpButtonNeverTranslateSiteSelected:)]; - - title = base::SysUTF16ToNSString( - l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_OPTIONS_MENU_BUTTON)); - [[denyPopUpButton itemAtIndex:0] setTitle:title]; - - // Adjust width for the first item. - base::scoped_nsobject<NSMenu> originalMenu([[denyPopUpButton menu] copy]); - [denyPopUpButton removeAllItems]; - [denyPopUpButton addItemWithTitle:[[originalMenu itemAtIndex:0] title]]; - [denyPopUpButton sizeToFit]; - [denyPopUpButton setMenu:originalMenu]; - - // 'Always translate' checkbox - if (!webContents_->GetBrowserContext()->IsOffTheRecord()) { - title = - l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ALWAYS_DO_THIS); - SEL action = @selector(handleAlwaysTranslateCheckboxPressed:); - beforeAlwaysTranslateCheckbox_ = - [self addCheckbox:title action:action toView:view]; - } - - NSImageView* icon = [self addIcon:view]; - - // Layout - CGFloat yPos = 0; - - [translateButton - setFrameOrigin:NSMakePoint(kTranslateBubbleContentWidth - - NSWidth([translateButton frame]), - yPos)]; - - NSRect denyPopUpButtonFrame = [denyPopUpButton frame]; - CGFloat diffY = [[denyPopUpButton cell] - titleRectForBounds:[denyPopUpButton bounds]].origin.y; - [denyPopUpButton - setFrameOrigin:NSMakePoint( - NSMinX([translateButton frame]) - - denyPopUpButtonFrame.size.width - - kTranslateBubbleRelatedControlHorizontalSpacing, - yPos + diffY)]; - - yPos += NSHeight([translateButton frame]) + - kTranslateBubbleUnrelatedControlVerticalSpacing; - - if (beforeAlwaysTranslateCheckbox_) { - [beforeAlwaysTranslateCheckbox_ - setFrameOrigin:NSMakePoint(kTranslateBubbleIconWidth + - kTranslateBubbleIconPadding, - yPos)]; - - yPos += NSHeight([beforeAlwaysTranslateCheckbox_ frame]) + - kTranslateBubbleRelatedControlVerticalSpacing; - } - - [textLabel setFrameOrigin:NSMakePoint(kTranslateBubbleIconWidth + - kTranslateBubbleIconPadding, - yPos)]; - - yPos = NSMaxY([textLabel frame]); - [icon setFrameOrigin:NSMakePoint(0, yPos - kTranslateBubbleIconHeight)]; - [view setFrameSize:NSMakeSize(kTranslateBubbleContentWidth, yPos)]; - - return view; -} - -- (NSView*)newTranslatingView { - NSRect contentFrame = - NSMakeRect(kTranslateBubbleFramePadding, kTranslateBubbleFramePadding, - kTranslateBubbleContentWidth, 0); - NSView* view = [[NSView alloc] initWithFrame:contentFrame]; - - NSString* message = - l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_TRANSLATING); - NSTextField* textLabel = [self addText:message - toView:view]; - NSString* title = - l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_REVERT); - NSButton* showOriginalButton = - [self addButton:title - action:@selector(handleShowOriginalButtonPressed:) - toView:view]; - [showOriginalButton setEnabled:NO]; - NSImageView* icon = [self addIcon:view]; - - // Layout - // TODO(hajimehoshi): Use l10n_util::VerticallyReflowGroup. - CGFloat yPos = 0; - - [showOriginalButton - setFrameOrigin:NSMakePoint(kTranslateBubbleContentWidth - - NSWidth([showOriginalButton frame]), - yPos)]; - - yPos += NSHeight([showOriginalButton frame]) + - kTranslateBubbleUnrelatedControlVerticalSpacing; - - [textLabel setFrameOrigin:NSMakePoint(kTranslateBubbleIconWidth + - kTranslateBubbleIconPadding, - yPos)]; - - yPos = NSMaxY([textLabel frame]); - [icon setFrameOrigin:NSMakePoint(0, yPos - kTranslateBubbleIconHeight)]; - [view setFrameSize:NSMakeSize(kTranslateBubbleContentWidth, yPos)]; - - return view; -} - -- (NSView*)newAfterTranslateView { - NSRect contentFrame = - NSMakeRect(kTranslateBubbleFramePadding, kTranslateBubbleFramePadding, - kTranslateBubbleContentWidth, 0); - NSView* view = [[NSView alloc] initWithFrame:contentFrame]; - - NSString* message = - l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_TRANSLATED); - NSTextField* textLabel = [self addText:message - toView:view]; - message = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ADVANCED_LINK); - NSButton* advancedLinkButton = - [self addLinkButtonWithText:message - action:@selector(handleAdvancedLinkButtonPressed:) - toView:view]; - NSString* title = - l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_REVERT); - NSButton* showOriginalButton = - [self addButton:title - action:@selector(handleShowOriginalButtonPressed:) - toView:view]; - - NSImageView* icon = [self addIcon:view]; - - // Layout - CGFloat yPos = 0; - - [showOriginalButton - setFrameOrigin:NSMakePoint(kTranslateBubbleContentWidth - - NSWidth([showOriginalButton frame]), - yPos)]; - - yPos += NSHeight([showOriginalButton frame]) + - kTranslateBubbleUnrelatedControlVerticalSpacing; - - [textLabel setFrameOrigin:NSMakePoint(kTranslateBubbleIconWidth + - kTranslateBubbleIconPadding, - yPos)]; - [advancedLinkButton setFrameOrigin:NSMakePoint( - NSMaxX([textLabel frame]), yPos)]; - - yPos = NSMaxY([textLabel frame]); - [icon setFrameOrigin:NSMakePoint(0, yPos - kTranslateBubbleIconHeight)]; - [view setFrameSize:NSMakeSize(kTranslateBubbleContentWidth, yPos)]; - - return view; -} - -- (NSView*)newErrorView { - NSRect contentFrame = - NSMakeRect(kTranslateBubbleFramePadding, kTranslateBubbleFramePadding, - kTranslateBubbleContentWidth, 0); - NSView* view = [[NSView alloc] initWithFrame:contentFrame]; - - NSString* message = - l10n_util::GetNSString(IDS_TRANSLATE_BUBBLE_COULD_NOT_TRANSLATE); - NSTextField* textLabel = [self addText:message toView:view]; - message = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ADVANCED_LINK); - NSButton* advancedLinkButton = - [self addLinkButtonWithText:message - action:@selector(handleAdvancedLinkButtonPressed:) - toView:view]; - NSString* title = - l10n_util::GetNSString(IDS_TRANSLATE_BUBBLE_TRY_AGAIN); - tryAgainButton_ = [self addButton:title - action:@selector(handleTryAgainButtonPressed:) - toView:view]; - - NSImageView* icon = [self addIcon:view]; - - // Layout - CGFloat yPos = 0; - - [tryAgainButton_ - setFrameOrigin:NSMakePoint(kTranslateBubbleContentWidth - - NSWidth([tryAgainButton_ frame]), - yPos)]; - - yPos += NSHeight([tryAgainButton_ frame]) + - kTranslateBubbleUnrelatedControlVerticalSpacing; - - [textLabel setFrameOrigin:NSMakePoint(kTranslateBubbleIconWidth + - kTranslateBubbleIconPadding, - yPos)]; - [advancedLinkButton - setFrameOrigin:NSMakePoint(NSMaxX([textLabel frame]), yPos)]; - - yPos = NSMaxY([textLabel frame]); - [icon setFrameOrigin:NSMakePoint(0, yPos - kTranslateBubbleIconHeight)]; - [view setFrameSize:NSMakeSize(kTranslateBubbleContentWidth, yPos)]; - - return view; -} - -- (NSView*)newAdvancedView { - NSRect contentFrame = - NSMakeRect(kTranslateBubbleFramePadding, kTranslateBubbleFramePadding, - kTranslateBubbleContentWidth, 0); - NSView* view = [[NSView alloc] initWithFrame:contentFrame]; - - NSString* title = l10n_util::GetNSStringWithFixup( - IDS_TRANSLATE_BUBBLE_PAGE_LANGUAGE); - NSTextField* sourceLanguageLabel = [self addText:title - toView:view]; - title = l10n_util::GetNSStringWithFixup( - IDS_TRANSLATE_BUBBLE_TRANSLATION_LANGUAGE); - NSTextField* targetLanguageLabel = [self addText:title - toView:view]; - - // combobox - int sourceDefaultIndex = model_->GetOriginalLanguageIndex(); - int targetDefaultIndex = model_->GetTargetLanguageIndex(); - sourceLanguageComboboxModel_.reset( - new LanguageComboboxModel(sourceDefaultIndex, model_.get())); - targetLanguageComboboxModel_.reset( - new LanguageComboboxModel(targetDefaultIndex, model_.get())); - SEL action = @selector(handleSourceLanguagePopUpButtonSelectedItemChanged:); - NSPopUpButton* sourcePopUpButton = - [self addPopUpButton:sourceLanguageComboboxModel_.get() - action:action - toView:view]; - action = @selector(handleTargetLanguagePopUpButtonSelectedItemChanged:); - NSPopUpButton* targetPopUpButton = - [self addPopUpButton:targetLanguageComboboxModel_.get() - action:action - toView:view]; - - // 'Always translate' checkbox - if (!webContents_->GetBrowserContext()->IsOffTheRecord()) { - NSString* title = - l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ALWAYS); - action = @selector(handleAlwaysTranslateCheckboxPressed:); - advancedAlwaysTranslateCheckbox_ = - [self addCheckbox:title action:action toView:view]; - } - - // Buttons - advancedDoneButton_ = - [self addButton:l10n_util::GetNSStringWithFixup(IDS_DONE) - action:@selector(handleDoneButtonPressed:) - toView:view]; - [advancedDoneButton_ setKeyEquivalent:@"\r"]; - advancedCancelButton_ = - [self addButton:l10n_util::GetNSStringWithFixup(IDS_CANCEL) - action:@selector(handleCancelButtonPressed:) - toView:view]; - - NSString* message = l10n_util::GetNSStringWithFixup( - IDS_TRANSLATE_BUBBLE_LANGUAGE_SETTINGS); - action = @selector(handleLanguageSettingsLinkButtonPressed:); - NSButton* languageSettingsLinkButton = - [self addLinkButtonWithText:message - action:action - toView:view]; - - // Layout - CGFloat textLabelWidth = NSWidth([sourceLanguageLabel frame]); - if (textLabelWidth < NSWidth([targetLanguageLabel frame])) - textLabelWidth = NSWidth([targetLanguageLabel frame]); - - CGFloat yPos = 0; - - [advancedDoneButton_ setFrameOrigin:NSMakePoint(0, yPos)]; - [advancedCancelButton_ setFrameOrigin:NSMakePoint(0, yPos)]; - - [languageSettingsLinkButton setFrameOrigin:NSMakePoint(0, yPos)]; - - // Vertical center the languageSettingsLinkButton with the - // advancedDoneButton_. Move the link position by 1px to make the baseline of - // the text inside the link vertically align with the text inside the buttons. - yPos = 1 + floor((NSHeight([advancedDoneButton_ frame]) - - NSHeight([languageSettingsLinkButton frame])) / 2); - [languageSettingsLinkButton setFrameOrigin:NSMakePoint(0, yPos)]; - - yPos = NSHeight([advancedDoneButton_ frame]) + - kTranslateBubbleUnrelatedControlVerticalSpacing; - - if (advancedAlwaysTranslateCheckbox_) { - [advancedAlwaysTranslateCheckbox_ - setFrameOrigin:NSMakePoint(textLabelWidth, yPos)]; - - yPos += NSHeight([advancedAlwaysTranslateCheckbox_ frame]) + - kTranslateBubbleRelatedControlVerticalSpacing; - } - - CGFloat diffY = [[sourcePopUpButton cell] - titleRectForBounds:[sourcePopUpButton bounds]].origin.y; - - [targetLanguageLabel setFrameOrigin:NSMakePoint( - textLabelWidth - NSWidth([targetLanguageLabel frame]), yPos + diffY)]; - - NSRect frame = [targetPopUpButton frame]; - frame.origin = NSMakePoint(textLabelWidth, yPos); - frame.size.width = - (kTranslateBubbleWindowWidth - 2 * kTranslateBubbleFramePadding) - - textLabelWidth; - [targetPopUpButton setFrame:frame]; - - yPos += NSHeight([targetPopUpButton frame]) + - kTranslateBubbleRelatedControlVerticalSpacing; - - [sourceLanguageLabel setFrameOrigin:NSMakePoint( - textLabelWidth - NSWidth([sourceLanguageLabel frame]), yPos + diffY)]; - - frame = [sourcePopUpButton frame]; - frame.origin = NSMakePoint(textLabelWidth, yPos); - frame.size.width = NSWidth([targetPopUpButton frame]); - [sourcePopUpButton setFrame:frame]; - - [view setFrameSize:NSMakeSize(kTranslateBubbleContentWidth, - NSMaxY([sourcePopUpButton frame]) + - kTranslateBubbleIconPadding)]; - - [self updateAdvancedView]; - - return view; -} - -- (void)updateAdvancedView { - NSString* title; - if (model_->IsPageTranslatedInCurrentLanguages()) - title = l10n_util::GetNSStringWithFixup(IDS_DONE); - else - title = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ACCEPT); - [advancedDoneButton_ setTitle:title]; - [advancedDoneButton_ sizeToFit]; - - NSRect frame = [advancedDoneButton_ frame]; - frame.origin.x = - (kTranslateBubbleWindowWidth - 2 * kTranslateBubbleFramePadding) - - NSWidth(frame); - [advancedDoneButton_ setFrameOrigin:frame.origin]; - - frame = [advancedCancelButton_ frame]; - frame.origin.x = NSMinX([advancedDoneButton_ frame]) - NSWidth(frame) - - kTranslateBubbleRelatedControlHorizontalSpacing; - [advancedCancelButton_ setFrameOrigin:frame.origin]; -} - -- (void)updateAlwaysCheckboxes { - NSInteger state = shouldAlwaysTranslate_ ? NSOnState : NSOffState; - [beforeAlwaysTranslateCheckbox_ setState:state]; - [advancedAlwaysTranslateCheckbox_ setState:state]; -} - -- (NSImageView*)addIcon:(NSView*)view { - NSRect imageFrame = - NSMakeRect(0, 0, kTranslateBubbleIconWidth, kTranslateBubbleIconHeight); - base::scoped_nsobject<NSImageView> image( - [[NSImageView alloc] initWithFrame:imageFrame]); - [image setImage:(ui::ResourceBundle::GetSharedInstance() - .GetImageNamed(IDR_TRANSLATE_BUBBLE_ICON) - .ToNSImage())]; - [view addSubview:image]; - return image.get(); -} - -- (NSTextView*)addStyledTextView:(NSString*)message - toView:(NSView*)view - withRanges:(std::vector<NSRange>)ranges - delegate:(id<NSTextViewDelegate>)delegate { - NSRect frame = - NSMakeRect(kTranslateBubbleFramePadding + kTranslateBubbleIconWidth + - kTranslateBubbleIconPadding, - kTranslateBubbleFramePadding, - kTranslateBubbleContentWidth - kTranslateBubbleIconWidth - - kTranslateBubbleIconPadding, - 0); - base::scoped_nsobject<HyperlinkTextView> styledText( - [[HyperlinkTextView alloc] initWithFrame:frame]); - [styledText setMessage:message - withFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]] - messageColor:(skia::SkColorToCalibratedNSColor(SK_ColorBLACK))]; - [styledText setDelegate:delegate]; - - NSColor* linkColor = - skia::SkColorToCalibratedNSColor(chrome_style::GetLinkColor()); - // Create the link with no underlining. - [styledText setLinkTextAttributes:nil]; - NSTextStorage* storage = [styledText textStorage]; - for (const auto& range : ranges) { - [styledText addLinkRange:range withURL:nil linkColor:linkColor]; - [storage addAttribute:NSUnderlineStyleAttributeName - value:@(NSUnderlineStyleNone) - range:range]; - } - - [view addSubview:styledText]; - [styledText setVerticallyResizable:YES]; - [styledText sizeToFit]; - return styledText.get(); -} - -- (NSTextField*)addText:(NSString*)text - toView:(NSView*)view { - base::scoped_nsobject<NSTextField> textField( - [[NSTextField alloc] initWithFrame:NSZeroRect]); - [textField setEditable:NO]; - [textField setSelectable:YES]; - [textField setDrawsBackground:NO]; - [textField setBezeled:NO]; - [textField setStringValue:text]; - NSFont* font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; - [textField setFont:font]; - [textField setAutoresizingMask:NSViewWidthSizable]; - [view addSubview:textField.get()]; - - [textField sizeToFit]; - return textField.get(); -} - -- (NSButton*)addLinkButtonWithText:(NSString*)text - action:(SEL)action - toView:(NSView*)view { - base::scoped_nsobject<NSButton> button( - [[HyperlinkButtonCell buttonWithString:text] retain]); - - [button setButtonType:NSMomentaryPushInButton]; - [button setBezelStyle:NSRegularSquareBezelStyle]; - [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [button sizeToFit]; - [button setTarget:self]; - [button setAction:action]; - - [view addSubview:button.get()]; - - return button.get(); -} - -- (NSButton*)addButton:(NSString*)title - action:(SEL)action - toView:(NSView*)view { - base::scoped_nsobject<NSButton> button( - [[NSButton alloc] initWithFrame:NSZeroRect]); - [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [button setTitle:title]; - [button setBezelStyle:NSRoundedBezelStyle]; - [[button cell] setControlSize:NSSmallControlSize]; - [button sizeToFit]; - [button setTarget:self]; - [button setAction:action]; - - [view addSubview:button.get()]; - - return button.get(); -} - -- (NSButton*)addCheckbox:(NSString*)title - action:(SEL)action - toView:(NSView*)view { - base::scoped_nsobject<NSButton> button( - [[NSButton alloc] initWithFrame:NSZeroRect]); - [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [button setTitle:title]; - [[button cell] setControlSize:NSSmallControlSize]; - [button setButtonType:NSSwitchButton]; - [button sizeToFit]; - [button setTarget:self]; - [button setAction:action]; - - [view addSubview:button.get()]; - - return button.get(); -} - -- (NSButton*)addCloseButton:(NSView*)view action:(SEL)action { - const int extent = chrome_style::GetCloseButtonSize(); - NSRect frame = NSMakeRect(0, 0, extent, extent); - base::scoped_nsobject<NSButton> button( - [[WebUIHoverCloseButton alloc] initWithFrame:frame]); - [button setTarget:self]; - [button setAction:action]; - [view addSubview:button.get()]; - return button.get(); -} - -- (NSPopUpButton*)addPopUpButton:(ui::ComboboxModel*)model - action:(SEL)action - toView:(NSView*)view { - base::scoped_nsobject<NSPopUpButton> button( - [[BubbleCombobox alloc] initWithFrame:NSZeroRect - pullsDown:NO - model:model]); - [button setTarget:self]; - [button setAction:action]; - [button sizeToFit]; - [view addSubview:button.get()]; - return button.get(); -} - -- (IBAction)handleTranslateButtonPressed:(id)sender { - model_->SetAlwaysTranslate(shouldAlwaysTranslate_); - translate::ReportUiAction(translate::TRANSLATE_BUTTON_CLICKED); - translateExecuted_ = YES; - model_->Translate(); -} - -- (IBAction)handleAlwaysTranslateCheckboxPressed:(NSButton*)sender { - shouldAlwaysTranslate_ = [sender state] == NSOnState; - translate::ReportUiAction(shouldAlwaysTranslate_ - ? translate::ALWAYS_TRANSLATE_CHECKED - : translate::ALWAYS_TRANSLATE_UNCHECKED); -} - -- (IBAction)handleDoneButtonPressed:(id)sender { - translate::ReportUiAction(translate::DONE_BUTTON_CLICKED); - model_->SetAlwaysTranslate(shouldAlwaysTranslate_); - if (model_->IsPageTranslatedInCurrentLanguages()) { - model_->GoBackFromAdvanced(); - [self performLayout]; - } else { - translateExecuted_ = true; - model_->Translate(); - [self switchView:TranslateBubbleModel::VIEW_STATE_TRANSLATING]; - } -} - -- (IBAction)handleCancelButtonPressed:(id)sender { - translate::ReportUiAction(translate::CANCEL_BUTTON_CLICKED); - model_->GoBackFromAdvanced(); - [self performLayout]; -} - -- (IBAction)handleCloseButtonPressed:(id)sender { - model_->DeclineTranslation(); - translate::ReportUiAction(translate::CLOSE_BUTTON_CLICKED); - [self close]; -} - -- (IBAction)handleShowOriginalButtonPressed:(id)sender { - translate::ReportUiAction(translate::SHOW_ORIGINAL_BUTTON_CLICKED); - model_->RevertTranslation(); - [self close]; -} - -- (IBAction)handleTryAgainButtonPressed:(id)sender { - model_->Translate(); - translate::ReportUiAction(translate::TRY_AGAIN_BUTTON_CLICKED); -} - -- (IBAction)handleAdvancedLinkButtonPressed:(id)sender { - translate::ReportUiAction(translate::ADVANCED_LINK_CLICKED); - [self switchView:TranslateBubbleModel::VIEW_STATE_ADVANCED]; -} - -- (IBAction)handleLanguageSettingsLinkButtonPressed:(id)sender { - GURL url = chrome::GetSettingsUrl(chrome::kLanguageOptionsSubPage); - webContents_->OpenURL(content::OpenURLParams( - url, content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_LINK, false)); - translate::ReportUiAction(translate::SETTINGS_LINK_CLICKED); - [self close]; -} - -- (IBAction)handleDenialPopUpButtonNeverTranslateLanguageSelected:(id)sender { - translate::ReportUiAction(translate::NEVER_TRANSLATE_LANGUAGE_MENU_CLICKED); - model_->DeclineTranslation(); - model_->SetNeverTranslateLanguage(true); - [self close]; -} - -- (IBAction)handleDenialPopUpButtonNeverTranslateSiteSelected:(id)sender { - translate::ReportUiAction(translate::NEVER_TRANSLATE_SITE_MENU_CLICKED); - model_->DeclineTranslation(); - model_->SetNeverTranslateSite(true); - [self close]; -} - -- (IBAction)handleSourceLanguagePopUpButtonSelectedItemChanged:(id)sender { - translate::ReportUiAction(translate::SOURCE_LANGUAGE_MENU_CLICKED); - NSPopUpButton* button = base::mac::ObjCCastStrict<NSPopUpButton>(sender); - model_->UpdateOriginalLanguageIndex([button indexOfSelectedItem]); - [self updateAdvancedView]; -} - -- (IBAction)handleTargetLanguagePopUpButtonSelectedItemChanged:(id)sender { - translate::ReportUiAction(translate::TARGET_LANGUAGE_MENU_CLICKED); - NSPopUpButton* button = base::mac::ObjCCastStrict<NSPopUpButton>(sender); - model_->UpdateTargetLanguageIndex([button indexOfSelectedItem]); - [self updateAdvancedView]; -} - -// The NSTextViewDelegate method which called when user click on the -// source or target language on the before translate view. -- (BOOL)textView:(NSTextView*)aTextView - clickedOnLink:(id)link - atIndex:(NSUInteger)charIndex { - translate::ReportUiAction(translate::ADVANCED_LINK_CLICKED); - [self switchView:TranslateBubbleModel::VIEW_STATE_ADVANCED]; - return YES; -} - -@end
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm deleted file mode 100644 index e8b97e0b..0000000 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm +++ /dev/null
@@ -1,203 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h" - -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#import "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" -#import "chrome/browser/ui/cocoa/browser_window_controller.h" -#import "chrome/browser/ui/cocoa/info_bubble_window.h" -#import "chrome/browser/ui/cocoa/test/cocoa_profile_test.h" -#include "chrome/browser/ui/cocoa/test/run_loop_testing.h" -#include "chrome/browser/ui/translate/translate_bubble_model.h" -#include "chrome/common/url_constants.h" -#include "content/public/browser/site_instance.h" -#include "ui/base/ui_base_features.h" - -@implementation BrowserWindowController (ForTesting) - -- (TranslateBubbleController*)translateBubbleController{ - return translateBubbleController_; -} - -@end - -@implementation TranslateBubbleController (ForTesting) - -- (NSView*)errorView { - NSNumber* key = @(TranslateBubbleModel::VIEW_STATE_ERROR); - return [views_ objectForKey:key]; -} -- (NSButton*)tryAgainButton { - return tryAgainButton_; -} - -@end - -class TranslateBubbleControllerTest : public CocoaProfileTest { - public: - TranslateBubbleControllerTest() {} - - // CocoaProfileTest: - void SetUp() override { - // This file only tests Cocoa UI and can be deleted when kSecondaryUiMd is - // default. - scoped_feature_list_.InitAndDisableFeature(features::kSecondaryUiMd); - - CocoaProfileTest::SetUp(); - - site_instance_ = content::SiteInstance::Create(profile()); - - NSWindow* nativeWindow = browser()->window()->GetNativeWindow(); - bwc_ = - [BrowserWindowController browserWindowControllerForWindow:nativeWindow]; - web_contents_ = AppendToTabStrip(); - } - - content::WebContents* AppendToTabStrip() { - std::unique_ptr<content::WebContents> web_contents = - content::WebContents::Create(content::WebContents::CreateParams( - profile(), site_instance_.get())); - content::WebContents* raw_web_contents = web_contents.get(); - browser()->tab_strip_model()->AppendWebContents(std::move(web_contents), - /*foreground=*/true); - return raw_web_contents; - } - - BrowserWindowController* bwc() { return bwc_; } - - TranslateBubbleController* bubble() { - return [bwc() translateBubbleController]; - } - - void ShowBubble() { - ASSERT_FALSE(bubble()); - translate::TranslateStep step = translate::TRANSLATE_STEP_BEFORE_TRANSLATE; - - [bwc_ showTranslateBubbleForWebContents:web_contents_ - step:step - errorType:translate::TranslateErrors::NONE]; - - // Ensure that there are no closing animations. - InfoBubbleWindow* window = (InfoBubbleWindow*)[bubble() window]; - [window setAllowedAnimations:info_bubble::kAnimateNone]; - } - - void SwitchToErrorView() { - translate::TranslateStep step = translate::TRANSLATE_STEP_TRANSLATE_ERROR; - [bwc_ - showTranslateBubbleForWebContents:web_contents_ - step:step - errorType:translate::TranslateErrors::NETWORK]; - } - - void CloseBubble() { - [bubble() close]; - chrome::testing::NSRunLoopRunAllPending(); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; - scoped_refptr<content::SiteInstance> site_instance_; - BrowserWindowController* bwc_; - content::WebContents* web_contents_; - - DISALLOW_COPY_AND_ASSIGN(TranslateBubbleControllerTest); -}; - -TEST_F(TranslateBubbleControllerTest, ShowAndClose) { - EXPECT_FALSE(bubble()); - - ShowBubble(); - EXPECT_TRUE(bubble()); - - CloseBubble(); - EXPECT_FALSE(bubble()); -} - -TEST_F(TranslateBubbleControllerTest, SwitchToErrorView) { - EXPECT_FALSE(bubble()); - ShowBubble(); - const TranslateBubbleModel* model = [bubble() model]; - - EXPECT_TRUE(bubble()); - EXPECT_EQ(TranslateBubbleModel::ViewState::VIEW_STATE_BEFORE_TRANSLATE, - model->GetViewState()); - - SwitchToErrorView(); - - NSView* errorView = [bubble() errorView]; - // We should have 4 subview inside the error view: - // A NSTextField, a NSImageView and two NSButton. - EXPECT_EQ(4UL, [[errorView subviews] count]); - - // one of the subview should be "Try again" button. - EXPECT_TRUE([[errorView subviews] containsObject:[bubble() tryAgainButton]]); - EXPECT_EQ(TranslateBubbleModel::ViewState::VIEW_STATE_ERROR, - model->GetViewState()); - EXPECT_TRUE(bubble()); - CloseBubble(); -} - -TEST_F(TranslateBubbleControllerTest, SwitchViews) { - // A basic test which just switch between views to make sure no crash. - EXPECT_FALSE(bubble()); - - ShowBubble(); - EXPECT_TRUE(bubble()); - - // Switch to during translating view. - [bubble() - switchView:(TranslateBubbleModel::ViewState::VIEW_STATE_TRANSLATING)]; - - EXPECT_TRUE(bubble()); - - // Switch to after translating view. - [bubble() - switchView:(TranslateBubbleModel::ViewState::VIEW_STATE_AFTER_TRANSLATE)]; - - EXPECT_TRUE(bubble()); - - // Switch to advanced view. - [bubble() switchView:(TranslateBubbleModel::ViewState::VIEW_STATE_ADVANCED)]; - - EXPECT_TRUE(bubble()); - - // Switch to before translating view. - [bubble() switchView: - (TranslateBubbleModel::ViewState::VIEW_STATE_BEFORE_TRANSLATE)]; - - EXPECT_TRUE(bubble()); - - CloseBubble(); - EXPECT_FALSE(bubble()); -} - -TEST_F(TranslateBubbleControllerTest, CloseRegistersDecline) { - const char kDeclineTranslateDismissUI[] = - "Translate.DeclineTranslateDismissUI"; - const char kDeclineTranslate[] = "Translate.DeclineTranslate"; - - // A simple close without any interactions registers as a dismissal. - { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseBubble(); - histogram_tester.ExpectTotalCount(kDeclineTranslateDismissUI, 1); - histogram_tester.ExpectTotalCount(kDeclineTranslate, 0); - } - - // A close while pressing e.g. 'x', registers as decline. - { - base::HistogramTester histogram_tester; - ShowBubble(); - [bubble() handleCloseButtonPressed:nil]; - - CloseBubble(); - histogram_tester.ExpectTotalCount(kDeclineTranslateDismissUI, 0); - histogram_tester.ExpectTotalCount(kDeclineTranslate, 1); - } -}
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_test_utils_views_cocoa.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_test_utils_views_cocoa.mm deleted file mode 100644 index 0574cd8..0000000 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_test_utils_views_cocoa.mm +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/translate/translate_bubble_test_utils.h" - -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/cocoa/browser_dialogs_views_mac.h" -#include "chrome/browser/ui/cocoa/browser_window_controller.h" -#include "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h" -#include "chrome/browser/ui/translate/translate_bubble_model.h" -#include "chrome/browser/ui/views/translate/translate_bubble_view.h" -#include "ui/events/keycodes/dom/dom_code.h" -#include "ui/views/controls/button/label_button.h" - -// TODO(groby): Share with translate_bubble_controller_unittest.mm -@implementation BrowserWindowController (ForTesting) - -- (TranslateBubbleController*)translateBubbleController { - return translateBubbleController_; -} - -@end - -namespace translate { - -namespace test_utils { - -const TranslateBubbleModel* GetCurrentModel(Browser* browser) { - DCHECK(browser); - if (chrome::ShowAllDialogsWithViewsToolkit()) { - TranslateBubbleView* view = TranslateBubbleView::GetCurrentBubble(); - return view ? view->model() : nullptr; - } - - NSWindow* native_window = browser->window()->GetNativeWindow(); - BrowserWindowController* controller = - [BrowserWindowController browserWindowControllerForWindow:native_window]; - return [[controller translateBubbleController] model]; -} - -void PressTranslate(Browser* browser) { - DCHECK(browser); - - if (chrome::ShowAllDialogsWithViewsToolkit()) { - TranslateBubbleView* bubble = TranslateBubbleView::GetCurrentBubble(); - DCHECK(bubble); - - views::LabelButton button(nullptr, base::string16()); - button.set_id(TranslateBubbleView::BUTTON_ID_TRANSLATE); - - bubble->ButtonPressed(&button, - ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, - ui::DomCode::ENTER, ui::EF_NONE)); - return; - } - - NSWindow* native_window = browser->window()->GetNativeWindow(); - BrowserWindowController* controller = - [BrowserWindowController browserWindowControllerForWindow:native_window]; - [[controller translateBubbleController] handleTranslateButtonPressed:nil]; -} - -} // namespace test_utils - -} // namespace translate
diff --git a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util.cc b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util.cc index 5e41940f..63e7925 100644 --- a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util.cc +++ b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util.cc
@@ -14,12 +14,10 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profiles_state.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" -#include "components/browser_sync/profile_sync_service.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" @@ -93,16 +91,15 @@ if (signin_error_controller && signin_error_controller->HasError()) return false; - const browser_sync::ProfileSyncService* sync_service = - ProfileSyncServiceFactory::GetForProfile(profile); // Promotion should only show for english locale. PrefService* local_state = g_browser_process->local_state(); std::string locale = base::i18n::GetConfiguredLocale(); if (locale != "en-US" && locale != "en-CA") return false; if (!base::FeatureList::IsEnabled(features::kDesktopIOSPromotion) || - !sync_service || !sync_service->IsSyncAllowed()) + !profile->IsSyncAllowed()) { return false; + } // Check if the specific entrypoint is enabled by Finch. std::string targeted_entry_point = base::GetFieldTrialParamValueByFeature(
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc index 73f9d37..5d731de 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/views/chrome_constrained_window_views_client.h" #include "chrome/browser/ui/views/chrome_views_delegate.h" #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h" #include "components/constrained_window/constrained_window_views.h" #include "services/service_manager/sandbox/switches.h" @@ -53,8 +54,6 @@ #include "ash/public/interfaces/constants.mojom.h" #include "content/public/common/content_switches.h" #include "ui/base/ui_base_features.h" -#else // defined(OS_CHROMEOS) -#include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h" #endif // defined(OS_CHROMEOS) ChromeBrowserMainExtraPartsViews::ChromeBrowserMainExtraPartsViews() { @@ -173,18 +172,14 @@ } void ChromeBrowserMainExtraPartsViews::PostBrowserStart() { -#if !defined(OS_CHROMEOS) relaunch_notification_controller_ = std::make_unique<RelaunchNotificationController>( UpgradeDetector::GetInstance()); -#endif } void ChromeBrowserMainExtraPartsViews::PostMainMessageLoopRun() { -#if !defined(OS_CHROMEOS) // The relaunch notification controller acts on timer-based events. Tear it // down explicitly here to avoid a case where such an event arrives during // shutdown. relaunch_notification_controller_.reset(); -#endif }
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h index 434a1f0..697ac4d 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h
@@ -27,9 +27,7 @@ } #endif -#if !defined(OS_CHROMEOS) class RelaunchNotificationController; -#endif class ChromeBrowserMainExtraPartsViews : public ChromeBrowserMainExtraParts { public: @@ -60,11 +58,9 @@ std::unique_ptr<views::MusClient> mus_client_; #endif -#if !defined(OS_CHROMEOS) // Manages the relaunch notification prompts. std::unique_ptr<RelaunchNotificationController> relaunch_notification_controller_; -#endif DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsViews); };
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm index bc1ff473..69c5df8c 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
@@ -73,6 +73,18 @@ // calling through private APIs. DCHECK(tabstrip); + const bool restored = !frame()->IsMaximized() && !frame()->IsFullscreen(); + gfx::Rect bounds = gfx::Rect(0, GetTopInset(restored), width(), + tabstrip->GetPreferredSize().height()); + bounds.Inset(GetTabStripLeftInset(), 0, + GetAfterTabstripItemWidth() + GetTabstripPadding(), 0); + return bounds; +} + +int BrowserNonClientFrameViewMac::GetTopInset(bool restored) const { + if (!browser_view()->IsTabStripVisible()) + return 0; + // Calculate the y offset for the tab strip because in fullscreen mode the tab // strip may need to move under the slide down menu bar. CGFloat y_offset = kTabstripTopInset; @@ -99,15 +111,7 @@ } } - gfx::Rect bounds = - gfx::Rect(0, y_offset, width(), tabstrip->GetPreferredSize().height()); - bounds.Inset(GetTabStripLeftInset(), 0, - GetAfterTabstripItemWidth() + GetTabstripPadding(), 0); - return bounds; -} - -int BrowserNonClientFrameViewMac::GetTopInset(bool restored) const { - return browser_view()->IsTabStripVisible() ? kTabstripTopInset : 0; + return y_offset; } int BrowserNonClientFrameViewMac::GetAfterTabstripItemWidth() const {
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc index 0e5d086..19f3694 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.cc +++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -323,15 +323,7 @@ vertical_layout_rect_ = browser_view->GetLocalBounds(); int top_inset = delegate_->GetTopInsetInBrowserView(false); int top = LayoutTabStripRegion(top_inset); - int possible_fullscreen_tab_strip_offset = 0; if (delegate_->IsTabStripVisible()) { -#if defined(OS_MACOSX) - // Tab strip should always start from the top inset unless it is under the - // system menu bar during full screen mode on Mac. In this case, the tab - // strip and other top UI will move under the menu bar while the content - // should stay put. - possible_fullscreen_tab_strip_offset = tab_strip_->bounds().y() - top_inset; -#endif // By passing true to GetTopInsetInBrowserView(), we position the tab // background to vertically align with the frame background image of a // restored-mode frame, even in a maximized window. Then in the frame code, @@ -354,7 +346,6 @@ UpdateTopContainerBounds(); int bottom = LayoutDownloadShelf(browser_view->height()); - top -= possible_fullscreen_tab_strip_offset; // Treat a detached bookmark bar as if the web contents container is shifted // upwards and overlaps it. int active_top_margin = GetContentsOffsetForBookmarkBar();
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc index 914e1fa1..3240412 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
@@ -50,6 +50,9 @@ IconLabelBubbleView::SeparatorView::SeparatorView(IconLabelBubbleView* owner) { DCHECK(owner); owner_ = owner; + + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); } void IconLabelBubbleView::SeparatorView::OnPaint(gfx::Canvas* canvas) { @@ -63,15 +66,18 @@ gfx::PointF(x, GetLocalBounds().bottom()), separator_color); } -void IconLabelBubbleView::SeparatorView::OnImplicitAnimationsCompleted() { - if (layer() && layer()->opacity() == 1.0f) - DestroyLayer(); -} - void IconLabelBubbleView::SeparatorView::UpdateOpacity() { if (!visible()) return; + // When using focus rings are visible we should hide the separator instantly + // when the IconLabelBubbleView is focused. Otherwise we should follow the + // inkdrop. + if (views::PlatformStyle::kPreferFocusRings && owner_->HasFocus()) { + layer()->SetOpacity(0.0f); + return; + } + views::InkDrop* ink_drop = owner_->GetInkDrop(); DCHECK(ink_drop); @@ -88,10 +94,6 @@ duration = kIconLabelBubbleFadeInDurationMs; } - if (!layer()) - SetPaintToLayer(); - layer()->SetFillsBoundsOpaquely(false); - if (disable_animation_for_test_) { layer()->SetOpacity(opacity); } else { @@ -99,7 +101,6 @@ animation.SetTransitionDuration( base::TimeDelta::FromMilliseconds(duration)); animation.SetTweenType(gfx::Tween::Type::EASE_IN); - animation.AddObserver(this); layer()->SetOpacity(opacity); } } @@ -377,6 +378,16 @@ OnActivate(event); } +void IconLabelBubbleView::OnFocus() { + separator_view_->UpdateOpacity(); + Button::OnFocus(); +} + +void IconLabelBubbleView::OnBlur() { + separator_view_->UpdateOpacity(); + Button::OnBlur(); +} + void IconLabelBubbleView::OnWidgetDestroying(views::Widget* widget) { widget->RemoveObserver(this); }
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h index 4d3254d..e45806a 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "base/strings/string16.h" -#include "ui/compositor/layer_animation_observer.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/size.h" #include "ui/views/animation/ink_drop_host_view.h" @@ -38,17 +37,13 @@ static constexpr int kTrailingPaddingPreMd = 2; // A view that draws the separator. - class SeparatorView : public views::View, - public ui::ImplicitAnimationObserver { + class SeparatorView : public views::View { public: explicit SeparatorView(IconLabelBubbleView* owner); // views::View: void OnPaint(gfx::Canvas* canvas) override; - // ui::ImplicitAnimationObserver: - void OnImplicitAnimationsCompleted() override; - // Updates the opacity based on the ink drop's state. void UpdateOpacity(); @@ -154,6 +149,8 @@ bool IsTriggerableEvent(const ui::Event& event) override; bool ShouldUpdateInkDropOnClickCanceled() const override; void NotifyClick(const ui::Event& event) override; + void OnFocus() override; + void OnBlur() override; // views::WidgetObserver: void OnWidgetDestroying(views::Widget* widget) override;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index 677eb81..60b6e2f 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -178,12 +178,14 @@ match_.contents_class); suggestion_view_->description()->SetText(match_.description, match_.description_class); - // Explicitly re-apply default styling - high contrast modes use different - // text colors depending on selection state. - suggestion_view_->content()->ApplyTextColor( - OmniboxPart::RESULTS_TEXT_DEFAULT); - suggestion_view_->description()->ApplyTextColor( - OmniboxPart::RESULTS_TEXT_DEFAULT); + + // Normally, OmniboxTextView caches its appearance, but in high contrast + // selected-ness changes the text colors, so the styling of the text part of + // the results needs to be recomputed. + if (high_contrast) { + suggestion_view_->content()->ReapplyStyling(); + suggestion_view_->description()->ReapplyStyling(); + } } AutocompleteMatch* keyword_match = match_.associated_keyword.get();
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc index 4d0cb05..5d87db9 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
@@ -224,36 +224,7 @@ std::make_unique<ACMatchClassifications>(classifications); render_text_ = CreateRenderText(text); - const size_t text_length = render_text_->text().length(); - for (size_t i = 0; i < classifications.size(); ++i) { - const size_t text_start = classifications[i].offset; - if (text_start >= text_length) - break; - - const size_t text_end = - (i < (classifications.size() - 1)) - ? std::min(classifications[i + 1].offset, text_length) - : text_length; - const gfx::Range current_range(text_start, text_end); - - // Calculate style-related data. - if (classifications[i].style & ACMatchClassification::MATCH) - render_text_->ApplyWeight(gfx::Font::Weight::BOLD, current_range); - - OmniboxPart part = OmniboxPart::RESULTS_TEXT_DEFAULT; - if (classifications[i].style & ACMatchClassification::URL) { - part = OmniboxPart::RESULTS_TEXT_URL; - render_text_->SetDirectionalityMode(gfx::DIRECTIONALITY_AS_URL); - } else if (classifications[i].style & ACMatchClassification::DIM) { - part = OmniboxPart::RESULTS_TEXT_DIMMED; - } else if (classifications[i].style & ACMatchClassification::INVISIBLE) { - part = OmniboxPart::RESULTS_TEXT_INVISIBLE; - } - render_text_->ApplyColor(result_view_->GetColor(part), current_range); - } - - UpdateLineHeight(); - SetPreferredSize(CalculatePreferredSize()); + ReapplyStyling(); } void OmniboxTextView::SetText(const SuggestionAnswer::ImageLine& line, @@ -309,6 +280,40 @@ return font_height_; } +void OmniboxTextView::ReapplyStyling() { + const ACMatchClassifications& classifications = *cached_classifications_; + const size_t text_length = render_text_->text().length(); + for (size_t i = 0; i < classifications.size(); ++i) { + const size_t text_start = classifications[i].offset; + if (text_start >= text_length) + break; + + const size_t text_end = + (i < (classifications.size() - 1)) + ? std::min(classifications[i + 1].offset, text_length) + : text_length; + const gfx::Range current_range(text_start, text_end); + + // Calculate style-related data. + if (classifications[i].style & ACMatchClassification::MATCH) + render_text_->ApplyWeight(gfx::Font::Weight::BOLD, current_range); + + OmniboxPart part = OmniboxPart::RESULTS_TEXT_DEFAULT; + if (classifications[i].style & ACMatchClassification::URL) { + part = OmniboxPart::RESULTS_TEXT_URL; + render_text_->SetDirectionalityMode(gfx::DIRECTIONALITY_AS_URL); + } else if (classifications[i].style & ACMatchClassification::DIM) { + part = OmniboxPart::RESULTS_TEXT_DIMMED; + } else if (classifications[i].style & ACMatchClassification::INVISIBLE) { + part = OmniboxPart::RESULTS_TEXT_INVISIBLE; + } + render_text_->ApplyColor(result_view_->GetColor(part), current_range); + } + + UpdateLineHeight(); + SetPreferredSize(CalculatePreferredSize()); +} + std::unique_ptr<gfx::RenderText> OmniboxTextView::CreateRenderText( const base::string16& text) const { auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.h b/chrome/browser/ui/views/omnibox/omnibox_text_view.h index 4a5bc29..01ccc0b 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_text_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.h
@@ -63,6 +63,10 @@ // multiple lines. int GetLineHeight() const; + // Reapplies text styling to the results text, based on the types of the match + // parts. + void ReapplyStyling(); + private: std::unique_ptr<gfx::RenderText> CreateRenderText( const base::string16& text) const;
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index 546f9af..d5845ef 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -604,6 +604,10 @@ views::Widget::OnNativeWidgetSizeChanged(new_size); } +void OverlayWindowViews::OnNativeWidgetDestroyed() { + controller_->OnWindowDestroyed(); +} + void OverlayWindowViews::TogglePlayPause() { // Retrieve expected active state based on what command was sent in // TogglePlayPause() since the IPC message may not have been propogated
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.h b/chrome/browser/ui/views/overlay/overlay_window_views.h index ca28d91..da9e1f3 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.h +++ b/chrome/browser/ui/views/overlay/overlay_window_views.h
@@ -51,6 +51,7 @@ void OnNativeBlur() override; void OnNativeWidgetMove() override; void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override; + void OnNativeWidgetDestroyed() override; // Gets the bounds of the controls. gfx::Rect GetCloseControlsBounds();
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc index f718d1d6d..0f421b4 100644 --- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc +++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -151,6 +151,10 @@ return button; } +bool OrderSummaryViewController::ShouldShowSecondaryButton() { + return false; +} + base::string16 OrderSummaryViewController::GetSheetTitle() { return l10n_util::GetStringUTF16(IDS_PAYMENTS_ORDER_SUMMARY_LABEL); }
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.h b/chrome/browser/ui/views/payments/order_summary_view_controller.h index 9f25d33..e085fa3 100644 --- a/chrome/browser/ui/views/payments/order_summary_view_controller.h +++ b/chrome/browser/ui/views/payments/order_summary_view_controller.h
@@ -40,6 +40,7 @@ private: // PaymentRequestSheetController: std::unique_ptr<views::Button> CreatePrimaryButton() override; + bool ShouldShowSecondaryButton() override; base::string16 GetSheetTitle() override; void FillContentView(views::View* content_view) override; void UpdatePayButtonState(bool enabled);
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.cc b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.cc index 3696241e..d52ea1ed 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.cc +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.cc
@@ -360,7 +360,7 @@ widget_ = RelaunchRecommendedBubbleView::ShowBubble( browser, upgrade_detector_->upgrade_detected_time(), - base::BindRepeating(&chrome::AttemptRestart)); + base::BindRepeating(&chrome::AttemptRelaunch)); // Monitor the widget so that |widget_| can be cleared on close. widget_->AddObserver(this); @@ -384,7 +384,7 @@ widget_ = RelaunchRequiredDialogView::Show( browser, timer_.desired_run_time(), - base::BindRepeating(&chrome::AttemptRestart)); + base::BindRepeating(&chrome::AttemptRelaunch)); // Monitor the widget so that |widget_| can be cleared on close. widget_->AddObserver(this); @@ -396,5 +396,5 @@ } void RelaunchNotificationController::OnRelaunchDeadlineExpired() { - chrome::AttemptRestart(); + chrome::AttemptRelaunch(); }
diff --git a/chrome/browser/ui/views/tabs/new_tab_button.cc b/chrome/browser/ui/views/tabs/new_tab_button.cc index ceefd28..401ae5a 100644 --- a/chrome/browser/ui/views/tabs/new_tab_button.cc +++ b/chrome/browser/ui/views/tabs/new_tab_button.cc
@@ -465,13 +465,13 @@ // The new tab background is mirrored in RTL mode, but the theme // background should never be mirrored. Mirror it here to compensate. float x_scale = 1.0f; - int x = GetMirroredX() + background_offset_.x(); - const gfx::Size size = GetContentsBounds().size(); + const gfx::Rect& contents_bounds = GetContentsBounds(); + int x = GetMirroredX() + contents_bounds.x() + background_offset_.x(); if (base::i18n::IsRTL()) { x_scale = -1.0f; // Offset by |width| such that the same region is painted as if there // was no flip. - x += size.width(); + x += contents_bounds.width(); } const bool succeeded = canvas->InitPaintFlagsForTiling(
diff --git a/chrome/browser/ui/webui/ukm/ukm_internals_ui.cc b/chrome/browser/ui/webui/ukm/ukm_internals_ui.cc index 1f25b7d..0b69b7b 100644 --- a/chrome/browser/ui/webui/ukm/ukm_internals_ui.cc +++ b/chrome/browser/ui/webui/ukm/ukm_internals_ui.cc
@@ -85,6 +85,8 @@ } // namespace +// Changes to this class should be in sync with its iOS equivalent +// ios/chrome/browser/ui/webui/ukm_internals_ui.cc UkmInternalsUI::UkmInternalsUI(content::WebUI* web_ui) : content::WebUIController(web_ui) { ukm::UkmService* ukm_service =
diff --git a/chrome/browser/vr/service/browser_xr_device.cc b/chrome/browser/vr/service/browser_xr_device.cc index 6fd9c9c..e32daa766 100644 --- a/chrome/browser/vr/service/browser_xr_device.cc +++ b/chrome/browser/vr/service/browser_xr_device.cc
@@ -113,21 +113,19 @@ base::WeakPtr<VRDisplayHost> display, device::mojom::XRDeviceRuntimeSessionOptionsPtr options, device::mojom::VRDisplayHost::RequestSessionCallback callback, - device::mojom::XRPresentationConnectionPtr connection, + device::mojom::XRSessionPtr session, device::mojom::XRSessionControllerPtr immersive_session_controller) { - if (connection && display) { + if (session && display) { if (options->immersive) { presenting_display_host_ = display.get(); immersive_session_controller_ = std::move(immersive_session_controller); } - device::mojom::XRSessionPtr xr_session = device::mojom::XRSession::New(); - xr_session->connection = std::move(connection); - std::move(callback).Run(std::move(xr_session)); + std::move(callback).Run(std::move(session)); } else { std::move(callback).Run(nullptr); - if (connection) { - // The device has been removed, but we still got a connection, so make + if (session) { + // The device has been removed, but we still got a session, so make // sure to clean up this weird state. immersive_session_controller_ = std::move(immersive_session_controller); StopImmersiveSession();
diff --git a/chrome/browser/vr/service/browser_xr_device.h b/chrome/browser/vr/service/browser_xr_device.h index de78a5a..242ee26 100644 --- a/chrome/browser/vr/service/browser_xr_device.h +++ b/chrome/browser/vr/service/browser_xr_device.h
@@ -57,7 +57,7 @@ base::WeakPtr<VRDisplayHost> display, device::mojom::XRDeviceRuntimeSessionOptionsPtr options, device::mojom::VRDisplayHost::RequestSessionCallback callback, - device::mojom::XRPresentationConnectionPtr connection, + device::mojom::XRSessionPtr session, device::mojom::XRSessionControllerPtr immersive_session_controller); device::mojom::XRRuntimePtr device_;
diff --git a/chrome/browser/vr/service/vr_display_host.cc b/chrome/browser/vr/service/vr_display_host.cc index b22645ba7..f2937a3 100644 --- a/chrome/browser/vr/service/vr_display_host.cc +++ b/chrome/browser/vr/service/vr_display_host.cc
@@ -124,25 +124,11 @@ std::move(display_info)); } -void VRDisplayHost::OnARSessionCreated( - vr::BrowserXrDevice* device, - device::mojom::VRDisplayHost::RequestSessionCallback callback, - device::mojom::XRSessionPtr session) { - if (!session) { - std::move(callback).Run(nullptr); - return; - } - - device->GetRuntime()->RequestMagicWindowSession( - base::BindOnce(&VRDisplayHost::OnMagicWindowSessionCreated, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - void VRDisplayHost::OnMagicWindowSessionCreated( device::mojom::VRDisplayHost::RequestSessionCallback callback, - device::mojom::VRMagicWindowProviderPtr magic_window_provider, + device::mojom::XRSessionPtr session, device::mojom::XRSessionControllerPtr controller) { - if (!magic_window_provider) { + if (!session) { std::move(callback).Run(nullptr); return; } @@ -152,10 +138,7 @@ magic_window_controllers_.AddPtr(std::move(controller)); - device::mojom::XRSessionPtr xr_session = device::mojom::XRSession::New(); - xr_session->magic_window_provider = magic_window_provider.PassInterface(); - - std::move(callback).Run(std::move(xr_session)); + std::move(callback).Run(std::move(session)); } VRDisplayHost::~VRDisplayHost() { @@ -214,28 +197,16 @@ ReportRequestPresent(); } - // Ensure we will notify the immersive device when we are destroyed, so - // lingering presentation state will be cleaned up. - DCHECK(device == immersive_device_); - device->RequestSession(this, std::move(runtime_options), std::move(callback)); - } else if (runtime_options->provide_passthrough_camera) { - // WebXrHitTest enabled means we are requesting an AR session. This means - // we make two requests to the device - one to request permissions and start - // the runtime, then a followup to actually get the magic window provider. - // TODO(offenwanger): Clean this up and make only one request. - // base::Unretained(device) is safe because either device is alive when we - // are called back, or we are called back with failure. - device->RequestSession( - this, std::move(runtime_options), - base::BindOnce(&VRDisplayHost::OnARSessionCreated, - weak_ptr_factory_.GetWeakPtr(), base::Unretained(device), - std::move(callback))); } else { - device->GetRuntime()->RequestMagicWindowSession( - base::BindOnce(&VRDisplayHost::OnMagicWindowSessionCreated, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::OnceCallback<void(device::mojom::XRSessionPtr, + device::mojom::XRSessionControllerPtr)> + magic_window_callback = + base::BindOnce(&VRDisplayHost::OnMagicWindowSessionCreated, + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + device->GetRuntime()->RequestSession(std::move(runtime_options), + std::move(magic_window_callback)); } }
diff --git a/chrome/browser/vr/service/vr_display_host.h b/chrome/browser/vr/service/vr_display_host.h index 2e8e9e6..e8b673e3 100644 --- a/chrome/browser/vr/service/vr_display_host.h +++ b/chrome/browser/vr/service/vr_display_host.h
@@ -73,12 +73,8 @@ bool InternalSupportsSession(device::mojom::XRSessionOptions* options); void OnMagicWindowSessionCreated( device::mojom::VRDisplayHost::RequestSessionCallback callback, - device::mojom::VRMagicWindowProviderPtr session, + device::mojom::XRSessionPtr session, device::mojom::XRSessionControllerPtr controller); - void OnARSessionCreated( - vr::BrowserXrDevice* device, - device::mojom::VRDisplayHost::RequestSessionCallback callback, - device::mojom::XRSessionPtr session); // TODO(https://crbug.com/837538): Instead, check before returning this // object.
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc index 1664f6d55..d0a4eeeb 100644 --- a/chrome/browser/vr/ui_unittest.cc +++ b/chrome/browser/vr/ui_unittest.cc
@@ -467,17 +467,15 @@ EXPECT_EQ(initial_position, content_group->LocalTransform()); } -TEST_F(UiTest, SecurityIconClickTriggersUnsupportedMode) { +TEST_F(UiTest, SecurityIconClickShouldShowPageInfo) { CreateScene(kNotInWebVr); // Initial state. VerifyOnlyElementsVisible("Initial", kElementsVisibleInBrowsing); - // Clicking on security icon should trigger unsupported mode. - EXPECT_CALL(*browser_, - OnUnsupportedMode(UiUnsupportedMode::kUnhandledPageInfo)); - browser_->OnUnsupportedMode(UiUnsupportedMode::kUnhandledPageInfo); - VerifyOnlyElementsVisible("Prompt invisible", kElementsVisibleInBrowsing); + EXPECT_CALL(*browser_, ShowPageInfo); + auto* security_icon = scene_->GetUiElementByName(kUrlBarSecurityButton); + ClickElement(security_icon); } TEST_F(UiTest, ClickingOmniboxTriggersUnsupportedMode) {
diff --git a/chrome/common/media_router/providers/cast/cast_media_source.cc b/chrome/common/media_router/providers/cast/cast_media_source.cc index 06f0047..8f97a0d 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source.cc +++ b/chrome/common/media_router/providers/cast/cast_media_source.cc
@@ -4,6 +4,7 @@ #include "chrome/common/media_router/providers/cast/cast_media_source.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -18,18 +19,19 @@ namespace { -constexpr char kMirroringAppId[] = "0F5096E8"; -constexpr char kAudioMirroringAppId[] = "85CDB22F"; - // Parameter keys used by new Cast URLs. constexpr char kCapabilitiesKey[] = "capabilities"; constexpr char kBroadcastNamespaceKey[] = "broadcastNamespace"; constexpr char kBroadcastMessageKey[] = "broadcastMessage"; +constexpr char kClientIdKey[] = "clientId"; +constexpr char kLaunchTimeoutKey[] = "launchTimeout"; // Parameter keys used by legacy Cast URLs. constexpr char kLegacyAppIdKey[] = "__castAppId__"; constexpr char kLegacyBroadcastNamespaceKey[] = "__castBroadcastNamespace__"; constexpr char kLegacyBroadcastMessageKey[] = "__castBroadcastMessage__"; +constexpr char kLegacyClientIdKey[] = "__castClientId__"; +constexpr char kLegacyLaunchTimeoutKey[] = "__castLaunchTimeout__"; // TODO(imcheng): Move to common utils? std::string DecodeURLComponent(const std::string& encoded) { @@ -61,8 +63,9 @@ std::unique_ptr<CastMediaSource> CastMediaSourceForTabMirroring( const MediaSource::Id& source_id) { return std::make_unique<CastMediaSource>( - source_id, std::vector<CastAppInfo>({CastAppInfo(kMirroringAppId), - CastAppInfo(kAudioMirroringAppId)})); + source_id, + std::vector<CastAppInfo>({CastAppInfo(kCastStreamingAppId), + CastAppInfo(kCastStreamingAudioAppId)})); } std::unique_ptr<CastMediaSource> CastMediaSourceForDesktopMirroring( @@ -70,28 +73,33 @@ // Desktop audio mirroring is only supported on some platforms. #if defined(OS_WIN) || defined(OS_CHROMEOS) return std::make_unique<CastMediaSource>( - source_id, std::vector<CastAppInfo>({CastAppInfo(kMirroringAppId), - CastAppInfo(kAudioMirroringAppId)})); + source_id, + std::vector<CastAppInfo>({CastAppInfo(kCastStreamingAppId), + CastAppInfo(kCastStreamingAudioAppId)})); #else return std::make_unique<CastMediaSource>( - source_id, std::vector<CastAppInfo>({CastAppInfo(kMirroringAppId)})); + source_id, std::vector<CastAppInfo>({CastAppInfo(kCastStreamingAppId)})); #endif } std::unique_ptr<CastMediaSource> CreateFromURLParams( const MediaSource::Id& source_id, const std::vector<CastAppInfo>& app_infos, + const std::string& client_id, const std::string& broadcast_namespace, - const std::string& broadcast_message) { + const std::string& broadcast_message, + base::TimeDelta launch_timeout) { if (app_infos.empty()) return nullptr; auto cast_source = std::make_unique<CastMediaSource>(source_id, app_infos); + cast_source->set_client_id(client_id); if (!broadcast_namespace.empty() && !broadcast_message.empty()) { cast_source->set_broadcast_request( BroadcastRequest(broadcast_namespace, broadcast_message)); } - + if (launch_timeout > base::TimeDelta()) + cast_source->set_launch_timeout(launch_timeout); return cast_source; } @@ -103,6 +111,8 @@ return nullptr; std::string broadcast_namespace, broadcast_message, capabilities; + std::string client_id; + int launch_timeout_millis = 0; for (net::QueryIterator query_it(url); !query_it.IsAtEnd(); query_it.Advance()) { std::string key = query_it.GetKey(); @@ -116,6 +126,12 @@ broadcast_message = DecodeURLComponent(value); } else if (key == kCapabilitiesKey) { capabilities = value; + } else if (key == kClientIdKey) { + client_id = value; + } else if (key == kLaunchTimeoutKey) { + if (!base::StringToInt(value, &launch_timeout_millis) || + launch_timeout_millis < 0) + launch_timeout_millis = 0; } } @@ -129,8 +145,9 @@ } } - return CreateFromURLParams(source_id, {app_info}, broadcast_namespace, - broadcast_message); + return CreateFromURLParams( + source_id, {app_info}, client_id, broadcast_namespace, broadcast_message, + base::TimeDelta::FromMilliseconds(launch_timeout_millis)); } std::unique_ptr<CastMediaSource> ParseLegacyCastUrl( @@ -141,6 +158,8 @@ // Legacy URLs can specify multiple apps. std::vector<std::string> app_id_params; std::string broadcast_namespace, broadcast_message; + std::string client_id; + int launch_timeout_millis = 0; for (const auto& key_value : parameters) { const auto& key = key_value.first; const auto& value = key_value.second; @@ -151,6 +170,12 @@ } else if (key == kLegacyBroadcastMessageKey) { // The broadcast message is URL-encoded. broadcast_message = DecodeURLComponent(value); + } else if (key == kLegacyClientIdKey) { + client_id = value; + } else if (key == kLegacyLaunchTimeoutKey) { + if (!base::StringToInt(value, &launch_timeout_millis) || + launch_timeout_millis < 0) + launch_timeout_millis = 0; } } @@ -187,8 +212,9 @@ if (app_infos.empty()) return nullptr; - return CreateFromURLParams(source_id, app_infos, broadcast_namespace, - broadcast_message); + return CreateFromURLParams( + source_id, app_infos, client_id, broadcast_namespace, broadcast_message, + base::TimeDelta::FromMilliseconds(launch_timeout_millis)); } } // namespace @@ -226,9 +252,6 @@ } CastMediaSource::CastMediaSource(const MediaSource::Id& source_id, - const CastAppInfo& app_info) - : source_id_(source_id), app_infos_({app_info}) {} -CastMediaSource::CastMediaSource(const MediaSource::Id& source_id, const std::vector<CastAppInfo>& app_infos) : source_id_(source_id), app_infos_(app_infos) {} CastMediaSource::CastMediaSource(const CastMediaSource& other) = default;
diff --git a/chrome/common/media_router/providers/cast/cast_media_source.h b/chrome/common/media_router/providers/cast/cast_media_source.h index ae090b5e2..e46b725 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source.h +++ b/chrome/common/media_router/providers/cast/cast_media_source.h
@@ -16,6 +16,16 @@ namespace media_router { +static constexpr char kCastStreamingAppId[] = "0F5096E8"; +static constexpr char kCastStreamingAudioAppId[] = "85CDB22F"; + +// Placeholder app ID advertised by the multizone leader in a receiver status +// message. +static constexpr char kMultizoneLeaderAppId[] = "MultizoneLeader"; + +static constexpr base::TimeDelta kDefaultLaunchTimeout = + base::TimeDelta::FromSeconds(60); + // Represents a Cast app and its capabilitity requirements. struct CastAppInfo { explicit CastAppInfo(const std::string& app_id); @@ -39,10 +49,8 @@ // Returns the parsed form of |source|, or nullptr if it cannot be parsed. static std::unique_ptr<CastMediaSource> From(const MediaSource::Id& source); - explicit CastMediaSource(const MediaSource::Id& source_id, - const CastAppInfo& app_info); - explicit CastMediaSource(const MediaSource::Id& source_id, - const std::vector<CastAppInfo>& app_infos); + CastMediaSource(const MediaSource::Id& source_id, + const std::vector<CastAppInfo>& app_infos); CastMediaSource(const CastMediaSource& other); ~CastMediaSource(); @@ -55,6 +63,12 @@ const MediaSource::Id& source_id() const { return source_id_; } const std::vector<CastAppInfo>& app_infos() const { return app_infos_; } + const std::string& client_id() const { return client_id_; } + void set_client_id(const std::string& client_id) { client_id_ = client_id; } + base::TimeDelta launch_timeout() const { return launch_timeout_; } + void set_launch_timeout(base::TimeDelta launch_timeout) { + launch_timeout_ = launch_timeout; + } const base::Optional<cast_channel::BroadcastRequest>& broadcast_request() const { return broadcast_request_; @@ -68,6 +82,9 @@ // TODO(imcheng): Fill in other parameters. MediaSource::Id source_id_; std::vector<CastAppInfo> app_infos_; + base::TimeDelta launch_timeout_ = kDefaultLaunchTimeout; + // Empty if not set. + std::string client_id_; base::Optional<cast_channel::BroadcastRequest> broadcast_request_; };
diff --git a/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc b/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc index 94a9204..54181fdc 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc +++ b/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc
@@ -13,7 +13,9 @@ MediaSource::Id source_id( "cast:ABCDEFAB?capabilities=video_out,audio_out" "&broadcastNamespace=namespace" - "&broadcastMessage=message"); + "&broadcastMessage=message" + "&clientId=12345" + "&launchTimeout=30000"); std::unique_ptr<CastMediaSource> source = CastMediaSource::From(source_id); ASSERT_TRUE(source); EXPECT_EQ(source_id, source->source_id()); @@ -27,13 +29,17 @@ ASSERT_TRUE(broadcast_request); EXPECT_EQ("namespace", broadcast_request->broadcast_namespace); EXPECT_EQ("message", broadcast_request->message); + EXPECT_EQ("12345", source->client_id()); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(30000), source->launch_timeout()); } TEST(CastMediaSourceTest, FromLegacyCastURL) { MediaSource::Id source_id( "https://google.com/cast#__castAppId__=ABCDEFAB(video_out,audio_out)" "/__castBroadcastNamespace__=namespace" - "/__castBroadcastMessage__=message"); + "/__castBroadcastMessage__=message" + "/__castClientId__=12345" + "/__castLaunchTimeout__=30000"); std::unique_ptr<CastMediaSource> source = CastMediaSource::From(source_id); ASSERT_TRUE(source); EXPECT_EQ(source_id, source->source_id()); @@ -47,6 +53,8 @@ ASSERT_TRUE(broadcast_request); EXPECT_EQ("namespace", broadcast_request->broadcast_namespace); EXPECT_EQ("message", broadcast_request->message); + EXPECT_EQ("12345", source->client_id()); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(30000), source->launch_timeout()); } TEST(CastMediaSourceTest, FromPresentationURL) { @@ -57,6 +65,8 @@ ASSERT_EQ(2u, source->app_infos().size()); EXPECT_EQ("0F5096E8", source->app_infos()[0].app_id); EXPECT_EQ("85CDB22F", source->app_infos()[1].app_id); + EXPECT_TRUE(source->client_id().empty()); + EXPECT_EQ(kDefaultLaunchTimeout, source->launch_timeout()); } TEST(CastMediaSourceTest, FromMirroringURN) { @@ -67,6 +77,8 @@ ASSERT_EQ(2u, source->app_infos().size()); EXPECT_EQ("0F5096E8", source->app_infos()[0].app_id); EXPECT_EQ("85CDB22F", source->app_infos()[1].app_id); + EXPECT_TRUE(source->client_id().empty()); + EXPECT_EQ(kDefaultLaunchTimeout, source->launch_timeout()); } TEST(CastMediaSourceTest, FromInvalidSource) {
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 70fddd7..d56dc0ba 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1997,11 +1997,9 @@ #endif // !defined(OS_ANDROID) #if !defined(OS_ANDROID) -#if !defined(OS_CHROMEOS) // Pref name for the policy controlling the way in which users are notified of // the need to relaunch the browser for a pending update. const char kRelaunchNotification[] = "browser.relaunch_notification"; -#endif // !defined(OS_CHROMEOS) // Pref name for the policy controlling the time period over which users are // notified of the need to relaunch the browser for a pending update. Values // are in milliseconds.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index c41685c..d2184936b 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -728,9 +728,7 @@ #endif // !defined(OS_ANDROID) #if !defined(OS_ANDROID) -#if !defined(OS_CHROMEOS) extern const char kRelaunchNotification[]; -#endif // !defined(OS_CHROMEOS) extern const char kRelaunchNotificationPeriod[]; #endif // !defined(OS_ANDROID)
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index db3480c6..2f8e1bf 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1474,6 +1474,8 @@ "../browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc", "../browser/ui/views/payments/shipping_option_view_controller_browsertest.cc", "../browser/ui/views/profiles/profile_chooser_view_browsertest.cc", + "../browser/ui/views/relaunch_notification/relaunch_recommended_bubble_view_browsertest.cc", + "../browser/ui/views/relaunch_notification/relaunch_required_dialog_view_browsertest.cc", "../browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog_browsertest.cc", "../browser/ui/views/select_file_dialog_extension_browsertest.cc", "../browser/ui/views/sync/profile_signin_confirmation_dialog_views_browsertest.cc", @@ -1527,12 +1529,6 @@ "../browser/ui/views/web_dialog_view_browsertest.cc", ] } - if (!is_chromeos) { - sources += [ - "../browser/ui/views/relaunch_notification/relaunch_recommended_bubble_view_browsertest.cc", - "../browser/ui/views/relaunch_notification/relaunch_required_dialog_view_browsertest.cc", - ] - } } if (is_linux && !is_component_build) { @@ -3205,6 +3201,7 @@ "../browser/media/router/mojo/media_sink_service_status_unittest.cc", "../browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc", "../browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc", + "../browser/media/router/providers/cast/cast_internal_message_util_unittest.cc", "../browser/media/router/providers/cast/cast_media_route_provider_metrics_unittest.cc", "../browser/media/router/providers/cast/cast_media_route_provider_unittest.cc", "../browser/media/router/providers/cast/dual_media_sink_service_unittest.cc", @@ -3472,7 +3469,6 @@ "../browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc", "../browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc", "../browser/extensions/api/signed_in_devices/signed_in_devices_manager_unittest.cc", - "../browser/extensions/api/socket/combined_socket_unittest.cc", "../browser/extensions/api/socket/socket_api_unittest.cc", "../browser/extensions/api/socket/tcp_socket_unittest.cc", "../browser/extensions/api/socket/tls_socket_unittest.cc", @@ -4168,7 +4164,6 @@ "../browser/ui/cocoa/omnibox/omnibox_popup_view_mac_unittest.mm", "../browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm", "../browser/ui/cocoa/page_info/page_info_bubble_controller_unittest.mm", - "../browser/ui/cocoa/page_info/permission_selector_button_unittest.mm", "../browser/ui/cocoa/profiles/avatar_button_controller_unittest.mm", "../browser/ui/cocoa/profiles/avatar_button_unittest.mm", "../browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm", @@ -4202,7 +4197,6 @@ "../browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm", "../browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm", "../browser/ui/cocoa/touchbar/suggested_text_touch_bar_controller_unittest.mm", - "../browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm", "../browser/ui/cocoa/url_drop_target_unittest.mm", "../browser/ui/cocoa/vertical_gradient_view_unittest.mm", "../browser/ui/cocoa/view_resizer_pong.h", @@ -4362,14 +4356,11 @@ "../browser/ui/views/payments/payment_request_item_list_unittest.cc", "../browser/ui/views/payments/validating_textfield_unittest.cc", "../browser/ui/views/payments/view_stack_unittest.cc", + "../browser/ui/views/relaunch_notification/relaunch_notification_controller_unittest.cc", + "../browser/ui/views/relaunch_notification/relaunch_required_dialog_view_unittest.cc", ] if (is_chromeos) { sources += [ "../browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc" ] - } else { - sources += [ - "../browser/ui/views/relaunch_notification/relaunch_notification_controller_unittest.cc", - "../browser/ui/views/relaunch_notification/relaunch_required_dialog_view_unittest.cc", - ] } if (!is_chromeos && (!is_mac || mac_views_browser)) { sources += [ @@ -5108,10 +5099,6 @@ # toolkit-views secondary UI. It should not be deleted with the Cocoa # bubble (but it can be deleted with the Cocoa browser window). "../browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_interactive_uitest.mm", - - # The translate bubble tests only obsolete Cocoa UI and doesn't link. - # Ensure the corresponding file is deleted when removing the next line. - # "../browser/ui/cocoa/translate/translate_bubble_test_utils_views_cocoa.mm", ] }
diff --git a/chrome/test/base/dialog_test_browser_window.cc b/chrome/test/base/dialog_test_browser_window.cc index bf88d63..d1110de3 100644 --- a/chrome/test/base/dialog_test_browser_window.cc +++ b/chrome/test/base/dialog_test_browser_window.cc
@@ -4,6 +4,7 @@ #include "chrome/test/base/dialog_test_browser_window.h" +#include "build/build_config.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -52,6 +53,10 @@ } gfx::Size DialogTestBrowserWindow::GetMaximumDialogSize() { +#if defined(OS_MACOSX) + // Zero-size windows aren't allowed on Mac. + return gfx::Size(1, 1); +#endif return gfx::Size(); }
diff --git a/chrome/test/data/extensions/api_test/socket/api/background.js b/chrome/test/data/extensions/api_test/socket/api/background.js index d093aa0..4e675fa8 100644 --- a/chrome/test/data/extensions/api_test/socket/api/background.js +++ b/chrome/test/data/extensions/api_test/socket/api/background.js
@@ -200,16 +200,16 @@ socket.read(acceptedSocketId, function(readInfo) { arrayBuffer2String(readInfo.data, function (s) { assertDataMatch(request, s); - succeeded = true; - // Test whether socket.getInfo correctly reflects the connection status - // if the peer has closed the connection. - setTimeout(function() { + // Rather than using a timeout, use another read to detect the peer + // termination. + socket.read(acceptedSocketId, function(readInfo2) { + chrome.test.assertEq(-2, readInfo2.resultCode); socket.getInfo(acceptedSocketId, function(info) { chrome.test.assertFalse(info.connected); socket.destroy(socketId); chrome.test.succeed(); }); - }, 500); + }); }); }); }
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 0383715..9dbacec 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2453,7 +2453,7 @@ }, "RelaunchNotification": { - "os": ["win", "linux", "mac"], + "os": ["win", "linux", "mac", "chromeos"], "test_policy": { "RelaunchNotification": 1 }, "pref_mappings": [ { "pref": "browser.relaunch_notification",
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 9753eec..16621e5 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -183,6 +183,8 @@ "webdata/autofill_table_encryptor_factory.h", "webdata/autofill_wallet_metadata_syncable_service.cc", "webdata/autofill_wallet_metadata_syncable_service.h", + "webdata/autofill_wallet_sync_bridge.cc", + "webdata/autofill_wallet_sync_bridge.h", "webdata/autofill_wallet_syncable_service.cc", "webdata/autofill_wallet_syncable_service.h", "webdata/autofill_webdata.h",
diff --git a/components/autofill/core/browser/webdata/OWNERS b/components/autofill/core/browser/webdata/OWNERS new file mode 100644 index 0000000..7385936a --- /dev/null +++ b/components/autofill/core/browser/webdata/OWNERS
@@ -0,0 +1 @@ +per-file *sync_bridge*=jkrcal@chromium.org
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc new file mode 100644 index 0000000..3296c81 --- /dev/null +++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
@@ -0,0 +1,90 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h" + +#include <utility> + +#include "base/logging.h" +#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#include "components/sync/model_impl/client_tag_based_model_type_processor.h" + +namespace autofill { + +namespace { + +// Address to this variable used as the user data key. +static int kAutofillWalletSyncBridgeUserDataKey = 0; + +} // namespace + +// static +void AutofillWalletSyncBridge::CreateForWebDataServiceAndBackend( + const std::string& app_locale, + AutofillWebDataBackend* web_data_backend, + AutofillWebDataService* web_data_service) { + web_data_service->GetDBUserData()->SetUserData( + &kAutofillWalletSyncBridgeUserDataKey, + std::make_unique<AutofillWalletSyncBridge>( + std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( + syncer::AUTOFILL_WALLET_DATA, + /*dump_stack=*/base::RepeatingClosure()))); +} + +// static +syncer::ModelTypeSyncBridge* AutofillWalletSyncBridge::FromWebDataService( + AutofillWebDataService* web_data_service) { + return static_cast<AutofillWalletSyncBridge*>( + web_data_service->GetDBUserData()->GetUserData( + &kAutofillWalletSyncBridgeUserDataKey)); +} + +AutofillWalletSyncBridge::AutofillWalletSyncBridge( + std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor) + : ModelTypeSyncBridge(std::move(change_processor)) {} + +AutofillWalletSyncBridge::~AutofillWalletSyncBridge() {} + +std::unique_ptr<syncer::MetadataChangeList> +AutofillWalletSyncBridge::CreateMetadataChangeList() { + NOTIMPLEMENTED(); + return nullptr; +} + +base::Optional<syncer::ModelError> AutofillWalletSyncBridge::MergeSyncData( + std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, + syncer::EntityChangeList entity_data) { + return ApplySyncChanges(std::move(metadata_change_list), + std::move(entity_data)); +} + +base::Optional<syncer::ModelError> AutofillWalletSyncBridge::ApplySyncChanges( + std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, + syncer::EntityChangeList entity_data) { + NOTIMPLEMENTED(); + return base::nullopt; +} + +void AutofillWalletSyncBridge::GetData(StorageKeyList storage_keys, + DataCallback callback) { + NOTIMPLEMENTED(); +} + +void AutofillWalletSyncBridge::GetAllDataForDebugging(DataCallback callback) { + NOTIMPLEMENTED(); +} + +std::string AutofillWalletSyncBridge::GetClientTag( + const syncer::EntityData& entity_data) { + NOTIMPLEMENTED(); + return ""; +} + +std::string AutofillWalletSyncBridge::GetStorageKey( + const syncer::EntityData& entity_data) { + NOTIMPLEMENTED(); + return ""; +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h new file mode 100644 index 0000000..6037895 --- /dev/null +++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
@@ -0,0 +1,63 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WALLET_SYNC_BRIDGE_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WALLET_SYNC_BRIDGE_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/supports_user_data.h" +#include "components/sync/model/metadata_change_list.h" +#include "components/sync/model/model_error.h" +#include "components/sync/model/model_type_change_processor.h" +#include "components/sync/model/model_type_sync_bridge.h" + +namespace autofill { + +class AutofillWebDataBackend; +class AutofillWebDataService; + +// Sync bridge responsible for propagating local changes to the processor and +// applying remote changes to the local database. +class AutofillWalletSyncBridge : public base::SupportsUserData::Data, + public syncer::ModelTypeSyncBridge { + public: + // Factory method that hides dealing with change_processor and also stores the + // created bridge within |web_data_service|. This method should only be + // called on |web_data_service|'s DB thread. + static void CreateForWebDataServiceAndBackend( + const std::string& app_locale, + AutofillWebDataBackend* webdata_backend, + AutofillWebDataService* web_data_service); + + static syncer::ModelTypeSyncBridge* FromWebDataService( + AutofillWebDataService* web_data_service); + + explicit AutofillWalletSyncBridge( + std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor); + ~AutofillWalletSyncBridge() override; + + // ModelTypeSyncBridge implementation. + std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList() + override; + base::Optional<syncer::ModelError> MergeSyncData( + std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, + syncer::EntityChangeList entity_data) override; + base::Optional<syncer::ModelError> ApplySyncChanges( + std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, + syncer::EntityChangeList entity_changes) override; + void GetData(StorageKeyList storage_keys, DataCallback callback) override; + void GetAllDataForDebugging(DataCallback callback) override; + std::string GetClientTag(const syncer::EntityData& entity_data) override; + std::string GetStorageKey(const syncer::EntityData& entity_data) override; + + private: + DISALLOW_COPY_AND_ASSIGN(AutofillWalletSyncBridge); +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WALLET_SYNC_BRIDGE_H_
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc index 0cec2e2..713f268 100644 --- a/components/browser_sync/profile_sync_components_factory_impl.cc +++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -14,6 +14,7 @@ #include "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h" #include "components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h" #include "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h" +#include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/browser/webdata/web_data_model_type_controller.h" #include "components/browser_sync/browser_sync_switches.h" @@ -151,9 +152,18 @@ // enforced by the datatype controller. Register unless explicitly disabled. bool wallet_disabled = disabled_types.Has(syncer::AUTOFILL_WALLET_DATA); if (!wallet_disabled) { - controllers.push_back(std::make_unique<AutofillWalletDataTypeController>( - syncer::AUTOFILL_WALLET_DATA, db_thread_, error_callback, - sync_client_, web_data_service_)); + if (base::FeatureList::IsEnabled(switches::kSyncUSSAutofillWalletData)) { + controllers.push_back( + std::make_unique<autofill::WebDataModelTypeController>( + syncer::AUTOFILL_WALLET_DATA, sync_client_, db_thread_, + web_data_service_, + base::BindRepeating(&AutofillProfileDelegateFromDataService))); + } else { + controllers.push_back( + std::make_unique<AutofillWalletDataTypeController>( + syncer::AUTOFILL_WALLET_DATA, db_thread_, error_callback, + sync_client_, web_data_service_)); + } } // Wallet metadata sync depends on Wallet data sync. Register if Wallet data
diff --git a/components/cast_channel/cast_message_util.cc b/components/cast_channel/cast_message_util.cc index 011ec8e..790c73c 100644 --- a/components/cast_channel/cast_message_util.cc +++ b/components/cast_channel/cast_message_util.cc
@@ -34,13 +34,14 @@ constexpr char kTypeNodeId[] = "type"; constexpr char kRequestIdNodeId[] = "requestId"; -// Cast application protocol message types. +// Cast application protocol message types. Keep in sync with CastMessageType. constexpr char kKeepAlivePingType[] = "PING"; constexpr char kKeepAlivePongType[] = "PONG"; constexpr char kGetAppAvailabilityRequestType[] = "GET_APP_AVAILABILITY"; constexpr char kConnectionRequestType[] = "CONNECT"; constexpr char kBroadcastRequestType[] = "APPLICATION_BROADCAST"; constexpr char kLaunchRequestType[] = "LAUNCH"; +constexpr char kStopRequestType[] = "STOP"; constexpr char kReceiverStatusType[] = "RECEIVER_STATUS"; constexpr char kLaunchErrorType[] = "LAUNCH_ERROR"; @@ -107,6 +108,7 @@ if (!message.has_payload_utf8()) return nullptr; + // TODO(https://crbug.com/809249): Parse JSON using data_decoder service. return base::DictionaryValue::From( base::JSONReader::Read(message.payload_utf8())); } @@ -146,6 +148,8 @@ return kBroadcastRequestType; case CastMessageType::kLaunch: return kLaunchRequestType; + case CastMessageType::kStop: + return kStopRequestType; case CastMessageType::kReceiverStatus: return kReceiverStatusType; case CastMessageType::kLaunchError: @@ -170,6 +174,8 @@ return CastMessageType::kBroadcast; if (type == kLaunchRequestType) return CastMessageType::kLaunch; + if (type == kStopRequestType) + return CastMessageType::kStop; if (type == kReceiverStatusType) return CastMessageType::kReceiverStatus; if (type == kLaunchErrorType) @@ -347,6 +353,17 @@ kPlatformReceiverId); } +CastMessage CreateStopRequest(const std::string& source_id, + int request_id, + const std::string& session_id) { + Value dict(Value::Type::DICTIONARY); + dict.SetKey(kTypeNodeId, Value(kStopRequestType)); + dict.SetKey(kRequestIdNodeId, Value(request_id)); + dict.SetKey("sessionId", Value(session_id)); + return CreateCastMessage(kReceiverNamespace, dict, source_id, + kPlatformReceiverId); +} + CastMessage CreateCastMessage(const std::string& message_namespace, const base::Value& message, const std::string& source_id, @@ -406,8 +423,7 @@ default; LaunchSessionResponse::~LaunchSessionResponse() = default; -LaunchSessionResponse GetLaunchSessionResponse( - const base::DictionaryValue& payload) { +LaunchSessionResponse GetLaunchSessionResponse(const base::Value& payload) { const Value* type_value = payload.FindKeyOfType(kTypeNodeId, Value::Type::STRING); if (!type_value)
diff --git a/components/cast_channel/cast_message_util.h b/components/cast_channel/cast_message_util.h index aedf0bc..c854352 100644 --- a/components/cast_channel/cast_message_util.h +++ b/components/cast_channel/cast_message_util.h
@@ -27,6 +27,7 @@ kConnect, // Virtual connection request kBroadcast, // Application broadcast / precache kLaunch, // Session launch request + kStop, // Session stop request kReceiverStatus, kLaunchError, kOther // Add new types above |kOther|. @@ -132,6 +133,10 @@ const std::string& app_id, const std::string& locale); +CastMessage CreateStopRequest(const std::string& source_id, + int request_id, + const std::string& session_id); + // Creates a generic CastMessage with |message| as the string payload. Used for // app messages. CastMessage CreateCastMessage(const std::string& message_namespace, @@ -168,16 +173,15 @@ ~LaunchSessionResponse(); Result result = Result::kUnknown; - // Populated if |result| is |kOk|. base::Optional<base::Value> receiver_status; }; // Parses |payload| into a LaunchSessionResponse. Returns an empty // LaunchSessionResponse if |payload| is not a properly formatted launch -// response. |payload| must be from the string payload of a CastMessage. -LaunchSessionResponse GetLaunchSessionResponse( - const base::DictionaryValue& payload); +// response. |payload| must be a dictionary from the string payload of a +// CastMessage. +LaunchSessionResponse GetLaunchSessionResponse(const base::Value& payload); } // namespace cast_channel
diff --git a/components/cast_channel/cast_message_util_unittest.cc b/components/cast_channel/cast_message_util_unittest.cc index 9fdbfa8..8e629cfd 100644 --- a/components/cast_channel/cast_message_util_unittest.cc +++ b/components/cast_channel/cast_message_util_unittest.cc
@@ -6,6 +6,7 @@ #include "base/json/json_reader.h" #include "base/values.h" +#include "components/cast_channel/proto/cast_channel.pb.h" #include "testing/gtest/include/gtest/gtest.h" namespace cast_channel { @@ -34,8 +35,7 @@ } )"; - std::unique_ptr<base::DictionaryValue> value = - base::DictionaryValue::From(base::JSONReader::Read(payload)); + std::unique_ptr<base::Value> value = base::JSONReader::Read(payload); ASSERT_TRUE(value); LaunchSessionResponse response = GetLaunchSessionResponse(*value); @@ -51,8 +51,7 @@ } )"; - std::unique_ptr<base::DictionaryValue> value = - base::DictionaryValue::From(base::JSONReader::Read(payload)); + std::unique_ptr<base::Value> value = base::JSONReader::Read(payload); ASSERT_TRUE(value); LaunchSessionResponse response = GetLaunchSessionResponse(*value); @@ -70,8 +69,7 @@ } )"; - std::unique_ptr<base::DictionaryValue> value = - base::DictionaryValue::From(base::JSONReader::Read(payload)); + std::unique_ptr<base::Value> value = base::JSONReader::Read(payload); ASSERT_TRUE(value); LaunchSessionResponse response = GetLaunchSessionResponse(*value); @@ -79,4 +77,26 @@ EXPECT_FALSE(response.receiver_status); } +TEST(CastMessageUtilTest, CreateStopRequest) { + std::string expected_message = R"( + { + "type": "STOP", + "requestId": 123, + "sessionId": "sessionId" + } + )"; + + std::unique_ptr<base::Value> expected_value = + base::JSONReader::Read(expected_message); + ASSERT_TRUE(expected_value); + + CastMessage message = CreateStopRequest("sourceId", 123, "sessionId"); + ASSERT_TRUE(IsCastMessageValid(message)); + + std::unique_ptr<base::Value> actual_value = + base::JSONReader::Read(message.payload_utf8()); + ASSERT_TRUE(actual_value); + EXPECT_EQ(*expected_value, *actual_value); +} + } // namespace cast_channel
diff --git a/components/consent_auditor/consent_auditor.h b/components/consent_auditor/consent_auditor.h index 30e61ac..fa62710d 100644 --- a/components/consent_auditor/consent_auditor.h +++ b/components/consent_auditor/consent_auditor.h
@@ -31,7 +31,7 @@ GOOGLE_LOCATION_SERVICE = 3, CHROME_UNIFIED_CONSENT = 4, - FEATURE_LAST = GOOGLE_LOCATION_SERVICE + FEATURE_LAST = CHROME_UNIFIED_CONSENT }; // Whether a consent is given or not given.
diff --git a/components/consent_auditor/consent_sync_bridge_impl.cc b/components/consent_auditor/consent_sync_bridge_impl.cc index 05c60ed..264f32cb 100644 --- a/components/consent_auditor/consent_sync_bridge_impl.cc +++ b/components/consent_auditor/consent_sync_bridge_impl.cc
@@ -51,16 +51,6 @@ return entity_data; } -// TODO(vitaliii): Delete this function both here and in UserEventSyncBridge. -std::unique_ptr<EntityData> CopyToEntityData( - const UserConsentSpecifics specifics) { - auto entity_data = std::make_unique<EntityData>(); - entity_data->non_unique_name = - base::Int64ToString(specifics.client_consent_time_usec()); - *entity_data->specifics.mutable_user_consent() = specifics; - return entity_data; -} - } // namespace ConsentSyncBridgeImpl::ConsentSyncBridgeImpl( @@ -296,11 +286,12 @@ } auto batch = std::make_unique<MutableDataBatch>(); - UserConsentSpecifics specifics; for (const Record& r : *data_records) { - if (specifics.ParseFromString(r.value)) { - DCHECK_EQ(r.id, GetStorageKeyFromSpecifics(specifics)); - batch->Put(r.id, CopyToEntityData(specifics)); + auto specifics = std::make_unique<UserConsentSpecifics>(); + + if (specifics->ParseFromString(r.value)) { + DCHECK_EQ(r.id, GetStorageKeyFromSpecifics(*specifics)); + batch->Put(r.id, MoveToEntityData(std::move(specifics))); } else { change_processor()->ReportError( {FROM_HERE, "Failed deserializing user events."});
diff --git a/components/password_manager/core/browser/password_bubble_experiment.cc b/components/password_manager/core/browser/password_bubble_experiment.cc index 3c446d4..27022f7a 100644 --- a/components/password_manager/core/browser/password_bubble_experiment.cc +++ b/components/password_manager/core/browser/password_bubble_experiment.cc
@@ -60,9 +60,14 @@ bool ShouldShowChromeSignInPasswordPromo( PrefService* prefs, const syncer::SyncService* sync_service) { - if (!sync_service || !sync_service->IsSyncAllowed() || - sync_service->IsFirstSetupComplete()) + if (!sync_service || + sync_service->HasDisableReason( + syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE) || + sync_service->HasDisableReason( + syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY) || + sync_service->IsFirstSetupComplete()) { return false; + } // Don't show the promo more than 3 times. constexpr int kThreshold = 3; return !prefs->GetBoolean(
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index 3482396..8f58dadd 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -150,8 +150,7 @@ true /* should_migrate_http_passwords */, true /* should_query_suppressed_https_forms */)), form_fetcher_(form_fetcher ? form_fetcher : owned_form_fetcher_.get()), - votes_uploader_(client, observed_form.IsPossibleChangePasswordForm()), - is_main_frame_secure_(client->IsMainFrameSecure()) { + votes_uploader_(client, observed_form.IsPossibleChangePasswordForm()) { // Non-HTML forms should not need any interaction with the renderer, and hence // no driver. Note that cloned PasswordFormManager instances can have HTML // forms without drivers as well. @@ -625,17 +624,14 @@ // Look for the actually submitted credentials in the list of previously saved // credentials that were available to autofilling. - // This first match via FindBestSavedMatch focuses on matches by username and - // falls back to password based matches if |submitted_form_| has no username - // filled. const PasswordForm* saved_form = FindBestSavedMatch(submitted_form_.get()); - if (saved_form != nullptr) { + if (saved_form) { // The user signed in with a login we autofilled. pending_credentials_ = *saved_form; SetPasswordOverridden(pending_credentials_.password_value != password_to_save.first); - if (IsPendingCredentialsPublicSuffixMatch()) { + if (pending_credentials_.is_public_suffix_match) { // If the autofilled credentials were a PSL match or credentials stored // from Android apps, store a copy with the current origin and signon // realm. This ensures that on the next visit, a precise match is found. @@ -647,10 +643,6 @@ // If this isn't updated, then password generation uploads are off for // sites where PSL matching is required to fill the login form, as two // PASSWORD votes are uploaded per saved password instead of one. - // - // TODO(gcasto): It would be nice if other state were shared such that if - // say a password was updated on one match it would update on all related - // passwords. This is a much larger change. UpdateMetadataForUsage(&pending_credentials_); // Update |pending_credentials_| in order to be able correctly save it. @@ -667,8 +659,7 @@ // actually correspond to two different accounts (see // http://crbug.com/385619). In that case the user should be asked again // before saving the password. This is ensured by setting - // |password_overriden_| on |pending_credentials_| to false and setting - // |origin| and |signon_realm| to correct values. + // |password_overriden_| on |pending_credentials_| to false. // // There is still the edge case when the autofilled credentials represent // the same account as |submitted_form_| but the stored password @@ -746,14 +737,8 @@ } } - if (!IsValidAndroidFacetURI(pending_credentials_.signon_realm)) { + if (!IsValidAndroidFacetURI(pending_credentials_.signon_realm)) pending_credentials_.action = submitted_form_->action; - // If the user selected credentials we autofilled from a PasswordForm - // that contained no action URL (IE6/7 imported passwords, for example), - // bless it with the action URL from the observed form. See b/1107719. - if (pending_credentials_.action.is_empty()) - pending_credentials_.action = observed_form_.action; - } pending_credentials_.password_value = password_to_save.first; pending_credentials_.preferred = submitted_form_->preferred; @@ -771,7 +756,9 @@ pending_credentials_.display_name = submitted_form_->display_name; pending_credentials_.federation_origin = submitted_form_->federation_origin; pending_credentials_.icon_url = submitted_form_->icon_url; - // Take the correct signon_realm for federated credentials. + // It's important to override |signon_realm| for federated credentials + // because it has format "federation://" + origin_host + "/" + + // federation_host pending_credentials_.signon_realm = submitted_form_->signon_realm; }
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h index 547c462..339b764 100644 --- a/components/password_manager/core/browser/password_form_manager.h +++ b/components/password_manager/core/browser/password_form_manager.h
@@ -437,10 +437,6 @@ VotesUploader votes_uploader_; - // True if the main frame's visible URL, at the time this PasswordFormManager - // was created, is secure. - bool is_main_frame_secure_ = false; - // Takes care of recording metrics and events for this PasswordFormManager. // Make sure to call Init before using |*this|, to ensure it is not null. scoped_refptr<PasswordFormMetricsRecorder> metrics_recorder_;
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index 437840a..7322313 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -71,11 +71,17 @@ // selection, rather than autofilling on page load, with highlighting of fields. const base::Feature kFillOnAccountSelect = {"fill-on-account-select", base::FEATURE_DISABLED_BY_DEFAULT}; -// Enables new password form parsing mechanism, details in -// go/new-cpm-design-refactoring. + +// Enables new password form parsing mechanism for filling passwords, details in +// https://goo.gl/QodPH1 const base::Feature kNewPasswordFormParsing = { "new-password-form-parsing", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables new password form parsing mechanism for saving passwords, details in +// https://goo.gl/QodPH1 +const base::Feature kNewPasswordFormParsingForSaving = { + "new-password-form-parsing-for-saving", base::FEATURE_DISABLED_BY_DEFAULT}; + // Field trial identifier for password generation requirements. const char* kGenerationRequirementsFieldTrial = "PasswordGenerationRequirements";
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h index cc59717..7eb1bf2 100644 --- a/components/password_manager/core/common/password_manager_features.h +++ b/components/password_manager/core/common/password_manager_features.h
@@ -26,6 +26,7 @@ extern const base::Feature kShowAllSavedPasswordsContextMenu; extern const base::Feature kFillOnAccountSelect; extern const base::Feature kNewPasswordFormParsing; +extern const base::Feature kNewPasswordFormParsingForSaving; extern const base::Feature kPasswordExport; extern const base::Feature kPasswordImport; extern const base::Feature kPasswordSearchMobile;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index c147691..b31014e6 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -11651,7 +11651,7 @@ 'dynamic_refresh': True, 'per_profile': False, }, - 'supported_on': ['chrome.*:66-'], + 'supported_on': ['chrome.*:66-', 'chrome_os:70-'], 'type': 'int-enum', 'schema': { 'type': 'integer',
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index 24152e3..1766d58 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -858,6 +858,7 @@ "engine/ui_model_worker_unittest.cc", "engine_impl/apply_control_data_updates_unittest.cc", "engine_impl/backoff_delay_provider_unittest.cc", + "engine_impl/cycle/data_type_debug_info_emitter_unittest.cc", "engine_impl/cycle/nudge_tracker_unittest.cc", "engine_impl/cycle/status_controller_unittest.cc", "engine_impl/debug_info_event_listener_unittest.cc",
diff --git a/components/sync/PRESUBMIT.py b/components/sync/PRESUBMIT.py index bca86cb..0d138565 100644 --- a/components/sync/PRESUBMIT.py +++ b/components/sync/PRESUBMIT.py
@@ -48,7 +48,7 @@ # Start and end regexes for finding the EntitySpecifics definition in # sync.proto. -PROTO_DEFINITION_START_PATTERN = '^message EntitySpecifics' +PROTO_DEFINITION_START_PATTERN = '^ oneof specifics_variant \{' PROTO_DEFINITION_END_PATTERN = '^\}' # Start and end regexes for finding the ModelTypeInfoMap definition @@ -60,6 +60,7 @@ # model_type.cc is where the ModelTypeInfoMap is # sync.proto is where the proto definitions for ModelTypes are. PROTO_FILE_PATH = './protocol/sync.proto' +PROTO_FILE_NAME = 'sync.proto' MODEL_TYPE_FILE_NAME = 'model_type.cc' SYNC_SOURCE_FILES = (r'^components[\\/]sync[\\/].*\.(cc|h)$',) @@ -214,12 +215,11 @@ if '//' in line or len(split_proto_line) < 3: continue - field_typename = split_proto_line[1] - field_identifier = split_proto_line[2] + field_typename = split_proto_line[0] + field_identifier = split_proto_line[1] proto_field_definitions[field_typename] = field_identifier return proto_field_definitions - def StripTrailingS(string): return string.rstrip('sS') @@ -384,8 +384,9 @@ results = [] results += CheckChangeLintsClean(input_api, output_api) for f in input_api.AffectedFiles(): - if f.LocalPath().endswith(MODEL_TYPE_FILE_NAME): - return CheckModelTypeInfoMap(input_api, output_api, f) + if (f.LocalPath().endswith(MODEL_TYPE_FILE_NAME) or + f.LocalPath().endswith(PROTO_FILE_NAME)): + results += CheckModelTypeInfoMap(input_api, output_api, f) return results def CheckChangeOnUpload(input_api, output_api):
diff --git a/components/sync/PRESUBMIT_test.py b/components/sync/PRESUBMIT_test.py index 6164a18a..df563a0 100755 --- a/components/sync/PRESUBMIT_test.py +++ b/components/sync/PRESUBMIT_test.py
@@ -70,16 +70,19 @@ # test presubmit parsing of EntitySpecifics definition in that file. MOCK_PROTOFILE_CONTENTS = ('\n' 'message EntitySpecifics {\n' - '//comment\n' + ' //comment\n' '\n' - 'optional AutofillSpecifics autofill = 123;\n' - 'optional AppSpecifics app = 456;\n' - 'optional AppSettingSpecifics app_setting = 789;\n' - 'optional ExtensionSettingSpecifics extension_setting = 910;\n' - 'optional ManagedUserSharedSettingSpecifics managed_user_shared_setting' + ' oneof specifics_variant {\n' + ' AutofillSpecifics autofill = 123;\n' + ' AppSpecifics app = 456;\n' + ' AppSettingSpecifics app_setting = 789;\n' + ' ExtensionSettingSpecifics extension_setting = 910;\n' + ' ManagedUserSharedSettingSpecifics managed_user_shared_setting' ' = 915;\n' - '//comment\n' - '}\n') + ' //comment\n' + ' }\n' + '}\n' + ) # Format string used as the contents of a mock model_type.cc
diff --git a/components/sync/base/data_type_histogram.cc b/components/sync/base/data_type_histogram.cc index 18546e4..42b8b34a 100644 --- a/components/sync/base/data_type_histogram.cc +++ b/components/sync/base/data_type_histogram.cc
@@ -11,9 +11,7 @@ void SyncRecordMemoryKbHistogram(const std::string& histogram_name_prefix, syncer::ModelType model_type, size_t value) { - std::string type_string; - if (RealModelTypeToNotificationType(model_type, &type_string)) { - std::string full_histogram_name = histogram_name_prefix + type_string; - base::UmaHistogramCounts1M(full_histogram_name, value / 1024); - } + std::string type_string = ModelTypeToHistogramSuffix(model_type); + std::string full_histogram_name = histogram_name_prefix + type_string; + base::UmaHistogramCounts1M(full_histogram_name, value / 1024); }
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h index 7903bba9..ea9a153 100644 --- a/components/sync/base/model_type.h +++ b/components/sync/base/model_type.h
@@ -331,10 +331,14 @@ // TODO(sync): The functions below badly need some cleanup. -// Returns a pointer to a string with application lifetime that represents -// the name of |model_type|. +// Returns a string with application lifetime that represents the name of +// |model_type|. const char* ModelTypeToString(ModelType model_type); +// Returns a string with application lifetime that is used as the histogram +// suffix for |model_type|. +const char* ModelTypeToHistogramSuffix(ModelType model_type); + // Some histograms take an integer parameter that represents a model type. // The mapping from ModelType to integer is defined here. It should match the // mapping from integer to labels defined in histograms.xml.
diff --git a/components/sync/driver/sync_driver_switches.cc b/components/sync/driver/sync_driver_switches.cc index e409510..697cd0f 100644 --- a/components/sync/driver/sync_driver_switches.cc +++ b/components/sync/driver/sync_driver_switches.cc
@@ -74,4 +74,8 @@ const base::Feature kSyncUSSAutofillProfile{"SyncUSSAutofillProfile", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enable USS implementation of autofill wallet datatype. +const base::Feature kSyncUSSAutofillWalletData{ + "SyncUSSAutofillWalletData", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace switches
diff --git a/components/sync/driver/sync_driver_switches.h b/components/sync/driver/sync_driver_switches.h index 77c3e17..b01df2b2 100644 --- a/components/sync/driver/sync_driver_switches.h +++ b/components/sync/driver/sync_driver_switches.h
@@ -29,6 +29,7 @@ extern const base::Feature kSyncUSSBookmarks; extern const base::Feature kSyncUSSSessions; extern const base::Feature kSyncUSSAutofillProfile; +extern const base::Feature kSyncUSSAutofillWalletData; } // namespace switches
diff --git a/components/sync/driver/sync_service.cc b/components/sync/driver/sync_service.cc index 2ec82a3..e04efc7 100644 --- a/components/sync/driver/sync_service.cc +++ b/components/sync/driver/sync_service.cc
@@ -17,11 +17,6 @@ return GetDisableReasons() == DISABLE_REASON_NONE; } -bool SyncService::IsSyncAllowed() const { - return !HasDisableReason(DISABLE_REASON_PLATFORM_OVERRIDE) && - !HasDisableReason(DISABLE_REASON_ENTERPRISE_POLICY); -} - bool SyncService::IsEngineInitialized() const { switch (GetState()) { case State::DISABLED:
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h index d7922988..3d270305 100644 --- a/components/sync/driver/sync_service.h +++ b/components/sync/driver/sync_service.h
@@ -187,11 +187,6 @@ bool IsEngineInitialized() const; // DEPRECATED! Use GetDisableReasons/HasDisableReason instead. - // Equivalent to "!HasDisableReason(DISABLE_REASON_PLATFORM_OVERRIDE) && - // !HasDisableReason(DISABLE_REASON_ENTERPRISE_POLICY)". - bool IsSyncAllowed() const; - - // DEPRECATED! Use GetDisableReasons/HasDisableReason instead. // Equivalent to having no disable reasons, i.e. // "GetDisableReasons() == DISABLE_REASON_NONE". bool CanSyncStart() const;
diff --git a/components/sync/engine_impl/cycle/data_type_debug_info_emitter.cc b/components/sync/engine_impl/cycle/data_type_debug_info_emitter.cc index 68c3a17..93bc48b 100644 --- a/components/sync/engine_impl/cycle/data_type_debug_info_emitter.cc +++ b/components/sync/engine_impl/cycle/data_type_debug_info_emitter.cc
@@ -4,14 +4,64 @@ #include "components/sync/engine_impl/cycle/data_type_debug_info_emitter.h" +#include <string> + +#include "base/metrics/histogram.h" #include "components/sync/engine/cycle/type_debug_info_observer.h" namespace syncer { +namespace { + +const char kModelTypeEntityChangeHistogramPrefix[] = + "Sync.ModelTypeEntityChange."; + +// Values corrospond to a UMA histogram, do not modify, or delete any values. +// Add new values only directly before COUNT. +enum ModelTypeEntityChange { + LOCAL_DELETION = 0, + LOCAL_CREATION = 1, + LOCAL_UPDATE = 2, + REMOTE_DELETION = 3, + REMOTE_UPDATE = 4, + MODEL_TYPE_ENTITY_CHANGE_COUNT = 5 +}; + +void EmitNewChangesToUma(int count, + ModelTypeEntityChange bucket, + base::HistogramBase* histogram) { + DCHECK_GE(count, 0); + if (count > 0) { + histogram->AddCount(bucket, count); + } +} + +// We'll add many values in this histogram. Since the name of the histogram is +// not static here, we cannot use the (efficient) macros that use caching of the +// histogram object. The helper functions like UmaHistogramEnumeration are not +// efficient and thus we need re-implement the code here, caching the resulting +// histogram object. +base::HistogramBase* GetModelTypeEntityChangeHistogram(ModelType type) { + std::string type_string = ModelTypeToHistogramSuffix(type); + std::string full_histogram_name = + kModelTypeEntityChangeHistogramPrefix + type_string; + return base::LinearHistogram::FactoryGet( + /*name=*/full_histogram_name, /*minimum=*/1, + /*maximum=*/MODEL_TYPE_ENTITY_CHANGE_COUNT, + /*bucket_count=*/MODEL_TYPE_ENTITY_CHANGE_COUNT + 1, + /*flagz=*/base::HistogramBase::kUmaTargetedHistogramFlag); +} + +} // namespace + DataTypeDebugInfoEmitter::DataTypeDebugInfoEmitter( ModelType type, base::ObserverList<TypeDebugInfoObserver>* observers) - : type_(type), type_debug_info_observers_(observers) {} + : type_(type), + type_debug_info_observers_(observers), + histogram_(GetModelTypeEntityChangeHistogram(type)) { + DCHECK(histogram_); +} DataTypeDebugInfoEmitter::~DataTypeDebugInfoEmitter() {} @@ -26,6 +76,23 @@ void DataTypeDebugInfoEmitter::EmitCommitCountersUpdate() { for (auto& observer : *type_debug_info_observers_) observer.OnCommitCountersUpdated(type_, commit_counters_); + + // Emit the newly added counts to UMA. + EmitNewChangesToUma( + /*count=*/commit_counters_.num_creation_commits_attempted - + emitted_commit_counters_.num_creation_commits_attempted, + /*bucket=*/LOCAL_CREATION, histogram_); + EmitNewChangesToUma( + /*count=*/commit_counters_.num_deletion_commits_attempted - + emitted_commit_counters_.num_deletion_commits_attempted, + /*bucket=*/LOCAL_DELETION, histogram_); + EmitNewChangesToUma( + /*count=*/commit_counters_.num_update_commits_attempted - + emitted_commit_counters_.num_update_commits_attempted, + /*bucket=*/LOCAL_UPDATE, histogram_); + + // Mark the current state of the counters as uploaded to UMA. + emitted_commit_counters_ = commit_counters_; } const UpdateCounters& DataTypeDebugInfoEmitter::GetUpdateCounters() const { @@ -39,6 +106,27 @@ void DataTypeDebugInfoEmitter::EmitUpdateCountersUpdate() { for (auto& observer : *type_debug_info_observers_) observer.OnUpdateCountersUpdated(type_, update_counters_); + + // Emit the newly added counts to UMA. + EmitNewChangesToUma( + /*count=*/update_counters_.num_tombstone_updates_received - + emitted_update_counters_.num_tombstone_updates_received, + /*bucket=*/REMOTE_DELETION, histogram_); + // The REMOTE_UPDATE type is not explicitly stored, we need to compute it as a + // diff of (all - deletions). + int emitted_remote_updates_count = + emitted_update_counters_.num_updates_received - + emitted_update_counters_.num_tombstone_updates_received; + int remote_updates_count = update_counters_.num_updates_received - + update_counters_.num_tombstone_updates_received; + EmitNewChangesToUma( + /*count=*/remote_updates_count - emitted_remote_updates_count, + /*bucket=*/REMOTE_UPDATE, histogram_); + + // Mark the current state of the counters as uploaded to UMA. + emitted_update_counters_ = update_counters_; } +void DataTypeDebugInfoEmitter::EmitStatusCountersUpdate() {} + } // namespace syncer
diff --git a/components/sync/engine_impl/cycle/data_type_debug_info_emitter.h b/components/sync/engine_impl/cycle/data_type_debug_info_emitter.h index e49be1b6..2aac422 100644 --- a/components/sync/engine_impl/cycle/data_type_debug_info_emitter.h +++ b/components/sync/engine_impl/cycle/data_type_debug_info_emitter.h
@@ -13,6 +13,10 @@ #include "components/sync/engine/cycle/commit_counters.h" #include "components/sync/engine/cycle/update_counters.h" +namespace base { +class HistogramBase; +} + namespace syncer { class TypeDebugInfoObserver; @@ -55,8 +59,10 @@ // Triggers an update counters update to registered observers. void EmitUpdateCountersUpdate(); - // Triggers a status counters update to registered observers. - virtual void EmitStatusCountersUpdate() = 0; + // Triggers a status counters update to registered observers. The default + // implementation does nothing and is present only to make this class + // non-abstract and thus unit-testable. + virtual void EmitStatusCountersUpdate(); protected: const ModelType type_; @@ -68,9 +74,20 @@ base::ObserverList<TypeDebugInfoObserver>* type_debug_info_observers_; private: + // The actual up-to-date counters. CommitCounters commit_counters_; UpdateCounters update_counters_; + // The last state of the counters emitted to UMA. In the next round of + // emitting to UMA, we only need to upload the diff between the actual + // counters and the counts here. + CommitCounters emitted_commit_counters_; + UpdateCounters emitted_update_counters_; + + // The histogram to record to; cached for efficiency because many histogram + // entries are recorded in this object during run-time. + base::HistogramBase* const histogram_; + DISALLOW_COPY_AND_ASSIGN(DataTypeDebugInfoEmitter); };
diff --git a/components/sync/engine_impl/cycle/data_type_debug_info_emitter_unittest.cc b/components/sync/engine_impl/cycle/data_type_debug_info_emitter_unittest.cc new file mode 100644 index 0000000..68cc6f7 --- /dev/null +++ b/components/sync/engine_impl/cycle/data_type_debug_info_emitter_unittest.cc
@@ -0,0 +1,131 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync/engine_impl/cycle/data_type_debug_info_emitter.h" + +#include "base/test/metrics/histogram_tester.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace syncer { +namespace { + +TEST(DataTypeDebugInfoEmitterTest, ShouldEmitCommitsToUMAIfChanged) { + base::ObserverList<TypeDebugInfoObserver> observers; + DataTypeDebugInfoEmitter emitter(BOOKMARKS, &observers); + + CommitCounters* counters = emitter.GetMutableCommitCounters(); + counters->num_deletion_commits_attempted += 3; + counters->num_creation_commits_attempted += 2; + counters->num_update_commits_attempted += 1; + + base::HistogramTester histogram_tester; + emitter.EmitCommitCountersUpdate(); + EXPECT_EQ( + 3, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange.BOOKMARK", + /*LOCAL_DELETION=*/0)); + EXPECT_EQ( + 2, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange.BOOKMARK", + /*LOCAL_CREATION=*/1)); + EXPECT_EQ(1, histogram_tester.GetBucketCount( + "Sync.ModelTypeEntityChange.BOOKMARK", /*LOCAL_UPDATE=*/2)); +} + +TEST(DataTypeDebugInfoEmitterTest, ShouldNotEmitCommitsToUMAIfNotChanged) { + base::ObserverList<TypeDebugInfoObserver> observers; + DataTypeDebugInfoEmitter emitter(BOOKMARKS, &observers); + + base::HistogramTester histogram_tester; + emitter.EmitCommitCountersUpdate(); + histogram_tester.ExpectTotalCount("Sync.ModelTypeEntityChange.BOOKMARK", 0); +} + +// Tests that at each EmitCommitCountersUpdate() call, only the changes since +// the last call to EmitCommitCountersUpdate() are reported to UMA. +TEST(DataTypeDebugInfoEmitterTest, ShouldEmitCommitsToUMAIncrementally) { + base::ObserverList<TypeDebugInfoObserver> observers; + DataTypeDebugInfoEmitter emitter(BOOKMARKS, &observers); + + CommitCounters* counters = emitter.GetMutableCommitCounters(); + counters->num_deletion_commits_attempted += 3; + counters->num_creation_commits_attempted += 2; + counters->num_update_commits_attempted += 1; + + // First emission - tested in the test above. + emitter.EmitCommitCountersUpdate(); + + counters = emitter.GetMutableCommitCounters(); + counters->num_deletion_commits_attempted += 1; + counters->num_creation_commits_attempted += 2; + counters->num_update_commits_attempted += 3; + + // Test the second emission that it only reports the increment in counters. + base::HistogramTester histogram_tester; + emitter.EmitCommitCountersUpdate(); + EXPECT_EQ( + 1, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange.BOOKMARK", + /*LOCAL_DELETION=*/0)); + EXPECT_EQ( + 2, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange.BOOKMARK", + /*LOCAL_CREATION=*/1)); + EXPECT_EQ(3, histogram_tester.GetBucketCount( + "Sync.ModelTypeEntityChange.BOOKMARK", /*LOCAL_UPDATE=*/2)); +} + +TEST(DataTypeDebugInfoEmitterTest, ShouldEmitUpdatesToUMAIfChanged) { + base::ObserverList<TypeDebugInfoObserver> observers; + DataTypeDebugInfoEmitter emitter(BOOKMARKS, &observers); + + UpdateCounters* counters = emitter.GetMutableUpdateCounters(); + counters->num_updates_received += 3; + counters->num_tombstone_updates_received += 1; + + base::HistogramTester histogram_tester; + emitter.EmitUpdateCountersUpdate(); + EXPECT_EQ( + 1, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange.BOOKMARK", + /*REMOTE_DELETION=*/3)); + EXPECT_EQ( + 2, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange.BOOKMARK", + /*REMOTE_UPDATE=*/4)); +} + +TEST(DataTypeDebugInfoEmitterTest, ShouldNotEmitUpdatesToUMAIfNotChanged) { + base::ObserverList<TypeDebugInfoObserver> observers; + DataTypeDebugInfoEmitter emitter(BOOKMARKS, &observers); + + base::HistogramTester histogram_tester; + emitter.EmitUpdateCountersUpdate(); + histogram_tester.ExpectTotalCount("Sync.ModelTypeEntityChange.BOOKMARK", 0); +} + +// Tests that at each EmitUpdateCountersUpdate() call, only the changes since +// the last call to EmitUpdateCountersUpdate() are reported to UMA. +TEST(DataTypeDebugInfoEmitterTest, ShouldEmitUpdatesToUMAIncrementally) { + base::ObserverList<TypeDebugInfoObserver> observers; + DataTypeDebugInfoEmitter emitter(BOOKMARKS, &observers); + + UpdateCounters* counters = emitter.GetMutableUpdateCounters(); + counters->num_updates_received += 3; + counters->num_tombstone_updates_received += 1; + + // First emission - tested in the test above. + emitter.EmitUpdateCountersUpdate(); + + counters = emitter.GetMutableUpdateCounters(); + counters->num_updates_received += 3; + counters->num_tombstone_updates_received += 2; + + // Test the second emission that it only reports the increment in counters. + base::HistogramTester histogram_tester; + emitter.EmitUpdateCountersUpdate(); + EXPECT_EQ( + 2, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange.BOOKMARK", + /*REMOTE_DELETION=*/3)); + EXPECT_EQ( + 1, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange.BOOKMARK", + /*REMOTE_UPDATE=*/4)); +} + +} // namespace +} // namespace syncer
diff --git a/components/sync/syncable/directory_backing_store.cc b/components/sync/syncable/directory_backing_store.cc index 6b681c4b..8c97f4b 100644 --- a/components/sync/syncable/directory_backing_store.cc +++ b/components/sync/syncable/directory_backing_store.cc
@@ -280,16 +280,14 @@ const int (&entries_counts)[MODEL_TYPE_COUNT]) { int total_entry_counts = 0; for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { - std::string model_type; - if (RealModelTypeToNotificationType((ModelType)i, &model_type)) { - std::string full_histogram_name = "Sync.ModelTypeCount." + model_type; - base::HistogramBase* histogram = base::Histogram::FactoryGet( - full_histogram_name, 1, 1000000, 50, - base::HistogramBase::kUmaTargetedHistogramFlag); - if (histogram) - histogram->Add(entries_counts[i]); - total_entry_counts += entries_counts[i]; - } + std::string model_type = ModelTypeToHistogramSuffix((ModelType)i); + std::string full_histogram_name = "Sync.ModelTypeCount." + model_type; + base::HistogramBase* histogram = base::Histogram::FactoryGet( + full_histogram_name, 1, 1000000, 50, + base::HistogramBase::kUmaTargetedHistogramFlag); + if (histogram) + histogram->Add(entries_counts[i]); + total_entry_counts += entries_counts[i]; } UMA_HISTOGRAM_COUNTS("Sync.ModelTypeCount", total_entry_counts); UMA_HISTOGRAM_COUNTS("Sync.ExtraSyncDataCount",
diff --git a/components/sync/syncable/model_type.cc b/components/sync/syncable/model_type.cc index b3b23a6..68ec049 100644 --- a/components/sync/syncable/model_type.cc +++ b/components/sync/syncable/model_type.cc
@@ -32,7 +32,9 @@ struct ModelTypeInfo { ModelType model_type; // Model Type notification string. - // This needs to match the corresponding proto message name in sync.proto + // This needs to match the corresponding proto message name in sync.proto. It + // is also used to identify the model type in the SyncModelType + // histogram_suffix in histograms.xml. Must always be kept in sync. const char* notification_type; // Root tag for Model Type // This should be the same as the model type but all lowercase. @@ -49,8 +51,10 @@ }; // Below struct entries are in the same order as their definition in the -// ModelType enum. Don't forget to update the ModelType enum when you make -// changes to this list. +// ModelType enum. When making changes to this list, don't forget to +// - update the ModelType enum, +// - update the SyncModelTypes enum in enums.xml, and +// - update the SyncModelType histogram suffix in histograms.xml. // Struct field values should be unique across the entire map. const ModelTypeInfo kModelTypeInfoMap[] = { {UNSPECIFIED, "", "", "Unspecified", -1, 0}, @@ -493,6 +497,17 @@ return "Invalid"; } +const char* ModelTypeToHistogramSuffix(ModelType model_type) { + if (model_type >= UNSPECIFIED && model_type < MODEL_TYPE_COUNT) { + // We use the same string that is used for notification types because they + // satisfy all we need (being stable and explanatory). + return kModelTypeInfoMap[model_type].notification_type; + } + NOTREACHED() << "No known suffix for model type " + << static_cast<int>(model_type) << "."; + return "Invalid"; +} + // The normal rules about histograms apply here. Always append to the bottom of // the list, and be careful to not reuse integer values that have already been // assigned.
diff --git a/components/sync/user_events/user_event_sync_bridge.cc b/components/sync/user_events/user_event_sync_bridge.cc index 6b6041d..846356c 100644 --- a/components/sync/user_events/user_event_sync_bridge.cc +++ b/components/sync/user_events/user_event_sync_bridge.cc
@@ -59,15 +59,6 @@ return entity_data; } -std::unique_ptr<EntityData> CopyToEntityData( - const UserEventSpecifics specifics) { - auto entity_data = std::make_unique<EntityData>(); - entity_data->non_unique_name = - base::Int64ToString(specifics.event_time_usec()); - *entity_data->specifics.mutable_user_event() = specifics; - return entity_data; -} - } // namespace UserEventSyncBridge::UserEventSyncBridge( @@ -358,11 +349,12 @@ } auto batch = std::make_unique<MutableDataBatch>(); - UserEventSpecifics specifics; for (const Record& r : *data_records) { - if (specifics.ParseFromString(r.value)) { - DCHECK_EQ(r.id, GetStorageKeyFromSpecifics(specifics)); - batch->Put(r.id, CopyToEntityData(specifics)); + auto specifics = std::make_unique<UserEventSpecifics>(); + + if (specifics->ParseFromString(r.value)) { + DCHECK_EQ(r.id, GetStorageKeyFromSpecifics(*specifics)); + batch->Put(r.id, MoveToEntityData(std::move(specifics))); } else { change_processor()->ReportError( {FROM_HERE, "Failed deserializing user events."});
diff --git a/components/test/data/ntp/render/1200x800_DefaultMV.png b/components/test/data/ntp/render/1200x800_DefaultMV.png index 958b314..f453798 100644 --- a/components/test/data/ntp/render/1200x800_DefaultMV.png +++ b/components/test/data/ntp/render/1200x800_DefaultMV.png Binary files differ
diff --git a/components/ukm/debug/BUILD.gn b/components/ukm/debug/BUILD.gn index f40504a..e4f6781 100644 --- a/components/ukm/debug/BUILD.gn +++ b/components/ukm/debug/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//third_party/closure_compiler/compile_js.gni") + source_set("util") { sources = [ "ukm_debug_data_extractor.cc", @@ -13,3 +15,16 @@ "//services/metrics/public/cpp:ukm_builders", ] } + +js_type_check("closure_compile") { + deps = [ + ":ukm_internals", + ] +} + +js_library("ukm_internals") { + deps = [ + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:util", + ] +}
diff --git a/components/ukm/debug/ukm_debug_data_extractor.cc b/components/ukm/debug/ukm_debug_data_extractor.cc index fc768528..89fd400e 100644 --- a/components/ukm/debug/ukm_debug_data_extractor.cc +++ b/components/ukm/debug/ukm_debug_data_extractor.cc
@@ -114,74 +114,5 @@ return std::move(ukm_data); } -// static -std::string UkmDebugDataExtractor::GetHTMLData(const UkmService* ukm_service) { - std::string output; - output.append(R"""(<!DOCTYPE html> - <html> - <head> - <meta http-equiv="Content-Security-Policy" - content="object-src 'none'; script-src 'none'"> - <title>UKM Debug</title> - </head> - <body> - <h1>UKM Debug page</h1> - )"""); - - if (ukm_service) { - output.append( - // 'id' attribute set so tests can extract this element. - base::StringPrintf("<p>IsEnabled:<span id='state'>%s</span></p>", - ukm_service->recording_enabled_ ? "True" : "False")); - output.append(base::StringPrintf("<p>ClientId:<span id='clientid'>%" PRIu64 - "</span></p>", - ukm_service->client_id_)); - output.append( - base::StringPrintf("<p>SessionId:%d</p>", ukm_service->session_id_)); - - const auto& decode_map = ukm_service->decode_map_; - std::map<SourceId, SourceData> source_data; - for (const auto& kv : ukm_service->recordings_.sources) { - source_data[kv.first].source = kv.second.get(); - } - - for (const auto& v : ukm_service->recordings_.entries) { - source_data[v->source_id].entries.push_back(v.get()); - } - - output.append("<h2>Sources</h2>"); - for (const auto& kv : source_data) { - const auto* src = kv.second.source; - if (src) { - output.append(base::StringPrintf("<h3>Id:%" PRId64 " Url:%s</h3>", - src->id(), src->url().spec().c_str())); - } else { - output.append(base::StringPrintf("<h3>Id:%" PRId64 "</h3>", kv.first)); - } - for (auto* entry : kv.second.entries) { - const auto it = decode_map.find(entry->event_hash); - if (it == decode_map.end()) { - output.append(base::StringPrintf( - "<h4>Entry: Unknown %" PRIu64 "</h4>", entry->event_hash)); - continue; - } - output.append(base::StringPrintf("<h4>Entry:%s</h4>", it->second.name)); - for (const auto& metric : entry->metrics) { - output.append(base::StringPrintf( - "<h5>Metric:%s Value:%" PRId64 "</h5>", - GetName(it->second, metric.first).c_str(), metric.second)); - } - } - } - } - - output.append(R"""( - </body> - </html> - )"""); - - return output; -} - } // namespace debug } // namespace ukm
diff --git a/components/ukm/debug/ukm_debug_data_extractor.h b/components/ukm/debug/ukm_debug_data_extractor.h index 0a55cdf..dc2810d 100644 --- a/components/ukm/debug/ukm_debug_data_extractor.h +++ b/components/ukm/debug/ukm_debug_data_extractor.h
@@ -26,10 +26,6 @@ // Returns UKM data structured in a DictionaryValue. static base::Value GetStructuredData(const UkmService* ukm_service); - // Returns UKM data as an HTML page. - // TODO(etiennep): Use GetStructuredData() instead. - static std::string GetHTMLData(const UkmService* ukm_service); - private: DISALLOW_COPY_AND_ASSIGN(UkmDebugDataExtractor); };
diff --git a/chrome/browser/resources/ukm/ukm_internals.html b/components/ukm/debug/ukm_internals.html similarity index 100% rename from chrome/browser/resources/ukm/ukm_internals.html rename to components/ukm/debug/ukm_internals.html
diff --git a/components/ukm/debug/ukm_internals.js b/components/ukm/debug/ukm_internals.js new file mode 100644 index 0000000..85c1c7a --- /dev/null +++ b/components/ukm/debug/ukm_internals.js
@@ -0,0 +1,78 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @typedef {{ + * name: string, + * value: string + * }} + */ +var Metric; + +/** + * @typedef {{ + * name: string, + * metrics: !Array<!Metric> + * }} + */ +var UkmEntry; + +/** + * @typedef {{ + * url: string, + * id: string, + * entries: !Array<UkmEntry>, + * }} + */ +var UkmDataSource; + +/** + * The Ukm data sent from the browser. + * @typedef {{ + * state: boolean, + * client_id: string, + * session_id: string, + * sources: !Array<!UkmDataSource>, + * }} + */ +var UkmData; + +/** + * Fetches data from the Ukm service and updates the DOM to display it as a + * list. + */ +function updateUkmData() { + cr.sendWithPromise('requestUkmData').then((/** @type {UkmData} */ data) => { + $('state').innerText = data.state ? 'True' : 'False'; + $('clientid').innerText = data.client_id; + $('sessionid').innerText = data.session_id; + + let sourceDiv = $('sources'); + for (const source of data.sources) { + const sourceElement = document.createElement('h3'); + if (source.url !== undefined) + sourceElement.innerText = `Id: ${source.id} Url: ${source.url}`; + else + sourceElement.innerText = `Id: ${source.id}`; + sourceDiv.appendChild(sourceElement); + + for (const entry of source.entries) { + const entryElement = document.createElement('h4'); + entryElement.innerText = `Entry: ${entry.name}`; + sourceDiv.appendChild(entryElement); + + if (entry.metrics === undefined) + continue; + for (const metric of entry.metrics) { + const metricElement = document.createElement('h5'); + metricElement.innerText = + `Metric: ${metric.name} Value: ${metric.value}`; + sourceDiv.appendChild(metricElement); + } + } + } + }); +} + +updateUkmData();
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc index 4747e0d..34795671 100644 --- a/components/unified_consent/unified_consent_service.cc +++ b/components/unified_consent/unified_consent_service.cc
@@ -135,7 +135,10 @@ return; } - DCHECK(sync_service_->IsSyncAllowed()); + DCHECK(!sync_service_->HasDisableReason( + syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE)); + DCHECK(!sync_service_->HasDisableReason( + syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY)); DCHECK(identity_manager_->HasPrimaryAccount()); DCHECK_LT(MigrationState::NOT_INITIALIZED, GetMigrationState());
diff --git a/components/unified_consent/url_keyed_data_collection_consent_helper.cc b/components/unified_consent/url_keyed_data_collection_consent_helper.cc index a504fdb..6ad5213 100644 --- a/components/unified_consent/url_keyed_data_collection_consent_helper.cc +++ b/components/unified_consent/url_keyed_data_collection_consent_helper.cc
@@ -87,8 +87,10 @@ sync_data_type_(sync_data_type), sync_data_type_upload_state_( syncer::GetUploadToGoogleState(sync_service_, sync_data_type_)) { - DCHECK(sync_service_); - sync_service_->AddObserver(this); + if (sync_service_) + sync_service_->AddObserver(this); + else + DCHECK_EQ(syncer::UploadState::NOT_ACTIVE, sync_data_type_upload_state_); } SyncBasedUrlKeyedDataCollectionConsentHelper::
diff --git a/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc b/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc index a83653c..d677ccb 100644 --- a/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc +++ b/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc
@@ -137,6 +137,16 @@ } TEST_F(UrlKeyedDataCollectionConsentHelperTest, + AnonymizedDataCollection_UnifiedConsentDisabled_NullSyncService) { + std::unique_ptr<UrlKeyedDataCollectionConsentHelper> helper = + UrlKeyedDataCollectionConsentHelper:: + NewAnonymizedDataCollectionConsentHelper( + false /* is_unified_consent_enabled */, &pref_service_, + nullptr /* sync_service */); + EXPECT_FALSE(helper->IsEnabled()); +} + +TEST_F(UrlKeyedDataCollectionConsentHelperTest, PersonalizeddDataCollection_UnifiedConsentEnabled) { std::unique_ptr<UrlKeyedDataCollectionConsentHelper> helper = UrlKeyedDataCollectionConsentHelper:: @@ -171,5 +181,25 @@ helper->RemoveObserver(this); } +TEST_F(UrlKeyedDataCollectionConsentHelperTest, + PersonalizedDataCollection_NullSyncService) { + { + std::unique_ptr<UrlKeyedDataCollectionConsentHelper> helper = + UrlKeyedDataCollectionConsentHelper:: + NewPersonalizedDataCollectionConsentHelper( + false /* is_unified_consent_enabled */, + nullptr /* sync_service */); + EXPECT_FALSE(helper->IsEnabled()); + } + { + std::unique_ptr<UrlKeyedDataCollectionConsentHelper> helper = + UrlKeyedDataCollectionConsentHelper:: + NewPersonalizedDataCollectionConsentHelper( + true /* is_unified_consent_enabled */, + nullptr /* sync_service */); + EXPECT_FALSE(helper->IsEnabled()); + } +} + } // namespace } // namespace unified_consent
diff --git a/components/viz/service/surfaces/surface_dependency_tracker.cc b/components/viz/service/surfaces/surface_dependency_tracker.cc index a8773e6b..08a14bc 100644 --- a/components/viz/service/surfaces/surface_dependency_tracker.cc +++ b/components/viz/service/surfaces/surface_dependency_tracker.cc
@@ -19,8 +19,6 @@ void SurfaceDependencyTracker::RequestSurfaceResolution(Surface* surface) { DCHECK(surface->HasPendingFrame()); - const CompositorFrame& pending_frame = surface->GetPendingFrame(); - if (IsSurfaceLate(surface)) { ActivateLateSurfaceSubtree(surface); return; @@ -28,8 +26,7 @@ // Activation dependencies that aren't currently known to the surface manager // or do not have an active CompositorFrame block this frame. - for (const SurfaceId& surface_id : - pending_frame.metadata.activation_dependencies) { + for (const SurfaceId& surface_id : surface->activation_dependencies()) { Surface* dependency = surface_manager_->GetSurfaceForId(surface_id); if (!dependency || !dependency->HasActiveFrame()) { blocked_surfaces_from_dependency_[surface_id.frame_sink_id()].insert( @@ -75,12 +72,7 @@ if (!surface->HasPendingFrame()) return; - const CompositorFrame& pending_frame = surface->GetPendingFrame(); - - DCHECK(!pending_frame.metadata.activation_dependencies.empty()); - - for (const SurfaceId& surface_id : - pending_frame.metadata.activation_dependencies) { + for (const SurfaceId& surface_id : surface->activation_dependencies()) { auto it = blocked_surfaces_from_dependency_.find(surface_id.frame_sink_id()); if (it == blocked_surfaces_from_dependency_.end()) @@ -110,10 +102,7 @@ void SurfaceDependencyTracker::ActivateLateSurfaceSubtree(Surface* surface) { DCHECK(surface->HasPendingFrame()); - const CompositorFrame& pending_frame = surface->GetPendingFrame(); - - for (const SurfaceId& surface_id : - pending_frame.metadata.activation_dependencies) { + for (const SurfaceId& surface_id : surface->activation_dependencies()) { Surface* dependency = surface_manager_->GetSurfaceForId(surface_id); if (dependency && dependency->HasPendingFrame()) ActivateLateSurfaceSubtree(dependency); @@ -125,8 +114,6 @@ void SurfaceDependencyTracker::UpdateSurfaceDeadline(Surface* surface) { DCHECK(surface->HasPendingFrame()); - const CompositorFrame& pending_frame = surface->GetPendingFrame(); - // Inherit the deadline from the first parent blocked on this surface. auto it = blocked_surfaces_from_dependency_.find( surface->surface_id().frame_sink_id()); @@ -146,8 +133,7 @@ surface->has_deadline()); // Recursively propagate the newly set deadline to children. - for (const SurfaceId& surface_id : - pending_frame.metadata.activation_dependencies) { + for (const SurfaceId& surface_id : surface->activation_dependencies()) { Surface* dependency = surface_manager_->GetSurfaceForId(surface_id); if (dependency && dependency->HasPendingFrame()) UpdateSurfaceDeadline(dependency);
diff --git a/components/webdata_services/web_data_service_wrapper.cc b/components/webdata_services/web_data_service_wrapper.cc index 8bcd4d3..0287a89 100644 --- a/components/webdata_services/web_data_service_wrapper.cc +++ b/components/webdata_services/web_data_service_wrapper.cc
@@ -18,6 +18,7 @@ #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.h" +#include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h" #include "components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/common/autofill_features.h" @@ -71,6 +72,9 @@ } } +// TODO(jkrcal): Rename this function when the last webdata sync type get +// converted to USS, e.g. to InitSyncBridgesOnDBSequence(). Check also other +// related functions. void InitSyncableAccountServicesOnDBSequence( scoped_refptr<base::SingleThreadTaskRunner> db_task_runner, const syncer::SyncableService::StartSyncFlare& sync_flare, @@ -79,15 +83,21 @@ const std::string& app_locale, autofill::AutofillWebDataBackend* autofill_backend) { DCHECK(db_task_runner->RunsTasksInCurrentSequence()); - autofill::AutofillWalletSyncableService::CreateForWebDataServiceAndBackend( - autofill_web_data.get(), autofill_backend, app_locale); + + if (base::FeatureList::IsEnabled(switches::kSyncUSSAutofillWalletData)) { + autofill::AutofillWalletSyncBridge::CreateForWebDataServiceAndBackend( + app_locale, autofill_backend, autofill_web_data.get()); + } else { + autofill::AutofillWalletSyncableService::CreateForWebDataServiceAndBackend( + autofill_web_data.get(), autofill_backend, app_locale); + autofill::AutofillWalletSyncableService::FromWebDataService( + autofill_web_data.get()) + ->InjectStartSyncFlare(sync_flare); + } + autofill::AutofillWalletMetadataSyncableService:: CreateForWebDataServiceAndBackend(autofill_web_data.get(), autofill_backend, app_locale); - - autofill::AutofillWalletSyncableService::FromWebDataService( - autofill_web_data.get()) - ->InjectStartSyncFlare(sync_flare); } } // namespace
diff --git a/components/zucchini/BUILD.gn b/components/zucchini/BUILD.gn index 77dc810..c871d9d1 100644 --- a/components/zucchini/BUILD.gn +++ b/components/zucchini/BUILD.gn
@@ -78,8 +78,8 @@ "rel32_finder.h", "rel32_utils.cc", "rel32_utils.h", - "reloc_utils.cc", - "reloc_utils.h", + "reloc_win32.cc", + "reloc_win32.h", "suffix_array.h", "target_pool.cc", "target_pool.h", @@ -169,7 +169,7 @@ "reference_set_unittest.cc", "rel32_finder_unittest.cc", "rel32_utils_unittest.cc", - "reloc_utils_unittest.cc", + "reloc_win32_unittest.cc", "suffix_array_unittest.cc", "target_pool_unittest.cc", "targets_affinity_unittest.cc",
diff --git a/components/zucchini/disassembler_win32.cc b/components/zucchini/disassembler_win32.cc index a932bea2..7eba0f4 100644 --- a/components/zucchini/disassembler_win32.cc +++ b/components/zucchini/disassembler_win32.cc
@@ -15,7 +15,7 @@ #include "components/zucchini/buffer_source.h" #include "components/zucchini/rel32_finder.h" #include "components/zucchini/rel32_utils.h" -#include "components/zucchini/reloc_utils.h" +#include "components/zucchini/reloc_win32.h" namespace zucchini {
diff --git a/components/zucchini/reloc_utils.cc b/components/zucchini/reloc_win32.cc similarity index 98% rename from components/zucchini/reloc_utils.cc rename to components/zucchini/reloc_win32.cc index d6f69b9..2f993ad1 100644 --- a/components/zucchini/reloc_utils.cc +++ b/components/zucchini/reloc_win32.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/zucchini/reloc_utils.h" +#include "components/zucchini/reloc_win32.h" #include <algorithm> #include <tuple>
diff --git a/components/zucchini/reloc_utils.h b/components/zucchini/reloc_win32.h similarity index 97% rename from components/zucchini/reloc_utils.h rename to components/zucchini/reloc_win32.h index aac1efb..207c6e7 100644 --- a/components/zucchini/reloc_utils.h +++ b/components/zucchini/reloc_win32.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ZUCCHINI_RELOC_UTILS_H_ -#define COMPONENTS_ZUCCHINI_RELOC_UTILS_H_ +#ifndef COMPONENTS_ZUCCHINI_RELOC_WIN32_H_ +#define COMPONENTS_ZUCCHINI_RELOC_WIN32_H_ #include <stddef.h> #include <stdint.h> @@ -137,4 +137,4 @@ } // namespace zucchini -#endif // COMPONENTS_ZUCCHINI_RELOC_UTILS_H_ +#endif // COMPONENTS_ZUCCHINI_RELOC_WIN32_H_
diff --git a/components/zucchini/reloc_utils_unittest.cc b/components/zucchini/reloc_win32_unittest.cc similarity index 99% rename from components/zucchini/reloc_utils_unittest.cc rename to components/zucchini/reloc_win32_unittest.cc index 65acf5b..ca9bbe6 100644 --- a/components/zucchini/reloc_utils_unittest.cc +++ b/components/zucchini/reloc_win32_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/zucchini/reloc_utils.h" +#include "components/zucchini/reloc_win32.h" #include <stdint.h>
diff --git a/content/browser/background_fetch/background_fetch_service_impl.cc b/content/browser/background_fetch/background_fetch_service_impl.cc index 596cfaa..864a1704c 100644 --- a/content/browser/background_fetch/background_fetch_service_impl.cc +++ b/content/browser/background_fetch/background_fetch_service_impl.cc
@@ -106,10 +106,14 @@ int64_t service_worker_registration_id, const std::string& developer_id, const std::string& unique_id, - const std::string& title, + const base::Optional<std::string>& title, + const SkBitmap& icon, UpdateUICallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!ValidateUniqueId(unique_id) || !ValidateTitle(title)) { + + // TODO(crbug.com/865063): Remove the check for |title| when updating both the + // title and icons is supported. + if (!ValidateUniqueId(unique_id) || !title || !ValidateTitle(*title)) { std::move(callback).Run( blink::mojom::BackgroundFetchError::INVALID_ARGUMENT); return; @@ -117,7 +121,7 @@ BackgroundFetchRegistrationId registration_id( service_worker_registration_id, origin_, developer_id, unique_id); - background_fetch_context_->UpdateUI(registration_id, title, + background_fetch_context_->UpdateUI(registration_id, *title, std::move(callback)); }
diff --git a/content/browser/background_fetch/background_fetch_service_impl.h b/content/browser/background_fetch/background_fetch_service_impl.h index c61095e1..d59fbe16 100644 --- a/content/browser/background_fetch/background_fetch_service_impl.h +++ b/content/browser/background_fetch/background_fetch_service_impl.h
@@ -47,7 +47,8 @@ void UpdateUI(int64_t service_worker_registration_id, const std::string& developer_id, const std::string& unique_id, - const std::string& title, + const base::Optional<std::string>& title, + const SkBitmap& icon, UpdateUICallback callback) override; void Abort(int64_t service_worker_registration_id, const std::string& developer_id,
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc index 6e2a9c6..36f5702 100644 --- a/content/browser/background_fetch/background_fetch_service_unittest.cc +++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -183,7 +183,7 @@ base::RunLoop run_loop; service_->UpdateUI(service_worker_registration_id, unique_id, developer_id, - title, + title, SkBitmap(), base::BindOnce(&BackgroundFetchServiceTest::DidGetError, base::Unretained(this), run_loop.QuitClosure(), out_error));
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc index eb9c846..bb71805 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -58,8 +58,7 @@ media_web_contents_observer_ = initiator_->media_web_contents_observer(); - window_ = - GetContentClient()->browser()->CreateWindowForPictureInPicture(this); + EnsureWindow(); DCHECK(window_) << "Picture in Picture requires a valid window."; } @@ -84,23 +83,25 @@ } void PictureInPictureWindowControllerImpl::Close(bool should_pause_video) { - DCHECK(window_); - - if (!window_->IsVisible()) + if (!window_ || !window_->IsVisible()) return; window_->Hide(); - initiator_->SetHasPictureInPictureVideo(false); + CloseInternal(should_pause_video); +} - surface_id_ = viz::SurfaceId(); - - OnLeavingPictureInPicture(should_pause_video); +void PictureInPictureWindowControllerImpl::OnWindowDestroyed() { + window_ = nullptr; + embedder_ = nullptr; + CloseInternal(true /* should_pause_video */); } void PictureInPictureWindowControllerImpl::EmbedSurface( const viz::SurfaceId& surface_id, const gfx::Size& natural_size) { + EnsureWindow(); DCHECK(window_); + DCHECK(surface_id.is_valid()); surface_id_ = surface_id; @@ -195,4 +196,21 @@ } } +void PictureInPictureWindowControllerImpl::CloseInternal( + bool should_pause_video) { + initiator_->SetHasPictureInPictureVideo(false); + + surface_id_ = viz::SurfaceId(); + + OnLeavingPictureInPicture(should_pause_video); +} + +void PictureInPictureWindowControllerImpl::EnsureWindow() { + if (window_) + return; + + window_ = + GetContentClient()->browser()->CreateWindowForPictureInPicture(this); +} + } // namespace content
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h index 8cd191f..7ce6d85 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
@@ -36,6 +36,7 @@ // PictureInPictureWindowController: CONTENT_EXPORT gfx::Size Show() override; CONTENT_EXPORT void Close(bool should_pause_video) override; + CONTENT_EXPORT void OnWindowDestroyed() override; CONTENT_EXPORT void ClickCustomControl( const std::string& control_id) override; CONTENT_EXPORT void EmbedSurface(const viz::SurfaceId& surface_id, @@ -59,6 +60,14 @@ // Signal to the media player that |this| is leaving Picture-in-Picture mode. void OnLeavingPictureInPicture(bool should_pause_video); + // Internal method to set the states after the window was closed, whether via + // the system or Chromium. + void CloseInternal(bool should_pause_video); + + // Creates a new window if the previous one was destroyed. It can happen + // because of the system control of the window. + void EnsureWindow(); + std::unique_ptr<OverlayWindow> window_; std::unique_ptr<OverlaySurfaceEmbedder> embedder_; WebContentsImpl* const initiator_;
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc index faa3314..a4d9ed9 100644 --- a/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -767,7 +767,13 @@ EXPECT_FALSE(HasPendingEvents()); } -TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) { +// TODO(https://crbug.com/866946): Test is flaky on Fuchsia. +#if defined(OS_FUCHSIA) +#define MAYBE_GestureTypesIgnoringAck DISABLED_GestureTypesIgnoringAck +#else +#define MAYBE_GestureTypesIgnoringAck GestureTypesIgnoringAck +#endif +TEST_F(InputRouterImplTest, MAYBE_GestureTypesIgnoringAck) { // We test every gesture type, ensuring that the stream of gestures is valid. const WebInputEvent::Type eventTypes[] = { WebInputEvent::kGestureTapDown, WebInputEvent::kGestureShowPress,
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.cc b/content/browser/speech/speech_recognition_dispatcher_host.cc index 4e8664e..87617e6 100644 --- a/content/browser/speech/speech_recognition_dispatcher_host.cc +++ b/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -201,7 +201,11 @@ : session_id_(SpeechRecognitionManager::kSessionIDInvalid), client_(std::move(client_ptr_info)), stopped_(false), - weak_factory_(this) {} + weak_factory_(this) { + client_.set_connection_error_handler( + base::BindOnce(&SpeechRecognitionSession::ConnectionErrorHandler, + base::Unretained(this))); +} SpeechRecognitionSession::~SpeechRecognitionSession() { // If a connection error happens and the session hasn't been stopped yet, @@ -273,4 +277,9 @@ void SpeechRecognitionSession::OnEnvironmentEstimationComplete(int session_id) { } +void SpeechRecognitionSession::ConnectionErrorHandler() { + if (!stopped_) + Abort(); +} + } // namespace content
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.h b/content/browser/speech/speech_recognition_dispatcher_host.h index ffa9bd51..9eeeb44 100644 --- a/content/browser/speech/speech_recognition_dispatcher_host.h +++ b/content/browser/speech/speech_recognition_dispatcher_host.h
@@ -109,6 +109,8 @@ float noise_volume) override; private: + void ConnectionErrorHandler(); + int session_id_; blink::mojom::SpeechRecognitionSessionClientPtr client_; bool stopped_;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 717e332..279b13f 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -406,6 +406,9 @@ WebRuntimeFeatures::EnableWorkStealingInScriptRunner( base::FeatureList::IsEnabled(features::kWorkStealingInScriptRunner)); + WebRuntimeFeatures::EnableScheduledScriptStreaming( + base::FeatureList::IsEnabled(features::kScheduledScriptStreaming)); + WebRuntimeFeatures::EnableFeatureFromString( "FeaturePolicyForPermissions", base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions));
diff --git a/content/public/browser/picture_in_picture_window_controller.h b/content/public/browser/picture_in_picture_window_controller.h index 64f01043..6df6f22 100644 --- a/content/public/browser/picture_in_picture_window_controller.h +++ b/content/public/browser/picture_in_picture_window_controller.h
@@ -38,7 +38,14 @@ // Returns the size of the window in pixels. virtual gfx::Size Show() = 0; + // Called to notify the controller that the window was requested to be closed + // by the user or the content. virtual void Close(bool should_pause_video) = 0; + + // Called by the window implementation to notify the controller that the + // window was requested to be closed and destroyed by the system. + virtual void OnWindowDestroyed() = 0; + virtual void ClickCustomControl(const std::string& control_id) = 0; virtual void EmbedSurface(const viz::SurfaceId& surface_id, const gfx::Size& natural_size) = 0;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 12feb84..04d6bae 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -590,6 +590,10 @@ const base::Feature kWorkStealingInScriptRunner{ "WorkStealingInScriptRunner", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enabled scheduler use for script streaming. +const base::Feature kScheduledScriptStreaming{ + "ScheduledScriptStreaming", base::FEATURE_DISABLED_BY_DEFAULT}; + #if defined(OS_ANDROID) // Autofill Accessibility in Android. // crbug.com/627860
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 8f0e58ea..d6249a7 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -135,6 +135,7 @@ CONTENT_EXPORT extern const base::Feature kWebXrOrientationSensorDevice; CONTENT_EXPORT extern const base::Feature kWipeCorruptV2IDBDatabases; CONTENT_EXPORT extern const base::Feature kWorkStealingInScriptRunner; +CONTENT_EXPORT extern const base::Feature kScheduledScriptStreaming; #if defined(OS_ANDROID) CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility;
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc index 5326845..80559a1 100644 --- a/content/renderer/render_process_impl.cc +++ b/content/renderer/render_process_impl.cc
@@ -144,8 +144,10 @@ SetV8FlagIfFeature(features::kV8VmFuture, "--future"); SetV8FlagIfNotFeature(features::kV8VmFuture, "--no-future"); - SetV8FlagIfFeature(features::kWebAssemblyBaseline, "--wasm-tier-up"); - SetV8FlagIfNotFeature(features::kWebAssemblyBaseline, "--no-wasm-tier-up"); + SetV8FlagIfFeature(features::kWebAssemblyBaseline, + "--liftoff --wasm-tier-up"); + SetV8FlagIfNotFeature(features::kWebAssemblyBaseline, + "--no-liftoff --no-wasm-tier-up"); if (base::FeatureList::IsEnabled(features::kWebAssemblyThreads)) { constexpr char kFlags[] =
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc index d573edc2..0ec1525 100644 --- a/content/shell/app/shell_main_delegate.cc +++ b/content/shell/app/shell_main_delegate.cc
@@ -248,6 +248,7 @@ command_line.AppendSwitch(switches::kEnablePreciseMemoryInfo); command_line.AppendSwitchASCII(network::switches::kHostResolverRules, + "MAP nonexistent.*.test ~NOTFOUND," "MAP *.test 127.0.0.1"); command_line.AppendSwitch(switches::kEnablePartialRaster);
diff --git a/device/usb/BUILD.gn b/device/usb/BUILD.gn index 3248fe6b4..5b183fcc 100644 --- a/device/usb/BUILD.gn +++ b/device/usb/BUILD.gn
@@ -81,9 +81,6 @@ if (is_win || is_mac) { sources += [ - "scoped_libusb_device_handle.cc", - "scoped_libusb_device_handle.h", - "scoped_libusb_device_ref.cc", "scoped_libusb_device_ref.h", "usb_context.cc", "usb_context.h",
diff --git a/device/usb/scoped_libusb_device_handle.cc b/device/usb/scoped_libusb_device_handle.cc deleted file mode 100644 index 4223a81..0000000 --- a/device/usb/scoped_libusb_device_handle.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "device/usb/scoped_libusb_device_handle.h" - -#include "device/usb/usb_context.h" -#include "third_party/libusb/src/libusb/libusb.h" - -namespace device { - -ScopedLibusbDeviceHandle::ScopedLibusbDeviceHandle( - libusb_device_handle* handle, - scoped_refptr<UsbContext> context) - : handle_(handle), context_(std::move(context)) {} - -ScopedLibusbDeviceHandle::ScopedLibusbDeviceHandle( - ScopedLibusbDeviceHandle&& other) - : handle_(other.handle_), context_(std::move(other.context_)) { - other.handle_ = nullptr; -} - -ScopedLibusbDeviceHandle::~ScopedLibusbDeviceHandle() { - Reset(); -} - -void ScopedLibusbDeviceHandle::Reset() { - libusb_close(handle_); - handle_ = nullptr; - context_.reset(); -} - -bool ScopedLibusbDeviceHandle::IsValid() const { - return handle_ != nullptr; -} - -} // namespace device
diff --git a/device/usb/scoped_libusb_device_handle.h b/device/usb/scoped_libusb_device_handle.h deleted file mode 100644 index a4eb378..0000000 --- a/device/usb/scoped_libusb_device_handle.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef DEVICE_USB_SCOPED_LIBUSB_DEVICE_HANDLE_H_ -#define DEVICE_USB_SCOPED_LIBUSB_DEVICE_HANDLE_H_ - -#include "base/macros.h" -#include "base/memory/scoped_refptr.h" - -struct libusb_device_handle; - -namespace device { - -class UsbContext; - -// This class owns a reference to a libusb_device_handle as well as a reference -// to the libusb_context. The libusb_context must outlive any -// libusb_device_handle instances created from it. -class ScopedLibusbDeviceHandle { - public: - ScopedLibusbDeviceHandle(libusb_device_handle* handle, - scoped_refptr<UsbContext> context); - ScopedLibusbDeviceHandle(ScopedLibusbDeviceHandle&& other); - ~ScopedLibusbDeviceHandle(); - - libusb_device_handle* get() const { return handle_; } - - void Reset(); - bool IsValid() const; - - private: - libusb_device_handle* handle_; - scoped_refptr<UsbContext> context_; - - DISALLOW_COPY_AND_ASSIGN(ScopedLibusbDeviceHandle); -}; - -} // namespace device - -#endif // DEVICE_USB_SCOPED_LIBUSB_DEVICE_HANDLE_H_
diff --git a/device/usb/scoped_libusb_device_ref.cc b/device/usb/scoped_libusb_device_ref.cc deleted file mode 100644 index b3ac5e8..0000000 --- a/device/usb/scoped_libusb_device_ref.cc +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "device/usb/scoped_libusb_device_ref.h" - -#include "device/usb/usb_context.h" -#include "third_party/libusb/src/libusb/libusb.h" - -namespace device { - -ScopedLibusbDeviceRef::ScopedLibusbDeviceRef(libusb_device* device, - scoped_refptr<UsbContext> context) - : device_(device), context_(std::move(context)) {} - -ScopedLibusbDeviceRef::ScopedLibusbDeviceRef(ScopedLibusbDeviceRef&& other) - : device_(other.device_), context_(std::move(other.context_)) { - other.device_ = nullptr; -} - -ScopedLibusbDeviceRef::~ScopedLibusbDeviceRef() { - Reset(); -} - -void ScopedLibusbDeviceRef::Reset() { - libusb_unref_device(device_); - device_ = nullptr; - context_.reset(); -} - -bool ScopedLibusbDeviceRef::IsValid() const { - return device_ != nullptr; -} - -bool operator==(const ScopedLibusbDeviceRef& ref, libusb_device* device) { - return ref.get() == device; -} - -} // namespace device
diff --git a/device/usb/scoped_libusb_device_ref.h b/device/usb/scoped_libusb_device_ref.h index 73a3731..05a21b2 100644 --- a/device/usb/scoped_libusb_device_ref.h +++ b/device/usb/scoped_libusb_device_ref.h
@@ -5,40 +5,19 @@ #ifndef DEVICE_USB_SCOPED_LIBUSB_DEVICE_REF_H_ #define DEVICE_USB_SCOPED_LIBUSB_DEVICE_REF_H_ -#include "base/macros.h" -#include "base/memory/scoped_refptr.h" - -struct libusb_device; +#include "base/scoped_generic.h" +#include "third_party/libusb/src/libusb/libusb.h" namespace device { -class UsbContext; +struct LibusbDeviceRefTraits { + static libusb_device* InvalidValue() { return nullptr; } -// This class owns a reference to a libusb_device as well as a reference to -// the libusb_context. The libusb_context must outlive any libusb_device -// instances created from it. -class ScopedLibusbDeviceRef { - public: - ScopedLibusbDeviceRef(libusb_device* device, - scoped_refptr<UsbContext> context); - ScopedLibusbDeviceRef(ScopedLibusbDeviceRef&& other); - ~ScopedLibusbDeviceRef(); - - libusb_device* get() const { return device_; } - - scoped_refptr<UsbContext> GetContext() const { return context_; } - - void Reset(); - bool IsValid() const; - - private: - libusb_device* device_; - scoped_refptr<UsbContext> context_; - - DISALLOW_COPY_AND_ASSIGN(ScopedLibusbDeviceRef); + static void Free(libusb_device* device) { libusb_unref_device(device); } }; -bool operator==(const ScopedLibusbDeviceRef& ref, libusb_device* device); +using ScopedLibusbDeviceRef = + base::ScopedGeneric<libusb_device*, LibusbDeviceRefTraits>; } // namespace device
diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc index b8c2307a..cce0691 100644 --- a/device/usb/usb_device_handle_impl.cc +++ b/device/usb/usb_device_handle_impl.cc
@@ -311,7 +311,7 @@ libusb_fill_control_setup(buffer->front(), type, request, value, index, length); libusb_fill_control_transfer(transfer->platform_transfer_, - device_handle->handle(), buffer->front(), + device_handle->handle_, buffer->front(), &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), timeout); @@ -341,7 +341,7 @@ } libusb_fill_bulk_transfer( - transfer->platform_transfer_, device_handle->handle(), endpoint, + transfer->platform_transfer_, device_handle->handle_, endpoint, buffer->front(), length, &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), timeout); @@ -371,7 +371,7 @@ } libusb_fill_interrupt_transfer( - transfer->platform_transfer_, device_handle->handle(), endpoint, + transfer->platform_transfer_, device_handle->handle_, endpoint, buffer->front(), length, &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), timeout); @@ -401,10 +401,10 @@ return nullptr; } - libusb_fill_iso_transfer( - transfer->platform_transfer_, device_handle->handle(), endpoint, - buffer->front(), static_cast<int>(length), num_packets, - &Transfer::PlatformCallback, transfer.get(), timeout); + libusb_fill_iso_transfer(transfer->platform_transfer_, device_handle->handle_, + endpoint, buffer->front(), static_cast<int>(length), + num_packets, &Transfer::PlatformCallback, + transfer.get(), timeout); for (size_t i = 0; i < packet_lengths.size(); ++i) transfer->platform_transfer_->iso_packet_desc[i].length = packet_lengths[i]; @@ -798,14 +798,16 @@ } UsbDeviceHandleImpl::UsbDeviceHandleImpl( + scoped_refptr<UsbContext> context, scoped_refptr<UsbDeviceImpl> device, - ScopedLibusbDeviceHandle handle, + PlatformUsbDeviceHandle handle, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) - : device_(std::move(device)), - handle_(std::move(handle)), + : device_(device), + handle_(handle), + context_(context), task_runner_(base::ThreadTaskRunnerHandle::Get()), blocking_task_runner_(blocking_task_runner) { - DCHECK(handle_.IsValid()) << "Cannot create device with an invalid handle."; + DCHECK(handle) << "Cannot create device with NULL handle."; } UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { @@ -815,19 +817,17 @@ // any thread. libusb is not safe to reentrancy so be sure not to try to close // the device from inside a transfer completion callback. if (blocking_task_runner_->RunsTasksInCurrentSequence()) { - handle_.Reset(); + libusb_close(handle_); } else { - blocking_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(base::DoNothing::Once<ScopedLibusbDeviceHandle>(), - std::move(handle_))); + blocking_task_runner_->PostTask(FROM_HERE, + base::BindOnce(&libusb_close, handle_)); } } void UsbDeviceHandleImpl::SetConfigurationOnBlockingThread( int configuration_value, ResultCallback callback) { - int rv = libusb_set_configuration(handle(), configuration_value); + int rv = libusb_set_configuration(handle_, configuration_value); if (rv != LIBUSB_SUCCESS) { USB_LOG(EVENT) << "Failed to set configuration " << configuration_value << ": " << ConvertPlatformUsbErrorToString(rv); @@ -855,7 +855,7 @@ void UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread( int interface_number, ResultCallback callback) { - int rv = libusb_claim_interface(handle(), interface_number); + int rv = libusb_claim_interface(handle_, interface_number); scoped_refptr<InterfaceClaimer> interface_claimer; if (rv == LIBUSB_SUCCESS) { interface_claimer = @@ -897,7 +897,7 @@ int interface_number, int alternate_setting, ResultCallback callback) { - int rv = libusb_set_interface_alt_setting(handle(), interface_number, + int rv = libusb_set_interface_alt_setting(handle_, interface_number, alternate_setting); if (rv != LIBUSB_SUCCESS) { USB_LOG(EVENT) << "Failed to set interface " << interface_number @@ -930,7 +930,7 @@ } void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread(ResultCallback callback) { - int rv = libusb_reset_device(handle()); + int rv = libusb_reset_device(handle_); if (rv != LIBUSB_SUCCESS) { USB_LOG(EVENT) << "Failed to reset device: " << ConvertPlatformUsbErrorToString(rv); @@ -941,7 +941,7 @@ void UsbDeviceHandleImpl::ClearHaltOnBlockingThread(uint8_t endpoint, ResultCallback callback) { - int rv = libusb_clear_halt(handle(), endpoint); + int rv = libusb_clear_halt(handle_, endpoint); if (rv != LIBUSB_SUCCESS) { USB_LOG(EVENT) << "Failed to clear halt: " << ConvertPlatformUsbErrorToString(rv);
diff --git a/device/usb/usb_device_handle_impl.h b/device/usb/usb_device_handle_impl.h index 32dbe04..acf0332d 100644 --- a/device/usb/usb_device_handle_impl.h +++ b/device/usb/usb_device_handle_impl.h
@@ -17,7 +17,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/threading/thread_checker.h" -#include "device/usb/scoped_libusb_device_handle.h" #include "device/usb/usb_device_handle.h" #include "third_party/libusb/src/libusb/libusb.h" @@ -35,8 +34,10 @@ const UsbEndpointDescriptor* endpoint; }; +class UsbContext; class UsbDeviceImpl; +typedef libusb_device_handle* PlatformUsbDeviceHandle; typedef libusb_iso_packet_descriptor* PlatformUsbIsoPacketDescriptor; typedef libusb_transfer* PlatformUsbTransferHandle; @@ -89,13 +90,14 @@ // This constructor is called by UsbDeviceImpl. UsbDeviceHandleImpl( + scoped_refptr<UsbContext> context, scoped_refptr<UsbDeviceImpl> device, - ScopedLibusbDeviceHandle handle, + PlatformUsbDeviceHandle handle, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); ~UsbDeviceHandleImpl() override; - libusb_device_handle* handle() const { return handle_.get(); } + PlatformUsbDeviceHandle handle() const { return handle_; } private: class InterfaceClaimer; @@ -172,7 +174,7 @@ scoped_refptr<UsbDeviceImpl> device_; - ScopedLibusbDeviceHandle handle_; + PlatformUsbDeviceHandle handle_; typedef std::map<int, scoped_refptr<InterfaceClaimer>> ClaimedInterfaceMap; ClaimedInterfaceMap claimed_interfaces_; @@ -184,6 +186,10 @@ typedef std::map<int, EndpointMapValue> EndpointMap; EndpointMap endpoint_map_; + // Retain the UsbContext so that the platform context will not be destroyed + // before this handle. + scoped_refptr<UsbContext> context_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
diff --git a/device/usb/usb_device_impl.cc b/device/usb/usb_device_impl.cc index d6eb68d..056c6c3 100644 --- a/device/usb/usb_device_impl.cc +++ b/device/usb/usb_device_impl.cc
@@ -28,7 +28,8 @@ namespace device { -UsbDeviceImpl::UsbDeviceImpl(ScopedLibusbDeviceRef platform_device, +UsbDeviceImpl::UsbDeviceImpl(scoped_refptr<UsbContext> context, + ScopedLibusbDeviceRef platform_device, const libusb_device_descriptor& descriptor) : UsbDevice(descriptor.bcdUSB, descriptor.bDeviceClass, @@ -40,8 +41,9 @@ base::string16(), base::string16(), base::string16()), + context_(std::move(context)), platform_device_(std::move(platform_device)) { - CHECK(platform_device_.IsValid()) << "platform_device must be valid"; + CHECK(platform_device_.is_valid()) << "platform_device must be valid"; ReadAllConfigurations(); RefreshActiveConfiguration(); } @@ -102,14 +104,12 @@ scoped_refptr<base::TaskRunner> task_runner, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) { base::AssertBlockingAllowed(); - libusb_device_handle* handle; + PlatformUsbDeviceHandle handle; const int rv = libusb_open(platform_device(), &handle); - ScopedLibusbDeviceHandle scoped_handle(handle, platform_device_.GetContext()); if (LIBUSB_SUCCESS == rv) { task_runner->PostTask( - FROM_HERE, - base::BindOnce(&UsbDeviceImpl::Opened, this, std::move(scoped_handle), - std::move(callback), blocking_task_runner)); + FROM_HERE, base::BindOnce(&UsbDeviceImpl::Opened, this, handle, + std::move(callback), blocking_task_runner)); } else { USB_LOG(EVENT) << "Failed to open device: " << ConvertPlatformUsbErrorToString(rv); @@ -119,12 +119,12 @@ } void UsbDeviceImpl::Opened( - ScopedLibusbDeviceHandle platform_handle, + PlatformUsbDeviceHandle platform_handle, OpenCallback callback, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) { DCHECK(thread_checker_.CalledOnValidThread()); scoped_refptr<UsbDeviceHandle> device_handle = new UsbDeviceHandleImpl( - this, std::move(platform_handle), blocking_task_runner); + context_, this, platform_handle, blocking_task_runner); handles().push_back(device_handle.get()); std::move(callback).Run(device_handle); }
diff --git a/device/usb/usb_device_impl.h b/device/usb/usb_device_impl.h index 9e3d2c7..16ab891 100644 --- a/device/usb/usb_device_impl.h +++ b/device/usb/usb_device_impl.h
@@ -21,7 +21,9 @@ #include "device/usb/usb_descriptors.h" #include "device/usb/usb_device.h" +struct libusb_device; struct libusb_device_descriptor; +struct libusb_device_handle; namespace base { class SequencedTaskRunner; @@ -29,12 +31,15 @@ namespace device { -class ScopedLibusbDeviceHandle; class UsbDeviceHandleImpl; +class UsbContext; + +typedef struct libusb_device_handle* PlatformUsbDeviceHandle; class UsbDeviceImpl : public UsbDevice { public: - UsbDeviceImpl(ScopedLibusbDeviceRef platform_device, + UsbDeviceImpl(scoped_refptr<UsbContext> context, + ScopedLibusbDeviceRef platform_device, const libusb_device_descriptor& descriptor); // UsbDevice implementation: @@ -74,13 +79,15 @@ OpenCallback callback, scoped_refptr<base::TaskRunner> task_runner, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); - void Opened(ScopedLibusbDeviceHandle platform_handle, + void Opened(PlatformUsbDeviceHandle platform_handle, OpenCallback callback, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); base::ThreadChecker thread_checker_; bool visited_ = false; + // The libusb_context must not be released before the libusb_device. + const scoped_refptr<UsbContext> context_; const ScopedLibusbDeviceRef platform_device_; DISALLOW_COPY_AND_ASSIGN(UsbDeviceImpl);
diff --git a/device/usb/usb_service_impl.cc b/device/usb/usb_service_impl.cc index 626ece05..83e14c6f0 100644 --- a/device/usb/usb_service_impl.cc +++ b/device/usb/usb_service_impl.cc
@@ -131,7 +131,7 @@ std::vector<ScopedLibusbDeviceRef> scoped_devices; scoped_devices.reserve(device_count); for (ssize_t i = 0; i < device_count; ++i) - scoped_devices.emplace_back(platform_devices[i], usb_context); + scoped_devices.emplace_back(platform_devices[i]); // Free the list but don't unref the devices because ownership has been // been transfered to the elements of |scoped_devices|. @@ -231,7 +231,6 @@ device_observer_(this), #endif weak_factory_(this) { - weak_self_ = weak_factory_.GetWeakPtr(); base::PostTaskWithTraits( FROM_HERE, kBlockingTaskTraits, base::Bind(&InitializeUsbContextOnBlockingThread, task_runner(), @@ -362,7 +361,7 @@ // Mark the existing device object visited and remove it from the list so // it will not be ignored. it->second->set_visited(true); - device.Reset(); + device.reset(); } } @@ -383,7 +382,7 @@ // that have been removed don't remain in |ignored_devices_| indefinitely. ignored_devices_.clear(); for (auto& device : *devices) { - if (device.IsValid()) + if (device.is_valid()) ignored_devices_.push_back(std::move(device)); } @@ -442,8 +441,8 @@ devices_being_enumerated_.insert(platform_device.get()); - auto device = base::MakeRefCounted<UsbDeviceImpl>(std::move(platform_device), - descriptor); + auto device = base::MakeRefCounted<UsbDeviceImpl>( + context_, std::move(platform_device), descriptor); base::OnceClosure add_device = base::BindOnce(&UsbServiceImpl::AddDevice, weak_factory_.GetWeakPtr(), refresh_complete, device); @@ -459,8 +458,7 @@ libusb_ref_device(device->platform_device()); base::OnceClosure enumeration_failed = base::BindOnce( &UsbServiceImpl::EnumerationFailed, weak_factory_.GetWeakPtr(), - ScopedLibusbDeviceRef(device->platform_device(), context_), - refresh_complete); + ScopedLibusbDeviceRef(device->platform_device()), refresh_complete); device->Open(base::BindOnce( &OnDeviceOpenedReadDescriptors, descriptor.iManufacturer, @@ -520,18 +518,18 @@ // libusb does not transfer ownership of |device_raw| to this function so a // reference must be taken here. libusb_ref_device(device_raw); - ScopedLibusbDeviceRef device(device_raw, self->context_); + ScopedLibusbDeviceRef device(device_raw); switch (event) { case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: self->task_runner()->PostTask( FROM_HERE, base::BindOnce(&UsbServiceImpl::OnPlatformDeviceAdded, - self->weak_self_, std::move(device))); + base::Unretained(self), std::move(device))); break; case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: self->task_runner()->PostTask( FROM_HERE, base::BindOnce(&UsbServiceImpl::OnPlatformDeviceRemoved, - self->weak_self_, std::move(device))); + base::Unretained(self), std::move(device))); break; default: NOTREACHED();
diff --git a/device/usb/usb_service_impl.h b/device/usb/usb_service_impl.h index 36f7115..e7e89d0 100644 --- a/device/usb/usb_service_impl.h +++ b/device/usb/usb_service_impl.h
@@ -122,10 +122,6 @@ ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_; #endif // OS_WIN - // This WeakPtr is used to safely post hotplug events back to the thread this - // object lives on. - base::WeakPtr<UsbServiceImpl> weak_self_; - base::WeakPtrFactory<UsbServiceImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(UsbServiceImpl);
diff --git a/device/vr/BUILD.gn b/device/vr/BUILD.gn index f0a7cb1..9a11ad0d 100644 --- a/device/vr/BUILD.gn +++ b/device/vr/BUILD.gn
@@ -160,8 +160,6 @@ "test/fake_vr_display_impl_client.h", "test/fake_vr_service_client.cc", "test/fake_vr_service_client.h", - "test/mock_vr_display_impl.cc", - "test/mock_vr_display_impl.h", "vr_export.h", ]
diff --git a/device/vr/android/gvr/gvr_device.cc b/device/vr/android/gvr/gvr_device.cc index 20166c65..9d4c9b17 100644 --- a/device/vr/android/gvr/gvr_device.cc +++ b/device/vr/android/gvr/gvr_device.cc
@@ -179,32 +179,31 @@ void GvrDevice::RequestSession( mojom::XRDeviceRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) { + if (!options->immersive) { + // TODO(https://crbug.com/695937): This should be NOTREACHED() once we no + // longer need the hacked GRV non-immersive mode. + ReturnNonImmersiveSession(std::move(callback)); + return; + } + GvrDelegateProvider* delegate_provider = GetGvrDelegateProvider(); if (!delegate_provider) { std::move(callback).Run(nullptr, nullptr); return; } - if (options->immersive) { - // StartWebXRPresentation is async as we may trigger a DON (Device ON) flow - // that pauses Chrome. - delegate_provider->StartWebXRPresentation( - GetVRDisplayInfo(), std::move(options), - base::BindOnce(&GvrDevice::OnStartPresentResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); - } else { - // TODO(https://crbug.com/695937): This should be NOTREACHED() once - // orientation device handles non-immersive VR sessions. - // TODO(https://crbug.com/842025): Handle this when RequestSession is called - // for non-immersive sessions. - NOTREACHED(); - } + // StartWebXRPresentation is async as we may trigger a DON (Device ON) flow + // that pauses Chrome. + delegate_provider->StartWebXRPresentation( + GetVRDisplayInfo(), std::move(options), + base::BindOnce(&GvrDevice::OnStartPresentResult, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void GvrDevice::OnStartPresentResult( mojom::XRRuntime::RequestSessionCallback callback, mojom::XRSessionPtr session) { - if (!session || !session->connection) { + if (!session) { std::move(callback).Run(nullptr, nullptr); return; } @@ -223,8 +222,7 @@ base::BindOnce(&GvrDevice::OnPresentingControllerMojoConnectionError, base::Unretained(this))); - std::move(callback).Run(std::move(session->connection), - std::move(session_controller)); + std::move(callback).Run(std::move(session), std::move(session_controller)); } // XRSessionController @@ -246,7 +244,7 @@ } void GvrDevice::OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { mojom::XRFrameDataPtr frame_data = mojom::XRFrameData::New(); frame_data->pose = GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), nullptr);
diff --git a/device/vr/android/gvr/gvr_device.h b/device/vr/android/gvr/gvr_device.h index 6061fcbe..e401efc0 100644 --- a/device/vr/android/gvr/gvr_device.h +++ b/device/vr/android/gvr/gvr_device.h
@@ -42,7 +42,7 @@ // VRDeviceBase void OnListeningForActivate(bool listening) override; void OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) override; + mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; void OnStartPresentResult(mojom::XRRuntime::RequestSessionCallback callback, mojom::XRSessionPtr session);
diff --git a/device/vr/oculus/oculus_device.cc b/device/vr/oculus/oculus_device.cc index 51b2627..eeb68ee 100644 --- a/device/vr/oculus/oculus_device.cc +++ b/device/vr/oculus/oculus_device.cc
@@ -113,6 +113,11 @@ void OculusDevice::RequestSession( mojom::XRDeviceRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) { + if (!options->immersive) { + ReturnNonImmersiveSession(std::move(callback)); + return; + } + StopOvrSession(); if (!render_loop_->IsRunning()) @@ -137,9 +142,7 @@ void OculusDevice::OnRequestSessionResult( mojom::XRRuntime::RequestSessionCallback callback, bool result, - mojom::VRSubmitFrameClientRequest request, - mojom::VRPresentationProviderPtrInfo provider_info, - mojom::VRDisplayFrameTransportOptionsPtr transport_options) { + mojom::XRSessionPtr session) { if (!result) { std::move(callback).Run(nullptr, nullptr); @@ -150,11 +153,6 @@ OnStartPresenting(); - auto connection = mojom::XRPresentationConnection::New(); - connection->client_request = std::move(request); - connection->provider = std::move(provider_info); - connection->transport_options = std::move(transport_options); - mojom::XRSessionControllerPtr session_controller; exclusive_controller_binding_.Bind(mojo::MakeRequest(&session_controller)); @@ -164,7 +162,7 @@ base::BindOnce(&OculusDevice::OnPresentingControllerMojoConnectionError, base::Unretained(this))); - std::move(callback).Run(std::move(connection), std::move(session_controller)); + std::move(callback).Run(std::move(session), std::move(session_controller)); if (!oculus_gamepad_factory_) { oculus_gamepad_factory_ = @@ -227,7 +225,7 @@ } void OculusDevice::OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { if (!session_) { std::move(callback).Run(nullptr); return;
diff --git a/device/vr/oculus/oculus_device.h b/device/vr/oculus/oculus_device.h index cff84ccd..9002ac33 100644 --- a/device/vr/oculus/oculus_device.h +++ b/device/vr/oculus/oculus_device.h
@@ -31,13 +31,10 @@ mojom::XRDeviceRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) override; void OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) override; - void OnRequestSessionResult( - mojom::XRRuntime::RequestSessionCallback callback, - bool result, - mojom::VRSubmitFrameClientRequest request, - mojom::VRPresentationProviderPtrInfo provider_info, - mojom::VRDisplayFrameTransportOptionsPtr transport_options); + mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; + void OnRequestSessionResult(mojom::XRRuntime::RequestSessionCallback callback, + bool result, + mojom::XRSessionPtr session); bool IsInitialized() { return !!session_; }
diff --git a/device/vr/oculus/oculus_render_loop.cc b/device/vr/oculus/oculus_render_loop.cc index 80a37b6e..f914b14 100644 --- a/device/vr/oculus/oculus_render_loop.cc +++ b/device/vr/oculus/oculus_render_loop.cc
@@ -48,7 +48,8 @@ on_controller_updated) : base::Thread("OculusRenderLoop"), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), - binding_(this), + presentation_binding_(this), + frame_data_binding_(this), on_presentation_ended_(on_presentation_ended), on_controller_updated_(on_controller_updated), weak_ptr_factory_(this) { @@ -69,7 +70,8 @@ void OculusRenderLoop::CleanUp() { submit_client_ = nullptr; StopOvrSession(); - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); } void OculusRenderLoop::SubmitFrameMissing(int16_t frame_index, @@ -241,28 +243,36 @@ #endif ) { main_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), false, nullptr, nullptr, nullptr)); + FROM_HERE, base::BindOnce(std::move(callback), false, nullptr)); return; } - binding_.Close(); - device::mojom::VRPresentationProviderPtr provider; - binding_.Bind(mojo::MakeRequest(&provider)); + presentation_binding_.Close(); + frame_data_binding_.Close(); + device::mojom::XRPresentationProviderPtr presentation_provider; + device::mojom::XRFrameDataProviderPtr frame_data_provider; + presentation_binding_.Bind(mojo::MakeRequest(&presentation_provider)); + frame_data_binding_.Bind(mojo::MakeRequest(&frame_data_provider)); - device::mojom::VRDisplayFrameTransportOptionsPtr transport_options = - device::mojom::VRDisplayFrameTransportOptions::New(); + device::mojom::XRPresentationTransportOptionsPtr transport_options = + device::mojom::XRPresentationTransportOptions::New(); transport_options->transport_method = - device::mojom::VRDisplayFrameTransportMethod::SUBMIT_AS_TEXTURE_HANDLE; + device::mojom::XRPresentationTransportMethod::SUBMIT_AS_TEXTURE_HANDLE; // Only set boolean options that we need. Default is false, and we should be // able to safely ignore ones that our implementation doesn't care about. transport_options->wait_for_transfer_notification = true; + auto submit_frame_sink = device::mojom::XRPresentationConnection::New(); + submit_frame_sink->provider = presentation_provider.PassInterface(); + submit_frame_sink->client_request = mojo::MakeRequest(&submit_client_); + submit_frame_sink->transport_options = std::move(transport_options); + + auto session = device::mojom::XRSession::New(); + session->data_provider = frame_data_provider.PassInterface(); + session->submit_frame_sink = std::move(submit_frame_sink); + main_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), true, - mojo::MakeRequest(&submit_client_), - provider.PassInterface(), std::move(transport_options))); + FROM_HERE, base::BindOnce(std::move(callback), true, std::move(session))); is_presenting_ = true; } @@ -296,7 +306,8 @@ void OculusRenderLoop::ExitPresent() { is_presenting_ = false; - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); submit_client_ = nullptr; ClearPendingFrame(); @@ -312,7 +323,7 @@ } void OculusRenderLoop::GetFrameData( - mojom::VRPresentationProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { DCHECK(is_presenting_); if (has_outstanding_frame_) {
diff --git a/device/vr/oculus/oculus_render_loop.h b/device/vr/oculus/oculus_render_loop.h index c8186b7..26cfdd5 100644 --- a/device/vr/oculus/oculus_render_loop.h +++ b/device/vr/oculus/oculus_render_loop.h
@@ -23,13 +23,12 @@ const int kMaxOculusRenderLoopInputId = (ovrControllerType_Remote + 1); -class OculusRenderLoop : public base::Thread, mojom::VRPresentationProvider { +class OculusRenderLoop : public base::Thread, + mojom::XRPresentationProvider, + mojom::XRFrameDataProvider { public: using RequestSessionCallback = - base::OnceCallback<void(bool result, - mojom::VRSubmitFrameClientRequest, - mojom::VRPresentationProviderPtrInfo, - mojom::VRDisplayFrameTransportOptionsPtr)>; + base::OnceCallback<void(bool result, mojom::XRSessionPtr)>; OculusRenderLoop( base::RepeatingCallback<void()> on_presentation_ended, @@ -43,7 +42,7 @@ void ExitPresent(); base::WeakPtr<OculusRenderLoop> GetWeakPtr(); - // VRPresentationProvider overrides: + // XRPresentationProvider overrides: void SubmitFrameMissing(int16_t frame_index, const gpu::SyncToken&) override; void SubmitFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox, @@ -58,7 +57,7 @@ const gfx::RectF& right_bounds, const gfx::Size& source_size) override; void GetFrameData( - mojom::VRPresentationProvider::GetFrameDataCallback callback) override; + mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; private: // base::Thread overrides: @@ -98,13 +97,14 @@ gfx::RectF right_bounds_; gfx::Size source_size_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; - mojom::VRSubmitFrameClientPtr submit_client_; + mojom::XRPresentationClientPtr submit_client_; ovrSession session_ = nullptr; ovrGraphicsLuid luid_ = {}; ovrPosef last_render_pose_; ovrTextureSwapChain texture_swap_chain_ = 0; double sensor_time_; - mojo::Binding<mojom::VRPresentationProvider> binding_; + mojo::Binding<mojom::XRPresentationProvider> presentation_binding_; + mojo::Binding<mojom::XRFrameDataProvider> frame_data_binding_; bool primary_input_pressed[kMaxOculusRenderLoopInputId]; base::RepeatingCallback<void()> on_presentation_ended_; base::RepeatingCallback<
diff --git a/device/vr/openvr/openvr_device.cc b/device/vr/openvr/openvr_device.cc index 09ab3ef..e3d4aa2 100644 --- a/device/vr/openvr/openvr_device.cc +++ b/device/vr/openvr/openvr_device.cc
@@ -173,6 +173,11 @@ void OpenVRDevice::RequestSession( mojom::XRDeviceRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) { + if (!options->immersive) { + ReturnNonImmersiveSession(std::move(callback)); + return; + } + if (!render_loop_->IsRunning()) render_loop_->Start(); @@ -211,9 +216,7 @@ void OpenVRDevice::OnRequestSessionResult( mojom::XRRuntime::RequestSessionCallback callback, bool result, - mojom::VRSubmitFrameClientRequest request, - mojom::VRPresentationProviderPtrInfo provider_info, - mojom::VRDisplayFrameTransportOptionsPtr transport_options) { + mojom::XRSessionPtr session) { if (!result) { OnPresentationEnded(); std::move(callback).Run(nullptr, nullptr); @@ -222,11 +225,6 @@ OnStartPresenting(); - auto connection = mojom::XRPresentationConnection::New(); - connection->client_request = std::move(request); - connection->provider = std::move(provider_info); - connection->transport_options = std::move(transport_options); - mojom::XRSessionControllerPtr session_controller; exclusive_controller_binding_.Bind(mojo::MakeRequest(&session_controller)); @@ -236,7 +234,7 @@ base::BindOnce(&OpenVRDevice::OnPresentingControllerMojoConnectionError, base::Unretained(this))); - std::move(callback).Run(std::move(connection), std::move(session_controller)); + std::move(callback).Run(std::move(session), std::move(session_controller)); } // XRSessionController @@ -255,7 +253,7 @@ } void OpenVRDevice::OnMagicWindowFrameDataRequest( - mojom::VRPresentationProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { if (!openvr_) { std::move(callback).Run(nullptr); return;
diff --git a/device/vr/openvr/openvr_device.h b/device/vr/openvr/openvr_device.h index c5af92f..95f4794 100644 --- a/device/vr/openvr/openvr_device.h +++ b/device/vr/openvr/openvr_device.h
@@ -36,19 +36,16 @@ void OnPollingEvents(); - void OnRequestSessionResult( - mojom::XRRuntime::RequestSessionCallback callback, - bool result, - mojom::VRSubmitFrameClientRequest request, - mojom::VRPresentationProviderPtrInfo provider_info, - mojom::VRDisplayFrameTransportOptionsPtr transport_options); + void OnRequestSessionResult(mojom::XRRuntime::RequestSessionCallback callback, + bool result, + mojom::XRSessionPtr session); bool IsInitialized() { return !!openvr_; } private: // VRDeviceBase void OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) override; + mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; // XRSessionController void SetFrameDataRestricted(bool restricted) override;
diff --git a/device/vr/openvr/openvr_render_loop.cc b/device/vr/openvr/openvr_render_loop.cc index fa37e4d..ce598d1 100644 --- a/device/vr/openvr/openvr_render_loop.cc +++ b/device/vr/openvr/openvr_render_loop.cc
@@ -50,7 +50,8 @@ : base::Thread("OpenVRRenderLoop"), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), update_gamepad_(std::move(update_gamepad)), - binding_(this), + presentation_binding_(this), + frame_data_binding_(this), weak_ptr_factory_(this) { DCHECK(main_thread_task_runner_); } @@ -148,7 +149,8 @@ void OpenVRRenderLoop::CleanUp() { submit_client_ = nullptr; - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); } void OpenVRRenderLoop::UpdateLayerBounds(int16_t frame_id, @@ -169,15 +171,15 @@ mojom::XRDeviceRuntimeSessionOptionsPtr options, RequestSessionCallback callback) { DCHECK(options->immersive); - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); if (!openvr_) { openvr_ = std::make_unique<OpenVRWrapper>(true); if (!openvr_->IsInitialized()) { openvr_ = nullptr; main_thread_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), false, nullptr, - nullptr, nullptr)); + FROM_HERE, base::BindOnce(std::move(callback), false, nullptr)); return; } @@ -193,20 +195,22 @@ !texture_helper_.EnsureInitialized()) { openvr_ = nullptr; main_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), false, nullptr, nullptr, nullptr)); + FROM_HERE, base::BindOnce(std::move(callback), false, nullptr)); return; } #endif DCHECK(!on_presentation_ended_); on_presentation_ended_ = std::move(on_presentation_ended); - device::mojom::VRPresentationProviderPtr provider; - binding_.Bind(mojo::MakeRequest(&provider)); - device::mojom::VRDisplayFrameTransportOptionsPtr transport_options = - device::mojom::VRDisplayFrameTransportOptions::New(); + device::mojom::XRPresentationProviderPtr presentation_provider; + device::mojom::XRFrameDataProviderPtr frame_data_provider; + presentation_binding_.Bind(mojo::MakeRequest(&presentation_provider)); + frame_data_binding_.Bind(mojo::MakeRequest(&frame_data_provider)); + + device::mojom::XRPresentationTransportOptionsPtr transport_options = + device::mojom::XRPresentationTransportOptions::New(); transport_options->transport_method = - device::mojom::VRDisplayFrameTransportMethod::SUBMIT_AS_TEXTURE_HANDLE; + device::mojom::XRPresentationTransportMethod::SUBMIT_AS_TEXTURE_HANDLE; // Only set boolean options that we need. Default is false, and we should be // able to safely ignore ones that our implementation doesn't care about. transport_options->wait_for_transfer_notification = true; @@ -220,11 +224,17 @@ input_active_state.controller_role = vr::TrackedControllerRole_Invalid; } + auto submit_frame_sink = device::mojom::XRPresentationConnection::New(); + submit_frame_sink->provider = presentation_provider.PassInterface(); + submit_frame_sink->client_request = mojo::MakeRequest(&submit_client_); + submit_frame_sink->transport_options = std::move(transport_options); + + auto session = device::mojom::XRSession::New(); + session->data_provider = frame_data_provider.PassInterface(); + session->submit_frame_sink = std::move(submit_frame_sink); + main_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), true, - mojo::MakeRequest(&submit_client_), - provider.PassInterface(), std::move(transport_options))); + FROM_HERE, base::BindOnce(std::move(callback), true, std::move(session))); is_presenting_ = true; openvr_->GetCompositor()->SuspendRendering(false); @@ -247,7 +257,8 @@ void OpenVRRenderLoop::ExitPresent() { is_presenting_ = false; - binding_.Close(); + presentation_binding_.Close(); + frame_data_binding_.Close(); submit_client_ = nullptr; if (openvr_) openvr_->GetCompositor()->SuspendRendering(true); @@ -325,7 +336,7 @@ } void OpenVRRenderLoop::GetFrameData( - mojom::VRPresentationProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { DCHECK(is_presenting_); if (has_outstanding_frame_) {
diff --git a/device/vr/openvr/openvr_render_loop.h b/device/vr/openvr/openvr_render_loop.h index df7fdc3..a27f7f4 100644 --- a/device/vr/openvr/openvr_render_loop.h +++ b/device/vr/openvr/openvr_render_loop.h
@@ -25,13 +25,12 @@ class OpenVRWrapper; struct OpenVRGamepadState; -class OpenVRRenderLoop : public base::Thread, mojom::VRPresentationProvider { +class OpenVRRenderLoop : public base::Thread, + mojom::XRPresentationProvider, + mojom::XRFrameDataProvider { public: using RequestSessionCallback = - base::OnceCallback<void(bool result, - mojom::VRSubmitFrameClientRequest, - mojom::VRPresentationProviderPtrInfo, - mojom::VRDisplayFrameTransportOptionsPtr)>; + base::OnceCallback<void(bool result, mojom::XRSessionPtr)>; OpenVRRenderLoop( base::RepeatingCallback<void(OpenVRGamepadState)> update_gamepad); @@ -43,7 +42,7 @@ void ExitPresent(); base::WeakPtr<OpenVRRenderLoop> GetWeakPtr(); - // VRPresentationProvider overrides: + // XRPresentationProvider overrides: void SubmitFrameMissing(int16_t frame_index, const gpu::SyncToken&) override; void SubmitFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox, @@ -58,7 +57,7 @@ const gfx::RectF& right_bounds, const gfx::Size& source_size) override; void GetFrameData( - VRPresentationProvider::GetFrameDataCallback callback) override; + XRFrameDataProvider::GetFrameDataCallback callback) override; private: // base::Thread overrides: @@ -94,11 +93,12 @@ gfx::RectF right_bounds_; gfx::Size source_size_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; - mojom::VRSubmitFrameClientPtr submit_client_; + mojom::XRPresentationClientPtr submit_client_; base::RepeatingCallback<void(OpenVRGamepadState)> update_gamepad_; base::OnceCallback<void()> on_presentation_ended_; std::unique_ptr<OpenVRWrapper> openvr_; - mojo::Binding<mojom::VRPresentationProvider> binding_; + mojo::Binding<mojom::XRPresentationProvider> presentation_binding_; + mojo::Binding<mojom::XRFrameDataProvider> frame_data_binding_; base::WeakPtrFactory<OpenVRRenderLoop> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(OpenVRRenderLoop);
diff --git a/device/vr/orientation/orientation_device.cc b/device/vr/orientation/orientation_device.cc index ee322dd..2de5b21 100644 --- a/device/vr/orientation/orientation_device.cc +++ b/device/vr/orientation/orientation_device.cc
@@ -144,11 +144,11 @@ DCHECK(!options->immersive); // TODO(offenwanger): Perform a check to see if sensors are available when // RequestSession is called for non-immersive sessions. - std::move(callback).Run(nullptr, nullptr); + ReturnNonImmersiveSession(std::move(callback)); } void VROrientationDevice::OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { mojom::VRPosePtr pose = mojom::VRPose::New(); pose->orientation.emplace(4);
diff --git a/device/vr/orientation/orientation_device.h b/device/vr/orientation/orientation_device.h index f9f3b19..0ac5337 100644 --- a/device/vr/orientation/orientation_device.h +++ b/device/vr/orientation/orientation_device.h
@@ -49,7 +49,7 @@ // VRDeviceBase void OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) override; + mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; // Indicates whether the device was able to connect to orientation events. bool IsAvailable() const { return available_; }
diff --git a/device/vr/public/mojom/README.md b/device/vr/public/mojom/README.md index 273b0d5e..dab1c92 100644 --- a/device/vr/public/mojom/README.md +++ b/device/vr/public/mojom/README.md
@@ -6,6 +6,24 @@ the browser process. The ones that cannot live in the browser, are hosted in a service. +# Supported Session types + +## Magic-window: +Magic window sessions are requested by sites that request poses, but render +through the normal Chrome compositor pipeline. +It serves as a basic mode that requires only some way to get orientation poses. + +## Immersive: +Immersive sessions are where the site wishes to request poses, then render +content back to a display other than chrome. The common case for this is Head +Mounted Displays (HMD), like Vive, Oculus, or Daydream. + +## Enviroment Integration +This type of session allows for enviroment integration by providing functions +that allow the site to query the enviroment, such as HitTest. A Enviroment +Integration session may also supply data in addition to the pose, such as a +camera frame. + # Renderer <-> Browser interfaces (defined in vr_service.mojom) VRService - lives in the browser process, corresponds to a single frame. Root object to obtain other XR objects. @@ -24,23 +42,23 @@ process. They may live in the browser process or may live in the isolated service. -## Presentation-related: -Presentation is exclusive access to a headset where a site may display -a stereo view to the user. -VRPresentationProvider - lives in the XRDevice process. Implements the details +## Data related: +All sessions need to be able to get data from a XR device. + +XRFrameDataProvider - lives in the XRDevice process. Provides a way to obtain +poses and other forms of data needed to render frames. + +## Presentation related: +Presentation is exclusive access to a device, where the experience takes over +the device's display, such as presenting a stereo view in an HMD. + +XRPresentationProvider - lives in the XRDevice process. Implements the details for a presentation session, such as submitting frames to the underlying VR API. -VRSubmitFrameClient - lives in the renderer process. Is notified when various +XRPresentationClient - lives in the renderer process. Is notified when various rendering events occur, so it can reclaim/reuse textures. -## Magic-window related: -Magic window is a mode where a site may request poses, but renders through the -normal Chrome compositor pipeline. - -VRMagicWindowProvider - lives in the XRDevice process. Provides a way to obtain -poses. - # Browser <-> Device interfaces (defined in isolated_xr_service.mojom) The XRDevice process may be the browser process or an isolated service for different devices implementations. A device provider in the browser will choose
diff --git a/device/vr/public/mojom/isolated_xr_service.mojom b/device/vr/public/mojom/isolated_xr_service.mojom index a1bcacda..83320de 100644 --- a/device/vr/public/mojom/isolated_xr_service.mojom +++ b/device/vr/public/mojom/isolated_xr_service.mojom
@@ -6,10 +6,10 @@ import "device/vr/public/mojom/vr_service.mojom"; -// The XRSessionController lives in the vr device service, and corresponds to a -// VRPresentationProvider or a VRMagicWindowProvider. The client is the browser -// process, which will pause or stop sessions depending events/state such as -// focus or other tabs requesting presentation. +// The XRSessionController lives in the vr device service, and corresponds to +// a set of the XRSession bindings. The client is the browser process, which +// will pause or stop sessions depending events/state such as focus or other +// tabs requesting immersive sessions. // Sessions are stopped by closing the mojo connection. interface XRSessionController { // A session may be paused temporarily for example when a non-presenting @@ -58,22 +58,14 @@ // browser process is the client, and may in turn expose device information to // render processes using vr_service interfaces, such as VRDisplayHost. interface XRRuntime { - // Attempt to start a presentation session. Clients may submit graphics to be - // displayed in the headset. Called by the browser process, but the - // VRPresentationProvider may be passed to the renderer process to allow - // submitting graphics without going through an extra IPC hop through the - // browser process. + // Attempt to start a session. Called by the browser process, but the result + // will probably be passed to the renderer process to allow getting data and + // possibly submitting graphics without going through an extra IPC hop through + // the browser process. RequestSession(XRDeviceRuntimeSessionOptions options) => ( - device.mojom.XRPresentationConnection? connection, + XRSession? session, XRSessionController? controller); - // Attempt to start a "magic window" session. Magic window sessions allow - // Clients to obtain poses (device position and orientation), but rendering - // goes through the standard Chrome compositor. - RequestMagicWindowSession() => - (device.mojom.VRMagicWindowProvider? session, - device.mojom.XRSessionController? controller); - // The browser may register for changes to a device. Initial VRDisplayInfo // will immediately be returned to the listener to prevent races. ListenToDeviceChanges(XRRuntimeEventListener listener) =>
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom index 108c4291..a00fd3c 100644 --- a/device/vr/public/mojom/vr_service.mojom +++ b/device/vr/public/mojom/vr_service.mojom
@@ -41,17 +41,25 @@ bool use_legacy_webvr_render_path; }; -// TODO(offenwanger) Rearrange these two interfaces to merge duplicate -// functionality. +// This structure contains all the mojo interfaces for different kinds of +// XRSession. The only interface required by all sessions is the +// XRFrameDataProvider. It must always be present. Other interfaces are set as +// apropriate based on the session creation options. (for example, an immersive +// session ought to have a XRPresentationConnection to submit the frames to the +// immersive enviroment). struct XRSession { - VRMagicWindowProvider? magic_window_provider; - XRPresentationConnection? connection; + XRFrameDataProvider data_provider; + XRPresentationConnection? submit_frame_sink; + XREnviromentIntegrationProvider? enviroment_provider; }; +// This structure contains the infomation and interfaces needed to create a two +// way connection between the renderer and a device to synchronize and submit +// frames to a sink outside of Chrome. struct XRPresentationConnection { - VRSubmitFrameClient& client_request; - VRPresentationProvider provider; - VRDisplayFrameTransportOptions transport_options; + XRPresentationProvider provider; + XRPresentationClient& client_request; + XRPresentationTransportOptions transport_options; }; struct XRInputSourceDescription { @@ -171,7 +179,7 @@ }; // Frame transport method from the Renderer's point of view. -enum VRDisplayFrameTransportMethod { +enum XRPresentationTransportMethod { NONE = 0, // Renderer should create a new texture handle (Windows) or @@ -185,10 +193,10 @@ DRAW_INTO_TEXTURE_MAILBOX = 3, }; -struct VRDisplayFrameTransportOptions { - VRDisplayFrameTransportMethod transport_method; +struct XRPresentationTransportOptions { + XRPresentationTransportMethod transport_method; - // Booleans indicating which of the VRSubmitFrameClient callbacks + // Booleans indicating which of the XRPresentationClient callbacks // are in use. Default is false, the device implementation should set // the ones to true that it needs and can ignore the rest. bool wait_for_transfer_notification; @@ -249,40 +257,6 @@ VRDisplayInfo display_info); }; -// After submitting a frame, the VRPresentationProvider will notify the client -// about several stages of the render pipeline. This allows pipelining -// efficiency. Following VRPresentationProvider::Submit*, the submitted frame -// will be transferred (read from, perhaps copied to another texture), and then -// rendered (submitted to the underlying VR API). -// The client lives in the render process, implemented by VRDisplay. -// -// See VRDisplayFrameTransportConfiguration which configures which of these -// callbacks are in use. -interface VRSubmitFrameClient { - // The VRPresentationProvider calls this to indicate that the submitted frame - // has been transferred, so the backing data (mailbox or GpuMemoryBuffer) can - // be reused or discarded. Note that this is a convenience/optimization - // feature, not a security feature - if a site discards the data early we may - // drop a frame, but nothing will otherwise misbehave. - // When the frame wasn't successfully transferred, the client should create a - // new mailbox/GpuMemoryBuffer rather than reusing an existing one to recover - // for subsequent frames. - OnSubmitFrameTransferred(bool success); - - // The VRPresentationProvider calls this after the frame was handed off to the - // underlying VR API. This allows some pipelining of CPU/GPU work, while - // delaying expensive tasks for a subsequent frame until the current frame has - // completed. - OnSubmitFrameRendered(); - - // This callback provides a GpuFence corresponding to the previous frame's - // rendering completion, intended for use with a server wait issued before - // the following wait to prevent its rendering work from competing with - // the previous frame. - OnSubmitFrameGpuFence(gfx.mojom.GpuFenceHandle gpu_fence_handle); -}; - - // Provides a communication channel from the renderer to the browser-side host // of a (device/) VrDisplayImpl. interface VRDisplayHost { @@ -298,47 +272,44 @@ ExitPresent(); }; -// Provides the necessary functionality for a non-presenting WebXR session to -// draw magic window content. +// Provides the necessary functionality for a WebXR session to get data for +// drawing frames. The kind of data it gets depends on what kind of session was +// requested. // This interface is hosted in the Browser process, but will move to a sandboxed // utility process on Windows. The render process communicates with it. -// For AR displays (VRDisplayCapabilities.can_provide_pass_through_images -// is true), clients can use GetFrameData to get images. -// TODO(836478): rename VRMagicWindowProvider to NonImmersiveWindowProvider or -// similar. -interface VRMagicWindowProvider { +interface XRFrameDataProvider { // frame_data is optional and will not be set if and only if the call fails // for some reason, such as device disconnection. GetFrameData() => (XRFrameData? frame_data); +}; - // Different devices can have different native orientations - 0 - // is the native orientation, and then increments of 90 degrees - // from there. +// Provides functionality for integrating enviroment information into an +// XRSession. For example, some AR sessions would implement hit test to allow +// developers to get the information about the world that its sensors supply. +interface XREnviromentIntegrationProvider { + // Different devices can have different native orientations - 0 is the native + // orientation, and then increments of 90 degrees from there. Session geometry + // is needed by the device when integrating enviroment image data, i.e. camera + // feeds, into a session. UpdateSessionGeometry( gfx.mojom.Size frame_size, display.mojom.Rotation display_rotation); - // Performs a raycast into the magic window scene and returns a list of - // XRHitResults sorted from closest to furthest hit from the ray. Each - // hit result contains a hit_matrix containing the transform of the hit - // where the rotation represents the normal of the surface hit. + // Performs a raycast into the scene and returns a list of XRHitResults sorted + // from closest to furthest hit from the ray. Each hit result contains a + // hit_matrix containing the transform of the hit where the rotation + // represents the normal of the surface hit. // An empty result list means there were no hits. If a nullopt is returned, // there was an error. - // TODO(https://crbug.com/842025): have one "session" type, merging - // VRMagicWindowProvider and VRPresentationProvider because RequestHitTest - // makes sense for both types of sessions. RequestHitTest(XRRay ray) => (array<XRHitResult>? results); }; -// Provides the necessary functionality for a presenting WebVR page to draw -// frames for a VrDisplay. +// Provides the necessary functionality for sending frames to a headset. // This interface is hosted in the Browser process, but will move to a sandboxed // utility process on Windows. The render process communicates with it. -interface VRPresentationProvider { - // frame_data is optional and will not be set if and only if the call fails - // for some reason, such as device disconnection. - GetFrameData() => (XRFrameData? frame_data); - +interface XRPresentationProvider { + // This function tells the device which parts of the canvas should be rendered + // to which view. UpdateLayerBounds(int16 frame_id, gfx.mojom.RectF left_bounds, gfx.mojom.RectF right_bounds, gfx.mojom.Size source_size); @@ -346,26 +317,59 @@ // ensure that every GetFrameData has a matching Submit call. This happens for // WebXR if there were no drawing operations to the opaque framebuffer, and // for WebVR 1.1 if the application didn't call SubmitFrame. Usable with any - // VRDisplayFrameTransportMethod. This path does *not* call the + // XRPresentationTransportMethod. This path does *not* call the // SubmitFrameClient methods such as OnSubmitFrameTransferred. This is // intended to help separate frames while presenting, it may or may not // be called for the last animating frame when presentation ends. SubmitFrameMissing(int16 frame_id, gpu.mojom.SyncToken sync_token); - // VRDisplayFrameTransportMethod SUBMIT_AS_MAILBOX_HOLDER + // XRPresentationTransportMethod SUBMIT_AS_MAILBOX_HOLDER SubmitFrame(int16 frame_id, gpu.mojom.MailboxHolder mailbox_holder, mojo_base.mojom.TimeDelta time_waited); - // VRDisplayFrameTransportMethod SUBMIT_AS_TEXTURE_HANDLE + // XRPresentationTransportMethod SUBMIT_AS_TEXTURE_HANDLE // TODO(https://crbug.com/676224): Support preprocessing of mojom files, since // this is Windows only. SubmitFrameWithTextureHandle(int16 frameId, handle texture); - // VRDisplayFrameTransportMethod DRAW_INTO_TEXTURE_MAILBOX + // XRPresentationTransportMethod DRAW_INTO_TEXTURE_MAILBOX SubmitFrameDrawnIntoTexture(int16 frameId, gpu.mojom.SyncToken sync_token, mojo_base.mojom.TimeDelta time_waited); }; +// After submitting a frame, the XRPresentationProvider will notify the client +// about several stages of the render pipeline. This allows pipelining +// efficiency. Following XRPresentationProvider::Submit*, the submitted frame +// will be transferred (read from, perhaps copied to another texture), and then +// rendered (submitted to the underlying VR API). +// The client lives in the render process. +// +// See XRPresentationTransportOptions which configures which of these +// callbacks are in use. +interface XRPresentationClient { + // The XRPresentationProvider calls this to indicate that the submitted frame + // has been transferred, so the backing data (mailbox or GpuMemoryBuffer) can + // be reused or discarded. Note that this is a convenience/optimization + // feature, not a security feature - if a site discards the data early we may + // drop a frame, but nothing will otherwise misbehave. + // When the frame wasn't successfully transferred, the client should create a + // new mailbox/GpuMemoryBuffer rather than reusing an existing one to recover + // for subsequent frames. + OnSubmitFrameTransferred(bool success); + + // The XRPresentationProvider calls this after the frame was handed off to the + // underlying VR API. This allows some pipelining of CPU/GPU work, while + // delaying expensive tasks for a subsequent frame until the current frame has + // completed. + OnSubmitFrameRendered(); + + // This callback provides a GpuFence corresponding to the previous frame's + // rendering completion, intended for use with a server wait issued before + // the following wait to prevent its rendering work from competing with + // the previous frame. + OnSubmitFrameGpuFence(gfx.mojom.GpuFenceHandle gpu_fence_handle); +}; + interface VRDisplayClient { OnChanged(VRDisplayInfo display); OnExitPresent();
diff --git a/device/vr/test/fake_vr_device.cc b/device/vr/test/fake_vr_device.cc index 4a5740d..626a2953 100644 --- a/device/vr/test/fake_vr_device.cc +++ b/device/vr/test/fake_vr_device.cc
@@ -54,18 +54,9 @@ mojom::XRDeviceRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) { OnStartPresenting(); - - mojom::XRSessionControllerPtr exclusive_session_controller; - controller_binding_.Bind(mojo::MakeRequest(&exclusive_session_controller)); - - // Unretained is safe because the error handler won't be called after - // controller_binding_ is destroyed. - controller_binding_.set_connection_error_handler( - base::BindOnce(&FakeVRDevice::OnPresentingControllerMojoConnectionError, - base::Unretained(this))); - - std::move(callback).Run(mojom::XRPresentationConnection::New(), - std::move(exclusive_session_controller)); + // The current tests never use the return values, so it's fine to return + // invalid data here. + std::move(callback).Run(nullptr, nullptr); } void FakeVRDevice::OnPresentingControllerMojoConnectionError() { @@ -74,7 +65,7 @@ } void FakeVRDevice::OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { mojom::XRFrameDataPtr frame_data = mojom::XRFrameData::New(); frame_data->pose = pose_.Clone(); std::move(callback).Run(std::move(frame_data));
diff --git a/device/vr/test/fake_vr_device.h b/device/vr/test/fake_vr_device.h index cfe8601..4e7c70a 100644 --- a/device/vr/test/fake_vr_device.h +++ b/device/vr/test/fake_vr_device.h
@@ -35,7 +35,7 @@ void OnPresentingControllerMojoConnectionError(); void OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) override; + mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; mojom::VRDisplayInfoPtr InitBasicDevice(); mojom::VREyeParametersPtr InitEye(float fov, float offset, uint32_t size);
diff --git a/device/vr/test/mock_vr_display_impl.cc b/device/vr/test/mock_vr_display_impl.cc deleted file mode 100644 index 4c63aeb..0000000 --- a/device/vr/test/mock_vr_display_impl.cc +++ /dev/null
@@ -1,20 +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. - -#include "device/vr/test/mock_vr_display_impl.h" - -namespace device { - -MockVRDisplayImpl::MockVRDisplayImpl( - device::VRDeviceBase* device, - mojom::VRMagicWindowProviderRequest session, - mojom::XRSessionControllerRequest controller, - bool is_frame_focused) - : VRDisplayImpl(device, std::move(session), std::move(controller)) { - SetFrameDataRestricted(!is_frame_focused); -} - -MockVRDisplayImpl::~MockVRDisplayImpl() = default; - -} // namespace device
diff --git a/device/vr/test/mock_vr_display_impl.h b/device/vr/test/mock_vr_display_impl.h deleted file mode 100644 index 32d0e1b8..0000000 --- a/device/vr/test/mock_vr_display_impl.h +++ /dev/null
@@ -1,39 +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 DEVICE_VR_TEST_MOCK_VR_DISPLAY_IMPL_H -#define DEVICE_VR_TEST_MOCK_VR_DISPLAY_IMPL_H - -#include "base/macros.h" -#include "device/vr/vr_display_impl.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace device { - -class MockVRDisplayImpl : public VRDisplayImpl { - public: - MockVRDisplayImpl(device::VRDeviceBase* device, - mojom::VRMagicWindowProviderRequest session, - mojom::XRSessionControllerRequest controller, - bool in_frame_focused); - ~MockVRDisplayImpl() override; - - MOCK_METHOD1(DoOnChanged, void(mojom::VRDisplayInfo* vr_device_info)); - void OnChanged(mojom::VRDisplayInfoPtr vr_device_info) { - DoOnChanged(vr_device_info.get()); - } - - MOCK_METHOD2(OnActivate, - void(mojom::VRDisplayEventReason, base::Callback<void(bool)>)); - - MOCK_METHOD0(ListeningForActivate, bool()); - MOCK_METHOD0(InFocusedFrame, bool()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockVRDisplayImpl); -}; - -} // namespace device - -#endif // DEVICE_VR_TEST_MOCK_VR_DISPLAY_IMPL_H
diff --git a/device/vr/vr_device_base.cc b/device/vr/vr_device_base.cc index 1c7703a..d5f3e5f 100644 --- a/device/vr/vr_device_base.cc +++ b/device/vr/vr_device_base.cc
@@ -53,7 +53,7 @@ } void VRDeviceBase::GetFrameData( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { if (!magic_window_enabled_) { std::move(callback).Run(nullptr); return; @@ -95,7 +95,7 @@ void VRDeviceBase::OnListeningForActivate(bool listening) {} void VRDeviceBase::OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { std::move(callback).Run(nullptr); } @@ -105,18 +105,27 @@ void VRDeviceBase::RequestHitTest( mojom::XRRayPtr ray, - mojom::VRMagicWindowProvider::RequestHitTestCallback callback) { + mojom::XREnviromentIntegrationProvider::RequestHitTestCallback callback) { NOTREACHED() << "Unexpected call to a device without hit-test support"; std::move(callback).Run(base::nullopt); } -void VRDeviceBase::RequestMagicWindowSession( - mojom::XRRuntime::RequestMagicWindowSessionCallback callback) { - mojom::VRMagicWindowProviderPtr provider; +void VRDeviceBase::ReturnNonImmersiveSession( + mojom::XRRuntime::RequestSessionCallback callback) { + mojom::XRFrameDataProviderPtr data_provider; + mojom::XREnviromentIntegrationProviderPtr enviroment_provider; mojom::XRSessionControllerPtr controller; magic_window_sessions_.push_back(std::make_unique<VRDisplayImpl>( - this, mojo::MakeRequest(&provider), mojo::MakeRequest(&controller))); - std::move(callback).Run(std::move(provider), std::move(controller)); + this, mojo::MakeRequest(&data_provider), + mojo::MakeRequest(&enviroment_provider), mojo::MakeRequest(&controller))); + + auto session = mojom::XRSession::New(); + session->data_provider = data_provider.PassInterface(); + // TODO(offenwanger) Not all session will want the enviroment provider. This + // should be refactored so it's only passed when it's requested. + session->enviroment_provider = enviroment_provider.PassInterface(); + + std::move(callback).Run(std::move(session), std::move(controller)); } void VRDeviceBase::EndMagicWindowSession(VRDisplayImpl* session) {
diff --git a/device/vr/vr_device_base.h b/device/vr/vr_device_base.h index 04f6c506..230a0acf 100644 --- a/device/vr/vr_device_base.h +++ b/device/vr/vr_device_base.h
@@ -31,12 +31,11 @@ mojom::XRRuntime::ListenToDeviceChangesCallback callback) final; void SetListeningForActivate(bool is_listening) override; - void GetFrameData( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback); + void GetFrameData(mojom::XRFrameDataProvider::GetFrameDataCallback callback); virtual void RequestHitTest( mojom::XRRayPtr ray, - mojom::VRMagicWindowProvider::RequestHitTestCallback callback); + mojom::XREnviromentIntegrationProvider::RequestHitTestCallback callback); unsigned int GetId() const; bool HasExclusiveSession(); @@ -75,17 +74,16 @@ void OnActivate(mojom::VRDisplayEventReason reason, base::Callback<void(bool)> on_handled); + void ReturnNonImmersiveSession( + mojom::XRRuntime::RequestSessionCallback callback); + std::vector<std::unique_ptr<VRDisplayImpl>> magic_window_sessions_; private: // TODO(https://crbug.com/842227): Rename methods to HandleOnXXX virtual void OnListeningForActivate(bool listening); virtual void OnMagicWindowFrameDataRequest( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback); - - // XRRuntime - void RequestMagicWindowSession( - mojom::XRRuntime::RequestMagicWindowSessionCallback callback) override; + mojom::XRFrameDataProvider::GetFrameDataCallback callback); mojom::XRRuntimeEventListenerPtr listener_;
diff --git a/device/vr/vr_device_base_unittest.cc b/device/vr/vr_device_base_unittest.cc index 5025d3ed..10cdc517 100644 --- a/device/vr/vr_device_base_unittest.cc +++ b/device/vr/vr_device_base_unittest.cc
@@ -11,8 +11,8 @@ #include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/test/fake_vr_device.h" #include "device/vr/test/fake_vr_service_client.h" -#include "device/vr/test/mock_vr_display_impl.h" #include "device/vr/vr_device_base.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace device { @@ -95,14 +95,6 @@ client_ = std::make_unique<FakeVRServiceClient>(mojo::MakeRequest(&proxy)); } - std::unique_ptr<MockVRDisplayImpl> MakeMockDisplay(VRDeviceBase* device) { - mojom::VRMagicWindowProviderPtr session; - mojom::XRSessionControllerPtr controller; - return std::make_unique<testing::NiceMock<MockVRDisplayImpl>>( - device, mojo::MakeRequest(&session), mojo::MakeRequest(&controller), - false); - } - std::unique_ptr<VRDeviceBaseForTesting> MakeVRDevice() { std::unique_ptr<VRDeviceBaseForTesting> device = std::make_unique<VRDeviceBaseForTesting>();
diff --git a/device/vr/vr_display_impl.cc b/device/vr/vr_display_impl.cc index b4e482b..d6b0ce5 100644 --- a/device/vr/vr_display_impl.cc +++ b/device/vr/vr_display_impl.cc
@@ -17,14 +17,13 @@ VRDisplayImpl::VRDisplayImpl( VRDeviceBase* device, - mojom::VRMagicWindowProviderRequest magic_window_request, + mojom::XRFrameDataProviderRequest magic_window_request, + mojom::XREnviromentIntegrationProviderRequest enviroment_request, mojom::XRSessionControllerRequest session_request) - : magic_window_binding_(this), - session_controller_binding_(this), + : magic_window_binding_(this, std::move(magic_window_request)), + enviroment_binding_(this, std::move(enviroment_request)), + session_controller_binding_(this, std::move(session_request)), device_(device) { - magic_window_binding_.Bind(std::move(magic_window_request)); - session_controller_binding_.Bind(std::move(session_request)); - // Unretained is safe because the binding will close when we are destroyed, // so we won't receive any more callbacks after that. session_controller_binding_.set_connection_error_handler(base::BindOnce( @@ -35,7 +34,7 @@ // Gets frame data for sessions. void VRDisplayImpl::GetFrameData( - mojom::VRMagicWindowProvider::GetFrameDataCallback callback) { + mojom::XRFrameDataProvider::GetFrameDataCallback callback) { if (device_->HasExclusiveSession() || restrict_frame_data_) { std::move(callback).Run(nullptr); return; @@ -63,7 +62,7 @@ void VRDisplayImpl::RequestHitTest( mojom::XRRayPtr ray, - mojom::VRMagicWindowProvider::RequestHitTestCallback callback) { + mojom::XREnviromentIntegrationProvider::RequestHitTestCallback callback) { if (restrict_frame_data_) { std::move(callback).Run(base::nullopt); return;
diff --git a/device/vr/vr_display_impl.h b/device/vr/vr_display_impl.h index 0d0bd8f..980798e 100644 --- a/device/vr/vr_display_impl.h +++ b/device/vr/vr_display_impl.h
@@ -20,15 +20,18 @@ class VRDeviceBase; -// VR device process implementation of a VRMagicWindowProvider within a WebVR +// VR device process implementation of a XRFrameDataProvider within a WebVR // or WebXR site session. // VRDisplayImpl objects are owned by their respective XRRuntime instances. // TODO(offenwanger): Rename this. -class DEVICE_VR_EXPORT VRDisplayImpl : public mojom::VRMagicWindowProvider, - public mojom::XRSessionController { +class DEVICE_VR_EXPORT VRDisplayImpl + : public mojom::XRFrameDataProvider, + public mojom::XREnviromentIntegrationProvider, + public mojom::XRSessionController { public: VRDisplayImpl(VRDeviceBase* device, - mojom::VRMagicWindowProviderRequest, + mojom::XRFrameDataProviderRequest, + mojom::XREnviromentIntegrationProviderRequest, mojom::XRSessionControllerRequest); ~VRDisplayImpl() override; @@ -39,7 +42,7 @@ // Accessible to tests. protected: - // mojom::VRMagicWindowProvider + // mojom::XRFrameDataProvider void GetFrameData(GetFrameDataCallback callback) override; void UpdateSessionGeometry(const gfx::Size& frame_size, display::Display::Rotation rotation) override; @@ -51,7 +54,8 @@ void OnMojoConnectionError(); - mojo::Binding<mojom::VRMagicWindowProvider> magic_window_binding_; + mojo::Binding<mojom::XRFrameDataProvider> magic_window_binding_; + mojo::Binding<mojom::XREnviromentIntegrationProvider> enviroment_binding_; mojo::Binding<mojom::XRSessionController> session_controller_binding_; device::VRDeviceBase* device_; bool restrict_frame_data_ = true;
diff --git a/device/vr/vr_display_impl_unittest.cc b/device/vr/vr_display_impl_unittest.cc index 6735be75..d4de7de 100644 --- a/device/vr/vr_display_impl_unittest.cc +++ b/device/vr/vr_display_impl_unittest.cc
@@ -21,13 +21,6 @@ VRDisplayImplTest() {} ~VRDisplayImplTest() override {} void onDisplaySynced() {} - void onPresentComplete( - device::mojom::XRPresentationConnectionPtr connection, - mojom::XRSessionControllerPtr immersive_session_controller) { - is_request_presenting_success_ = connection ? true : false; - - immersive_session_controller_ = std::move(immersive_session_controller); - } protected: void SetUp() override { @@ -39,9 +32,11 @@ std::unique_ptr<VRDisplayImpl> MakeDisplay( mojom::XRSessionControllerPtr* controller) { - mojom::VRMagicWindowProviderPtr session; + mojom::XRFrameDataProviderPtr data_provider; + mojom::XREnviromentIntegrationProviderPtr enviroment_provider; auto display = std::make_unique<VRDisplayImpl>( - device(), mojo::MakeRequest(&session), mojo::MakeRequest(controller)); + device(), mojo::MakeRequest(&data_provider), + mojo::MakeRequest(&enviroment_provider), mojo::MakeRequest(controller)); static_cast<mojom::XRSessionController*>(display.get()) ->SetFrameDataRestricted(true); return display; @@ -50,13 +45,13 @@ void RequestSession(VRDisplayImpl* display_impl) { device_->RequestSession( mojom::XRDeviceRuntimeSessionOptionsPtr(), - base::BindOnce(&VRDisplayImplTest::onPresentComplete, - base::Unretained(this))); + base::BindOnce( + [](device::mojom::XRSessionPtr session, + mojom::XRSessionControllerPtr immersive_session_controller) {})); } void ExitPresent() { device_->StopSession(); - immersive_session_controller_ = nullptr; } bool presenting() { return device_->IsPresenting(); } @@ -64,10 +59,8 @@ FakeVRServiceClient* client() { return client_.get(); } base::MessageLoop message_loop_; - bool is_request_presenting_success_ = false; std::unique_ptr<FakeVRDevice> device_; std::unique_ptr<FakeVRServiceClient> client_; - mojom::XRSessionControllerPtr immersive_session_controller_; DISALLOW_COPY_AND_ASSIGN(VRDisplayImplTest); }; @@ -77,6 +70,7 @@ std::unique_ptr<VRDisplayImpl> display_1 = MakeDisplay(&controller1); static_cast<mojom::XRSessionController*>(display_1.get()) ->SetFrameDataRestricted(false); + mojom::XRSessionControllerPtr controller2; std::unique_ptr<VRDisplayImpl> display_2 = MakeDisplay(&controller2); static_cast<mojom::XRSessionController*>(display_2.get()) @@ -92,31 +86,36 @@ EXPECT_EQ(expect_null, !data); }; - static_cast<mojom::VRMagicWindowProvider*>(display_1.get()) + static_cast<mojom::XRFrameDataProvider*>(display_1.get()) ->GetFrameData(base::BindOnce(callback, false, &was_called)); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(was_called); was_called = false; - static_cast<mojom::VRMagicWindowProvider*>(display_2.get()) + + static_cast<mojom::XRFrameDataProvider*>(display_2.get()) ->GetFrameData(base::BindOnce(callback, false, &was_called)); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(was_called); was_called = false; // Attempt to present. RequestSession(display_1.get()); - EXPECT_TRUE(is_request_presenting_success_); EXPECT_TRUE(presenting()); EXPECT_TRUE(device()->HasExclusiveSession()); - // While a device is presenting, noone should have access to magic window. - static_cast<mojom::VRMagicWindowProvider*>(display_1.get()) + // While a device is presenting, no one should have access to magic window. + static_cast<mojom::XRFrameDataProvider*>(display_1.get()) ->GetFrameData(base::BindOnce(callback, true, &was_called)); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(was_called); was_called = false; - static_cast<mojom::VRMagicWindowProvider*>(display_2.get()) + + static_cast<mojom::XRFrameDataProvider*>(display_2.get()) ->GetFrameData(base::BindOnce(callback, true, &was_called)); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(was_called); was_called = false; @@ -128,13 +127,16 @@ // Once presentation had ended both services should be able to access the // device. - static_cast<mojom::VRMagicWindowProvider*>(display_1.get()) + static_cast<mojom::XRFrameDataProvider*>(display_1.get()) ->GetFrameData(base::BindOnce(callback, false, &was_called)); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(was_called); was_called = false; - static_cast<mojom::VRMagicWindowProvider*>(display_2.get()) + + static_cast<mojom::XRFrameDataProvider*>(display_2.get()) ->GetFrameData(base::BindOnce(callback, false, &was_called)); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(was_called); was_called = false;
diff --git a/extensions/browser/api/socket/BUILD.gn b/extensions/browser/api/socket/BUILD.gn index a707906e..e20046a05 100644 --- a/extensions/browser/api/socket/BUILD.gn +++ b/extensions/browser/api/socket/BUILD.gn
@@ -9,6 +9,8 @@ source_set("socket") { sources = [ + "mojo_data_pump.cc", + "mojo_data_pump.h", "socket.cc", "socket.h", "socket_api.cc",
diff --git a/extensions/browser/api/socket/mojo_data_pump.cc b/extensions/browser/api/socket/mojo_data_pump.cc new file mode 100644 index 0000000..fdc22f73 --- /dev/null +++ b/extensions/browser/api/socket/mojo_data_pump.cc
@@ -0,0 +1,117 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/api/socket/mojo_data_pump.h" + +#include <utility> + +#include "base/memory/ptr_util.h" +#include "net/base/completion_callback.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" + +namespace extensions { + +MojoDataPump::MojoDataPump(mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream) + : receive_stream_(std::move(receive_stream)), + receive_stream_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL), + send_stream_(std::move(send_stream)), + send_stream_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL) { + DCHECK(receive_stream_.is_valid()); + DCHECK(send_stream_.is_valid()); + receive_stream_watcher_.Watch( + receive_stream_.get(), + MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED, + base::BindRepeating(&MojoDataPump::ReceiveMore, base::Unretained(this))); + send_stream_watcher_.Watch( + send_stream_.get(), + MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED, + base::BindRepeating(&MojoDataPump::SendMore, base::Unretained(this))); +} + +MojoDataPump::~MojoDataPump() {} + +void MojoDataPump::Read(int count, ReadCallback callback) { + DCHECK(callback); + DCHECK(!read_callback_); + + if (count <= 0) { + std::move(callback).Run(net::ERR_INVALID_ARGUMENT, nullptr); + return; + } + + read_size_ = count; + read_callback_ = std::move(callback); + receive_stream_watcher_.ArmOrNotify(); +} + +void MojoDataPump::Write(net::IOBuffer* io_buffer, + int io_buffer_size, + net::CompletionOnceCallback callback) { + DCHECK(callback); + DCHECK(!write_callback_); + + write_callback_ = std::move(callback); + pending_write_buffer_ = io_buffer; + pending_write_buffer_size_ = io_buffer_size; + + send_stream_watcher_.ArmOrNotify(); +} + +void MojoDataPump::ReceiveMore(MojoResult result, + const mojo::HandleSignalsState& /* ignored */) { + DCHECK(read_callback_); + DCHECK_NE(0u, read_size_); + + if (result != MOJO_RESULT_OK) { + read_size_ = 0; + std::move(read_callback_).Run(net::ERR_FAILED, nullptr); + return; + } + + uint32_t num_bytes = read_size_; + auto io_buffer = + base::MakeRefCounted<net::IOBuffer>(static_cast<size_t>(num_bytes)); + result = receive_stream_->ReadData(io_buffer->data(), &num_bytes, + MOJO_READ_DATA_FLAG_NONE); + if (result != MOJO_RESULT_OK) { + read_size_ = 0; + std::move(read_callback_).Run(net::ERR_FAILED, nullptr); + return; + } + + if (result == MOJO_RESULT_SHOULD_WAIT) { + receive_stream_watcher_.ArmOrNotify(); + return; + } + read_size_ = 0; + std::move(read_callback_).Run(num_bytes, io_buffer); +} + +void MojoDataPump::SendMore(MojoResult result, + const mojo::HandleSignalsState& state) { + DCHECK(write_callback_); + + uint32_t num_bytes = pending_write_buffer_size_; + result = send_stream_->WriteData(pending_write_buffer_->data(), &num_bytes, + MOJO_WRITE_DATA_FLAG_NONE); + if (result == MOJO_RESULT_SHOULD_WAIT) { + send_stream_watcher_.ArmOrNotify(); + return; + } + pending_write_buffer_ = nullptr; + pending_write_buffer_size_ = 0; + if (result != MOJO_RESULT_OK) { + std::move(write_callback_).Run(net::ERR_FAILED); + return; + } + std::move(write_callback_).Run(num_bytes); +} + +} // namespace extensions
diff --git a/extensions/browser/api/socket/mojo_data_pump.h b/extensions/browser/api/socket/mojo_data_pump.h new file mode 100644 index 0000000..f4f6876 --- /dev/null +++ b/extensions/browser/api/socket/mojo_data_pump.h
@@ -0,0 +1,71 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_API_SOCKET_MOJO_DATA_PUMP_H_ +#define EXTENSIONS_BROWSER_API_SOCKET_MOJO_DATA_PUMP_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "extensions/browser/api/socket/socket.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "mojo/public/cpp/system/simple_watcher.h" +#include "net/base/completion_once_callback.h" + +namespace net { +class IOBuffer; +}; + +namespace extensions { + +// Helper class to read from a mojo consumer handle and write to mojo producer +// handle. +class MojoDataPump { + public: + using ReadCallback = + base::OnceCallback<void(int, scoped_refptr<net::IOBuffer> io_buffer)>; + + MojoDataPump(mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream); + + ~MojoDataPump(); + + // Reads from |receive_stream|. It's illegal to call Read() when a previous + // one hasn't completed yet. + void Read(int count, ReadCallback callback); + + // Writes to |send_stream|. It's illegal to call Write() when a previous one + // hasn't completed yet. + void Write(net::IOBuffer* io_buffer, + int io_buffer_size, + net::CompletionOnceCallback callback); + + // Returns whether a read is pending. + bool HasPendingRead() const { return !read_callback_.is_null(); } + + // Returns whether a write is pending. + bool HasPendingWrite() const { return !write_callback_.is_null(); } + + private: + void OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, int result); + void StartWatching(); + void ReceiveMore(MojoResult result, const mojo::HandleSignalsState& state); + void SendMore(MojoResult result, const mojo::HandleSignalsState& state); + + mojo::ScopedDataPipeConsumerHandle receive_stream_; + mojo::SimpleWatcher receive_stream_watcher_; + mojo::ScopedDataPipeProducerHandle send_stream_; + mojo::SimpleWatcher send_stream_watcher_; + + ReadCallback read_callback_; + net::CompletionOnceCallback write_callback_; + scoped_refptr<net::IOBuffer> pending_write_buffer_; + int pending_write_buffer_size_ = 0; + uint32_t read_size_ = 0; + + DISALLOW_COPY_AND_ASSIGN(MojoDataPump); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_SOCKET_MOJO_DATA_PUMP_H_
diff --git a/extensions/browser/api/socket/socket.cc b/extensions/browser/api/socket/socket.cc index 74f1132d..23dac927 100644 --- a/extensions/browser/api/socket/socket.cc +++ b/extensions/browser/api/socket/socket.cc
@@ -85,20 +85,27 @@ WriteData(); } -bool Socket::SetKeepAlive(bool enable, int delay) { return false; } - -bool Socket::SetNoDelay(bool no_delay) { return false; } - -int Socket::Listen(const std::string& address, - uint16_t port, - int backlog, - std::string* error_msg) { - *error_msg = kSocketTypeNotSupported; - return net::ERR_FAILED; +void Socket::SetKeepAlive(bool enable, + int delay, + SetKeepAliveCallback callback) { + std::move(callback).Run(false); } -void Socket::Accept(const AcceptCompletionCallback& callback) { - callback.Run(net::ERR_FAILED, NULL); +void Socket::SetNoDelay(bool no_delay, SetNoDelayCallback callback) { + std::move(callback).Run(false); +} + +void Socket::Listen(const std::string& address, + uint16_t port, + int backlog, + ListenCallback callback) { + std::move(callback).Run(net::ERR_FAILED, kSocketTypeNotSupported); +} + +void Socket::Accept(AcceptCompletionCallback callback) { + std::move(callback).Run(net::ERR_FAILED, nullptr /* socket */, base::nullopt, + mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); } // static
diff --git a/extensions/browser/api/socket/socket.h b/extensions/browser/api/socket/socket.h index d83b94c..a55eede 100644 --- a/extensions/browser/api/socket/socket.h +++ b/extensions/browser/api/socket/socket.h
@@ -7,6 +7,7 @@ #include <stdint.h> +#include <memory> #include <string> #include <utility> @@ -17,11 +18,13 @@ #include "content/public/browser/browser_thread.h" #include "extensions/browser/api/api_resource.h" #include "extensions/browser/api/api_resource_manager.h" -#include "net/base/completion_callback.h" +#include "net/base/completion_once_callback.h" #include "net/base/io_buffer.h" #include "net/base/ip_endpoint.h" #include "net/socket/tcp_client_socket.h" #include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/mojom/tcp_socket.mojom.h" +#include "services/network/public/mojom/tls_socket.mojom.h" #if defined(OS_CHROMEOS) #include "extensions/browser/api/socket/app_firewall_hole_manager.h" @@ -36,7 +39,9 @@ namespace extensions { using CompletionCallback = base::Callback<void(int)>; -using ReadCompletionCallback = base::Callback< +using SetNoDelayCallback = base::OnceCallback<void(bool)>; +using SetKeepAliveCallback = base::OnceCallback<void(bool)>; +using ReadCompletionCallback = base::OnceCallback< void(int, scoped_refptr<net::IOBuffer> io_buffer, bool socket_destroying)>; using RecvFromCompletionCallback = base::Callback<void(int, @@ -44,8 +49,15 @@ bool socket_destroying, const std::string&, uint16_t)>; +using ListenCallback = + base::OnceCallback<void(int, const std::string& error_msg)>; + using AcceptCompletionCallback = - base::Callback<void(int, std::unique_ptr<net::TCPClientSocket>)>; + base::OnceCallback<void(int, + network::mojom::TCPConnectedSocketPtr, + const base::Optional<net::IPEndPoint>&, + mojo::ScopedDataPipeConsumerHandle, + mojo::ScopedDataPipeProducerHandle)>; // A Socket wraps a low-level socket and includes housekeeping information that // we need to manage it in the context of an extension. @@ -78,7 +90,7 @@ // the remote endpoint. In order to upgrade this socket to TLS, callers // must also supply the hostname of the endpoint via set_hostname(). virtual void Connect(const net::AddressList& address, - const CompletionCallback& callback) = 0; + net::CompletionOnceCallback callback) = 0; // |socket_destroying| is true if disconnect is due to destruction of the // socket. virtual void Disconnect(bool socket_destroying) = 0; @@ -88,7 +100,7 @@ // The |callback| will be called with the number of bytes read into the // buffer, or a negative number if an error occurred. - virtual void Read(int count, const ReadCompletionCallback& callback) = 0; + virtual void Read(int count, ReadCompletionCallback callback) = 0; // The |callback| will be called with |byte_count| or a negative number if an // error occurred. @@ -103,13 +115,15 @@ const net::IPEndPoint& address, const CompletionCallback& callback) = 0; - virtual bool SetKeepAlive(bool enable, int delay); - virtual bool SetNoDelay(bool no_delay); - virtual int Listen(const std::string& address, - uint16_t port, - int backlog, - std::string* error_msg); - virtual void Accept(const AcceptCompletionCallback& callback); + virtual void SetKeepAlive(bool enable, + int delay, + SetKeepAliveCallback callback); + virtual void SetNoDelay(bool no_delay, SetNoDelayCallback callback); + virtual void Listen(const std::string& address, + uint16_t port, + int backlog, + ListenCallback callback); + virtual void Accept(AcceptCompletionCallback callback); virtual bool IsConnected() = 0;
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc index 8f7c8cf..3d33656 100644 --- a/extensions/browser/api/socket/socket_api.cc +++ b/extensions/browser/api/socket/socket_api.cc
@@ -4,7 +4,6 @@ #include "extensions/browser/api/socket/socket_api.h" -#include <memory> #include <utility> #include <vector> @@ -254,7 +253,7 @@ void SocketCreateFunction::Work() { Socket* socket = NULL; if (socket_type_ == kSocketTypeTCP) { - socket = new TCPSocket(extension_->id()); + socket = new TCPSocket(browser_context(), extension_->id()); } else if (socket_type_ == kSocketTypeUDP) { socket = new UDPSocket(std::move(socket_), std::move(socket_receiver_request_), @@ -463,15 +462,27 @@ return; } - int result = - socket->Listen(params_->address, params_->port, - params_->backlog.get() ? *params_->backlog : 5, &error_); - SetResult(std::make_unique<base::Value>(result)); - if (result != net::OK) { + socket->Listen(params_->address, params_->port, + params_->backlog.get() ? *params_->backlog : 5, + base::BindOnce(&SocketListenFunction::OnCompleted, this)); +} + +void SocketListenFunction::OnCompleted(int result, + const std::string& error_msg) { + DCHECK_NE(net::ERR_IO_PENDING, result); + Socket* socket = GetSocket(params_->socket_id); + if (!socket) { + error_ = kSocketNotFoundError; + SetResult(std::make_unique<base::Value>(-1)); AsyncWorkCompleted(); return; } - + SetResult(std::make_unique<base::Value>(result)); + if (result != net::OK) { + error_ = error_msg; + AsyncWorkCompleted(); + return; + } OpenFirewallHole(params_->address, params_->socket_id, socket); } @@ -488,21 +499,27 @@ void SocketAcceptFunction::AsyncWorkStart() { Socket* socket = GetSocket(params_->socket_id); if (socket) { - socket->Accept(base::Bind(&SocketAcceptFunction::OnAccept, this)); + socket->Accept(base::BindOnce(&SocketAcceptFunction::OnAccept, this)); } else { error_ = kSocketNotFoundError; - OnAccept(-1, NULL); + OnAccept(net::ERR_FAILED, nullptr, base::nullopt, + mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); } } void SocketAcceptFunction::OnAccept( int result_code, - std::unique_ptr<net::TCPClientSocket> socket) { + network::mojom::TCPConnectedSocketPtr socket, + const base::Optional<net::IPEndPoint>& remote_addr, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle) { std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue()); result->SetInteger(kResultCodeKey, result_code); - if (socket) { + if (result_code == net::OK) { Socket* client_socket = - new TCPSocket(std::move(socket), extension_id(), true); + new TCPSocket(std::move(socket), std::move(receive_pipe_handle), + std::move(send_pipe_handle), remote_addr, extension_id()); result->SetInteger(kSocketIdKey, AddSocket(client_socket)); } SetResult(std::move(result)); @@ -529,7 +546,7 @@ } socket->Read(params_->buffer_size.get() ? *params_->buffer_size : 4096, - base::BindRepeating(&SocketReadFunction::OnCompleted, this)); + base::BindOnce(&SocketReadFunction::OnCompleted, this)); } void SocketReadFunction::OnCompleted(int bytes_read, @@ -731,18 +748,25 @@ return true; } -void SocketSetKeepAliveFunction::Work() { - bool result = false; +void SocketSetKeepAliveFunction::AsyncWorkStart() { Socket* socket = GetSocket(params_->socket_id); - if (socket) { - int delay = 0; - if (params_->delay.get()) - delay = *params_->delay; - result = socket->SetKeepAlive(params_->enable, delay); - } else { + if (!socket) { + SetResult(std::make_unique<base::Value>(false)); error_ = kSocketNotFoundError; + AsyncWorkCompleted(); + return; } - SetResult(std::make_unique<base::Value>(result)); + int delay = 0; + if (params_->delay.get()) + delay = *params_->delay; + socket->SetKeepAlive( + params_->enable, delay, + base::BindOnce(&SocketSetKeepAliveFunction::OnCompleted, this)); +} + +void SocketSetKeepAliveFunction::OnCompleted(bool success) { + SetResult(std::make_unique<base::Value>(success)); + AsyncWorkCompleted(); } SocketSetNoDelayFunction::SocketSetNoDelayFunction() {} @@ -755,14 +779,22 @@ return true; } -void SocketSetNoDelayFunction::Work() { - bool result = false; +void SocketSetNoDelayFunction::AsyncWorkStart() { Socket* socket = GetSocket(params_->socket_id); - if (socket) - result = socket->SetNoDelay(params_->no_delay); - else + if (!socket) { error_ = kSocketNotFoundError; - SetResult(std::make_unique<base::Value>(result)); + SetResult(std::make_unique<base::Value>(false)); + AsyncWorkCompleted(); + return; + } + socket->SetNoDelay( + params_->no_delay, + base::BindOnce(&SocketSetNoDelayFunction::OnCompleted, this)); +} + +void SocketSetNoDelayFunction::OnCompleted(bool success) { + SetResult(std::make_unique<base::Value>(success)); + AsyncWorkCompleted(); } SocketGetInfoFunction::SocketGetInfoFunction() {} @@ -1084,8 +1116,6 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); params_ = api::socket::Secure::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params_.get()); - url_request_getter_ = content::BrowserContext::GetDefaultStoragePartition( - browser_context())->GetURLRequestContext(); return true; } @@ -1103,8 +1133,7 @@ } // Make sure that the socket is a TCP client socket. - if (socket->GetSocketType() != Socket::TYPE_TCP || - static_cast<TCPSocket*>(socket)->ClientStream() == NULL) { + if (socket->GetSocketType() != Socket::TYPE_TCP) { SetResult(std::make_unique<base::Value>(net::ERR_INVALID_ARGUMENT)); error_ = kSecureSocketTypeError; AsyncWorkCompleted(); @@ -1118,31 +1147,32 @@ return; } - net::URLRequestContext* url_request_context = - url_request_getter_->GetURLRequestContext(); - - TLSSocket::UpgradeSocketToTLS( - socket, url_request_context->ssl_config_service(), - url_request_context->cert_verifier(), - url_request_context->transport_security_state(), - url_request_context->cert_transparency_verifier(), - url_request_context->ct_policy_enforcer(), extension_id(), + TCPSocket* tcp_socket = static_cast<TCPSocket*>(socket); + tcp_socket->UpgradeToTLS( params_->options.get(), - base::Bind(&SocketSecureFunction::TlsConnectDone, this)); + base::BindOnce(&SocketSecureFunction::TlsConnectDone, this)); } -void SocketSecureFunction::TlsConnectDone(std::unique_ptr<TLSSocket> socket, - int result) { - // if an error occurred, socket MUST be NULL. - DCHECK(result == net::OK || socket == NULL); - - if (socket && result == net::OK) { - ReplaceSocket(params_->socket_id, socket.release()); - } else { +void SocketSecureFunction::TlsConnectDone( + int result, + network::mojom::TLSClientSocketPtr tls_socket, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle) { + if (result != net::OK) { RemoveSocket(params_->socket_id); error_ = net::ErrorToString(result); + results_ = api::socket::Secure::Results::Create(result); + AsyncWorkCompleted(); + return; } + auto socket = + std::make_unique<TLSSocket>(std::move(tls_socket), local_addr, peer_addr, + std::move(receive_pipe_handle), + std::move(send_pipe_handle), extension_id()); + ReplaceSocket(params_->socket_id, socket.release()); results_ = api::socket::Secure::Results::Create(result); AsyncWorkCompleted(); }
diff --git a/extensions/browser/api/socket/socket_api.h b/extensions/browser/api/socket/socket_api.h index cf52938..eae243f 100644 --- a/extensions/browser/api/socket/socket_api.h +++ b/extensions/browser/api/socket/socket_api.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <string> #include "base/gtest_prod_util.h" @@ -41,7 +42,6 @@ namespace extensions { class Socket; -class TLSSocket; // A simple interface to ApiResourceManager<Socket> or derived class. The goal // of this interface is to allow Socket API functions to use distinct instances @@ -184,8 +184,10 @@ FRIEND_TEST_ALL_PREFIXES(SocketUnitTest, Create); enum SocketType { kSocketTypeInvalid = -1, kSocketTypeTCP, kSocketTypeUDP }; + // These two fields are only applicable if |socket_type_| is UDP. network::mojom::UDPSocketPtrInfo socket_; network::mojom::UDPSocketReceiverRequest socket_receiver_request_; + std::unique_ptr<api::socket::Create::Params> params_; SocketType socket_type_; }; @@ -278,6 +280,7 @@ void AsyncWorkStart() override; private: + void OnCompleted(int result, const std::string& error_msg); std::unique_ptr<api::socket::Listen::Params> params_; }; @@ -295,7 +298,11 @@ void AsyncWorkStart() override; private: - void OnAccept(int result_code, std::unique_ptr<net::TCPClientSocket> socket); + void OnAccept(int result_code, + network::mojom::TCPConnectedSocketPtr socket, + const base::Optional<net::IPEndPoint>& remote_addr, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle); std::unique_ptr<api::socket::Accept::Params> params_; }; @@ -400,9 +407,11 @@ // AsyncApiFunction: bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(bool success); + std::unique_ptr<api::socket::SetKeepAlive::Params> params_; }; @@ -417,9 +426,11 @@ // AsyncApiFunction: bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(bool success); + std::unique_ptr<api::socket::SetNoDelay::Params> params_; }; @@ -561,11 +572,14 @@ void AsyncWorkStart() override; private: - // Callback from TLSSocket::UpgradeSocketToTLS(). - void TlsConnectDone(std::unique_ptr<TLSSocket> socket, int result); + void TlsConnectDone(int result, + network::mojom::TLSClientSocketPtr tls_socket, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle); std::unique_ptr<api::socket::Secure::Params> params_; - scoped_refptr<net::URLRequestContextGetter> url_request_getter_; DISALLOW_COPY_AND_ASSIGN(SocketSecureFunction); };
diff --git a/extensions/browser/api/socket/tcp_socket.cc b/extensions/browser/api/socket/tcp_socket.cc index a1ee755..e80bd771 100644 --- a/extensions/browser/api/socket/tcp_socket.cc +++ b/extensions/browser/api/socket/tcp_socket.cc
@@ -4,21 +4,49 @@ #include "extensions/browser/api/socket/tcp_socket.h" +#include <utility> + #include "base/callback_helpers.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" #include "extensions/browser/api/api_resource.h" +#include "extensions/browser/api/socket/mojo_data_pump.h" #include "net/base/address_list.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" -#include "net/base/rand_callback.h" -#include "net/log/net_log_source.h" -#include "net/socket/tcp_client_socket.h" +#include "net/base/url_util.h" +#include "services/network/public/mojom/ssl_config.mojom.h" namespace extensions { +namespace { + +// Returns true if successfully parsed the SSL protocol version that is +// represented by a string. Returns false if |version_str| is invalid. +bool SSLProtocolVersionFromString(const std::string& version_str, + network::mojom::SSLVersion* version_out) { + if (version_str == "tls1") { + *version_out = network::mojom::SSLVersion::kTLS1; + return true; + } + if (version_str == "tls1.1") { + *version_out = network::mojom::SSLVersion::kTLS11; + return true; + } + if (version_str == "tls1.2") { + *version_out = network::mojom::SSLVersion::kTLS12; + return true; + } + return false; +} + +} // namespace + const char kTCPSocketTypeInvalidError[] = "Cannot call both connect and listen on the same socket."; const char kSocketListenError[] = "Could not listen on the specified port."; @@ -45,38 +73,31 @@ return g_server_factory.Pointer(); } -TCPSocket::TCPSocket(const std::string& owner_extension_id) - : Socket(owner_extension_id), socket_mode_(UNKNOWN) {} - -TCPSocket::TCPSocket(std::unique_ptr<net::TCPClientSocket> tcp_client_socket, - const std::string& owner_extension_id, - bool is_connected) - : Socket(owner_extension_id), - socket_(std::move(tcp_client_socket)), - socket_mode_(CLIENT) { - this->is_connected_ = is_connected; -} - -TCPSocket::TCPSocket(std::unique_ptr<net::TCPServerSocket> tcp_server_socket, +TCPSocket::TCPSocket(content::BrowserContext* browser_context, const std::string& owner_extension_id) : Socket(owner_extension_id), - server_socket_(std::move(tcp_server_socket)), - socket_mode_(SERVER) {} + browser_context_(browser_context), + socket_mode_(UNKNOWN), + mojo_data_pump_(nullptr), + task_runner_(base::SequencedTaskRunnerHandle::Get()), + weak_factory_(this) {} -// static -TCPSocket* TCPSocket::CreateSocketForTesting( - std::unique_ptr<net::TCPClientSocket> tcp_client_socket, - const std::string& owner_extension_id, - bool is_connected) { - return new TCPSocket(std::move(tcp_client_socket), owner_extension_id, - is_connected); -} +TCPSocket::TCPSocket(network::mojom::TCPConnectedSocketPtr socket, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream, + const base::Optional<net::IPEndPoint>& remote_addr, + const std::string& owner_extension_id) + : Socket(owner_extension_id), + browser_context_(nullptr), + socket_mode_(CLIENT), + client_socket_(std::move(socket)), + mojo_data_pump_(std::make_unique<MojoDataPump>(std::move(receive_stream), + std::move(send_stream))), + task_runner_(base::SequencedTaskRunnerHandle::Get()), + peer_addr_(remote_addr), -// static -TCPSocket* TCPSocket::CreateServerSocketForTesting( - std::unique_ptr<net::TCPServerSocket> tcp_server_socket, - const std::string& owner_extension_id) { - return new TCPSocket(std::move(tcp_server_socket), owner_extension_id); + weak_factory_(this) { + is_connected_ = true; } TCPSocket::~TCPSocket() { @@ -84,48 +105,57 @@ } void TCPSocket::Connect(const net::AddressList& address, - const CompletionCallback& callback) { - DCHECK(!callback.is_null()); + net::CompletionOnceCallback callback) { + DCHECK(callback); - if (socket_mode_ == SERVER || !connect_callback_.is_null()) { - callback.Run(net::ERR_CONNECTION_FAILED); + if (socket_mode_ == SERVER || connect_callback_) { + std::move(callback).Run(net::ERR_CONNECTION_FAILED); return; } if (is_connected_) { - callback.Run(net::ERR_SOCKET_IS_CONNECTED); + std::move(callback).Run(net::ERR_SOCKET_IS_CONNECTED); return; } - DCHECK(!server_socket_.get()); + DCHECK(!server_socket_); socket_mode_ = CLIENT; - connect_callback_ = callback; + connect_callback_ = std::move(callback); - int result = net::ERR_CONNECTION_FAILED; - if (!is_connected_) { - socket_.reset( - new net::TCPClientSocket(address, NULL, NULL, net::NetLogSource())); - result = socket_->Connect( - base::Bind(&TCPSocket::OnConnectComplete, base::Unretained(this))); - } + // |completion_callback| is called on current thread. + network::mojom::NetworkContext::CreateTCPConnectedSocketCallback + completion_callback = base::BindOnce(&TCPSocket::OnConnectComplete, + weak_factory_.GetWeakPtr()); - if (result != net::ERR_IO_PENDING) - OnConnectComplete(result); + // |completion_callback_ui| is called on the UI thread. + network::mojom::NetworkContext::CreateTCPConnectedSocketCallback + completion_callback_ui = + base::BindOnce(&TCPSocket::OnConnectCompleteOnUIThread, task_runner_, + std::move(completion_callback)); + + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(&TCPSocket::ConnectOnUIThread, storage_partition_, + browser_context_, address, + mojo::MakeRequest(&client_socket_), + std::move(completion_callback_ui))); } void TCPSocket::Disconnect(bool socket_destroying) { is_connected_ = false; - if (socket_.get()) - socket_->Disconnect(); - server_socket_.reset(NULL); + local_addr_ = base::nullopt; + peer_addr_ = base::nullopt; + mojo_data_pump_ = nullptr; + client_socket_.reset(); + server_socket_.reset(); + listen_callback_.Reset(); connect_callback_.Reset(); + accept_callback_.Reset(); // TODO(devlin): Should we do this for all callbacks? - if (!read_callback_.is_null()) { - base::ResetAndReturn(&read_callback_) + if (read_callback_) { + std::move(read_callback_) .Run(net::ERR_CONNECTION_CLOSED, nullptr, socket_destroying); } - accept_callback_.Reset(); - accept_socket_.reset(NULL); } void TCPSocket::Bind(const std::string& address, @@ -134,42 +164,30 @@ callback.Run(net::ERR_FAILED); } -void TCPSocket::Read(int count, const ReadCompletionCallback& callback) { - DCHECK(!callback.is_null()); +void TCPSocket::Read(int count, ReadCompletionCallback callback) { + DCHECK(callback); const bool socket_destroying = false; if (socket_mode_ != CLIENT) { - callback.Run(net::ERR_FAILED, nullptr, socket_destroying); + std::move(callback).Run(net::ERR_FAILED, nullptr, socket_destroying); return; } - if (!read_callback_.is_null() || !connect_callback_.is_null()) { + if (!mojo_data_pump_) { + std::move(callback).Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, + socket_destroying); + return; + } + if (mojo_data_pump_->HasPendingRead() || connect_callback_) { // It's illegal to read a net::TCPSocket while a pending Connect or Read is // already in progress. - callback.Run(net::ERR_IO_PENDING, nullptr, socket_destroying); + std::move(callback).Run(net::ERR_IO_PENDING, nullptr, socket_destroying); return; } - if (count < 0) { - callback.Run(net::ERR_INVALID_ARGUMENT, nullptr, socket_destroying); - return; - } - - if (!socket_.get() || !is_connected_) { - callback.Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, socket_destroying); - return; - } - - read_callback_ = callback; - scoped_refptr<net::IOBuffer> io_buffer = new net::IOBuffer(count); - int result = socket_->Read( - io_buffer.get(), - count, - base::Bind( - &TCPSocket::OnReadComplete, base::Unretained(this), io_buffer)); - - if (result != net::ERR_IO_PENDING) - OnReadComplete(io_buffer, result); + read_callback_ = std::move(callback); + mojo_data_pump_->Read(count, base::BindOnce(&TCPSocket::OnReadComplete, + base::Unretained(this))); } void TCPSocket::RecvFrom(int count, @@ -185,85 +203,105 @@ callback.Run(net::ERR_FAILED); } -bool TCPSocket::SetKeepAlive(bool enable, int delay) { - if (!socket_.get()) - return false; - return socket_->SetKeepAlive(enable, delay); -} - -bool TCPSocket::SetNoDelay(bool no_delay) { - if (!socket_.get()) - return false; - return socket_->SetNoDelay(no_delay); -} - -int TCPSocket::Listen(const std::string& address, - uint16_t port, - int backlog, - std::string* error_msg) { - if (socket_mode_ == CLIENT) { - *error_msg = kTCPSocketTypeInvalidError; - return net::ERR_NOT_IMPLEMENTED; +void TCPSocket::SetKeepAlive(bool enable, + int delay, + SetKeepAliveCallback callback) { + if (!client_socket_) { + std::move(callback).Run(net::ERR_FAILED); + return; } - DCHECK(!socket_.get()); + client_socket_->SetKeepAlive(enable, delay, std::move(callback)); +} + +void TCPSocket::SetNoDelay(bool no_delay, SetNoDelayCallback callback) { + if (!client_socket_) { + std::move(callback).Run(net::ERR_FAILED); + return; + } + client_socket_->SetNoDelay(no_delay, std::move(callback)); +} + +void TCPSocket::Listen(const std::string& address, + uint16_t port, + int backlog, + ListenCallback callback) { + DCHECK(!server_socket_); + DCHECK(!client_socket_); + DCHECK(!listen_callback_); + + if (socket_mode_ == CLIENT) { + std::move(callback).Run(net::ERR_NOT_IMPLEMENTED, + kTCPSocketTypeInvalidError); + return; + } + + net::IPEndPoint ip_end_point; + if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) { + std::move(callback).Run(net::ERR_INVALID_ARGUMENT, ""); + return; + } + socket_mode_ = SERVER; - if (!server_socket_.get()) { - server_socket_.reset(new net::TCPServerSocket(NULL, net::NetLogSource())); - } + listen_callback_ = std::move(callback); - int result = server_socket_->ListenWithAddressAndPort(address, port, backlog); - if (result) { - server_socket_.reset(); - *error_msg = kSocketListenError; - } - return result; + // |completion_callback| is called on current thread. + network::mojom::NetworkContext::CreateTCPServerSocketCallback + completion_callback = base::BindOnce(&TCPSocket::OnListenComplete, + weak_factory_.GetWeakPtr()); + + // |completion_callback_ui| is called on the UI thread. + network::mojom::NetworkContext::CreateTCPServerSocketCallback + completion_callback_ui = + base::BindOnce(&TCPSocket::OnListenCompleteOnUIThread, task_runner_, + std::move(completion_callback)); + + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(&TCPSocket::ListenOnUIThread, storage_partition_, + browser_context_, ip_end_point, backlog, + mojo::MakeRequest(&server_socket_), + std::move(completion_callback_ui))); } -void TCPSocket::Accept(const AcceptCompletionCallback& callback) { +void TCPSocket::Accept(AcceptCompletionCallback callback) { if (socket_mode_ != SERVER || !server_socket_.get()) { - callback.Run(net::ERR_FAILED, NULL); + std::move(callback).Run(net::ERR_FAILED, nullptr, base::nullopt, + mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); return; } // Limits to only 1 blocked accept call. - if (!accept_callback_.is_null()) { - callback.Run(net::ERR_FAILED, NULL); + if (accept_callback_) { + std::move(callback).Run(net::ERR_FAILED, nullptr, base::nullopt, + mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); return; } - int result = server_socket_->Accept( - &accept_socket_, - base::Bind(&TCPSocket::OnAccept, base::Unretained(this))); - if (result == net::ERR_IO_PENDING) { - accept_callback_ = callback; - } else if (result == net::OK) { - accept_callback_ = callback; - this->OnAccept(result); - } else { - callback.Run(result, NULL); - } + accept_callback_ = std::move(callback); + server_socket_->Accept( + nullptr /* observer */, + base::BindOnce(&TCPSocket::OnAccept, base::Unretained(this))); } bool TCPSocket::IsConnected() { - RefreshConnectionStatus(); return is_connected_; } bool TCPSocket::GetPeerAddress(net::IPEndPoint* address) { - if (!socket_.get()) + if (!peer_addr_) return false; - return !socket_->GetPeerAddress(address); + *address = peer_addr_.value(); + return true; } bool TCPSocket::GetLocalAddress(net::IPEndPoint* address) { - if (socket_.get()) { - return !socket_->GetLocalAddress(address); - } else if (server_socket_.get()) { - return !server_socket_->GetLocalAddress(address); - } else { + if (!local_addr_) return false; - } + *address = local_addr_.value(); + return true; } Socket::SocketType TCPSocket::GetSocketType() const { return Socket::TYPE_TCP; } @@ -271,97 +309,265 @@ int TCPSocket::WriteImpl(net::IOBuffer* io_buffer, int io_buffer_size, const net::CompletionCallback& callback) { - if (socket_mode_ != CLIENT) - return net::ERR_FAILED; - else if (!socket_.get() || !IsConnected()) + if (!mojo_data_pump_) return net::ERR_SOCKET_NOT_CONNECTED; - else - return socket_->Write(io_buffer, io_buffer_size, callback, - Socket::GetNetworkTrafficAnnotationTag()); + + mojo_data_pump_->Write(io_buffer, io_buffer_size, + base::BindOnce(&TCPSocket::OnWriteComplete, + base::Unretained(this), callback)); + return net::ERR_IO_PENDING; } -void TCPSocket::RefreshConnectionStatus() { - if (!is_connected_) +// static +void TCPSocket::ConnectOnUIThread( + content::StoragePartition* storage_partition, + content::BrowserContext* browser_context, + const net::AddressList& remote_addr_list, + network::mojom::TCPConnectedSocketRequest request, + network::mojom::NetworkContext::CreateTCPConnectedSocketCallback + completion_callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (!storage_partition) { + storage_partition = + content::BrowserContext::GetDefaultStoragePartition(browser_context); + } + storage_partition->GetNetworkContext()->CreateTCPConnectedSocket( + base::nullopt, remote_addr_list, + net::MutableNetworkTrafficAnnotationTag( + Socket::GetNetworkTrafficAnnotationTag()), + std::move(request), nullptr /* observer */, + std::move(completion_callback)); +} + +// static +void TCPSocket::OnConnectCompleteOnUIThread( + scoped_refptr<base::SequencedTaskRunner> original_task_runner, + network::mojom::NetworkContext::CreateTCPConnectedSocketCallback callback, + int result, + const base::Optional<net::IPEndPoint>& local_addr, + const base::Optional<net::IPEndPoint>& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + original_task_runner->PostTask( + FROM_HERE, + base::BindOnce(std::move(callback), result, local_addr, peer_addr, + std::move(receive_stream), std::move(send_stream))); +} + +void TCPSocket::OnConnectComplete( + int result, + const base::Optional<net::IPEndPoint>& local_addr, + const base::Optional<net::IPEndPoint>& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream) { + DCHECK(!is_connected_); + DCHECK(connect_callback_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + if (result == net::OK) { + is_connected_ = true; + local_addr_ = local_addr; + peer_addr_ = peer_addr; + mojo_data_pump_ = std::make_unique<MojoDataPump>(std::move(receive_stream), + std::move(send_stream)); + } + std::move(connect_callback_).Run(result); +} + +// static +void TCPSocket::ListenOnUIThread( + content::StoragePartition* storage_partition, + content::BrowserContext* browser_context, + const net::IPEndPoint& local_addr, + int backlog, + network::mojom::TCPServerSocketRequest request, + network::mojom::NetworkContext::CreateTCPServerSocketCallback callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (!storage_partition) { + storage_partition = + content::BrowserContext::GetDefaultStoragePartition(browser_context); + } + storage_partition->GetNetworkContext()->CreateTCPServerSocket( + local_addr, backlog, + net::MutableNetworkTrafficAnnotationTag( + Socket::GetNetworkTrafficAnnotationTag()), + std::move(request), std::move(callback)); +} + +// static +void TCPSocket::OnListenCompleteOnUIThread( + const scoped_refptr<base::SequencedTaskRunner>& original_task_runner, + network::mojom::NetworkContext::CreateTCPServerSocketCallback callback, + int result, + const base::Optional<net::IPEndPoint>& local_addr) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + original_task_runner->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), result, local_addr)); +} + +void TCPSocket::OnListenComplete( + int result, + const base::Optional<net::IPEndPoint>& local_addr) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(listen_callback_); + + if (result != net::OK) { + server_socket_.reset(); + std::move(listen_callback_).Run(result, kSocketListenError); return; - if (server_socket_) - return; - if (!socket_->IsConnected()) { + } + local_addr_ = local_addr; + std::move(listen_callback_).Run(result, ""); +} + +content::StoragePartition* TCPSocket::GetStoragePartitionHelper() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + return storage_partition_ + ? storage_partition_ + : content::BrowserContext::GetDefaultStoragePartition( + browser_context_); +} + +void TCPSocket::OnAccept(int result, + const base::Optional<net::IPEndPoint>& remote_addr, + network::mojom::TCPConnectedSocketPtr connected_socket, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream) { + DCHECK(accept_callback_); + std::move(accept_callback_) + .Run(result, std::move(connected_socket), remote_addr, + std::move(receive_stream), std::move(send_stream)); +} + +void TCPSocket::OnWriteComplete(const net::CompletionCallback& callback, + int result) { + if (result < 0) { + // Write side has terminated. This can be an error or a graceful close. + // TCPSocketEventDispatcher doesn't distinguish between the two. Disconnect(false /* socket_destroying */); } + callback.Run(result); } -void TCPSocket::OnConnectComplete(int result) { - DCHECK(!connect_callback_.is_null()); - DCHECK(!is_connected_); - is_connected_ = result == net::OK; +void TCPSocket::OnReadComplete(int result, + scoped_refptr<net::IOBuffer> io_buffer) { + DCHECK(read_callback_); - // The completion callback may re-enter TCPSocket, e.g. to Read(); therefore - // we reset |connect_callback_| before calling it. - CompletionCallback connect_callback = connect_callback_; - connect_callback_.Reset(); - connect_callback.Run(result); -} - -void TCPSocket::OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, - int result) { - DCHECK(!read_callback_.is_null()); - read_callback_.Run(result, io_buffer, false /* socket_destroying */); - read_callback_.Reset(); -} - -void TCPSocket::OnAccept(int result) { - DCHECK(!accept_callback_.is_null()); - if (result == net::OK && accept_socket_.get()) { - accept_callback_.Run(result, - base::WrapUnique(static_cast<net::TCPClientSocket*>( - accept_socket_.release()))); - } else { - accept_callback_.Run(result, NULL); + // Use a local variable for |read_callback_|, because otherwise Disconnect() + // will try to invoke |read_callback_| with a hardcoded result code. + ReadCompletionCallback callback = std::move(read_callback_); + if (result < 0) { + // Read side has terminated. This can be an error or a graceful close. + // TCPSocketEventDispatcher doesn't distinguish between the two. + Disconnect(false /* socket_destroying */); } - accept_callback_.Reset(); + std::move(callback).Run(result, io_buffer, false /* socket_destroying */); } -void TCPSocket::Release() { - // Release() is only invoked when the underlying sockets are taken (via - // ClientStream()) by TLSSocket. TLSSocket only supports CLIENT-mode - // sockets. - DCHECK(!server_socket_.release() && !accept_socket_.release() && - socket_mode_ == CLIENT) - << "Called in server mode."; - - // Release() doesn't disconnect the underlying sockets, but it does - // disconnect them from this TCPSocket. - is_connected_ = false; - - connect_callback_.Reset(); - read_callback_.Reset(); - accept_callback_.Reset(); - - DCHECK(socket_.get()) << "Called on null client socket."; - ignore_result(socket_.release()); +void TCPSocket::OnUpgradeToTLSComplete( + UpgradeToTLSCallback callback, + network::mojom::TLSClientSocketPtr tls_socket, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + int result, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream) { + std::move(callback).Run(result, std::move(tls_socket), local_addr, peer_addr, + std::move(receive_stream), std::move(send_stream)); } -net::TCPClientSocket* TCPSocket::ClientStream() { - if (socket_mode_ != CLIENT || GetSocketType() != TYPE_TCP) - return NULL; - return socket_.get(); +void TCPSocket::UpgradeToTLS(api::socket::SecureOptions* options, + UpgradeToTLSCallback callback) { + if (!client_socket_ || !mojo_data_pump_ || + mojo_data_pump_->HasPendingRead() || mojo_data_pump_->HasPendingWrite()) { + std::move(callback).Run(net::ERR_FAILED, nullptr, net::IPEndPoint(), + net::IPEndPoint(), + mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); + return; + } + if (!local_addr_ || !peer_addr_) { + DVLOG(1) << "Could not get local address or peer address."; + std::move(callback).Run(net::ERR_FAILED, nullptr, net::IPEndPoint(), + net::IPEndPoint(), + mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); + return; + } + + // Convert any U-LABELs to A-LABELs. + url::CanonHostInfo host_info; + std::string canon_host = net::CanonicalizeHost(hostname(), &host_info); + + // Canonicalization shouldn't fail: the socket is already connected with a + // host, using this hostname. + if (host_info.family == url::CanonHostInfo::BROKEN) { + DVLOG(1) << "Could not canonicalize hostname"; + std::move(callback).Run(net::ERR_FAILED, nullptr, net::IPEndPoint(), + net::IPEndPoint(), + mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); + return; + } + + mojo_data_pump_ = nullptr; + network::mojom::TLSClientSocketOptionsPtr mojo_socket_options = + network::mojom::TLSClientSocketOptions::New(); + if (options && options->tls_version.get()) { + network::mojom::SSLVersion version_min, version_max; + bool has_version_min = false; + bool has_version_max = false; + api::socket::TLSVersionConstraints* versions = options->tls_version.get(); + if (versions->min.get()) { + has_version_min = + SSLProtocolVersionFromString(*versions->min, &version_min); + } + if (versions->max.get()) { + has_version_max = + SSLProtocolVersionFromString(*versions->max, &version_max); + } + if (has_version_min) + mojo_socket_options->version_min = version_min; + if (has_version_max) + mojo_socket_options->version_max = version_max; + } + network::mojom::TLSClientSocketPtr tls_socket; + network::mojom::TLSClientSocketRequest tls_socket_request = + mojo::MakeRequest(&tls_socket); + net::HostPortPair host_port_pair(canon_host, peer_addr_.value().port()); + client_socket_->UpgradeToTLS( + host_port_pair, std::move(mojo_socket_options), + net::MutableNetworkTrafficAnnotationTag( + Socket::GetNetworkTrafficAnnotationTag()), + std::move(tls_socket_request), nullptr /* observer */, + base::BindOnce(&TCPSocket::OnUpgradeToTLSComplete, base::Unretained(this), + std::move(callback), std::move(tls_socket), + local_addr_.value(), peer_addr_.value())); } -bool TCPSocket::HasPendingRead() const { - return !read_callback_.is_null(); -} - -ResumableTCPSocket::ResumableTCPSocket(const std::string& owner_extension_id) - : TCPSocket(owner_extension_id), +ResumableTCPSocket::ResumableTCPSocket(content::BrowserContext* browser_context, + const std::string& owner_extension_id) + : TCPSocket(browser_context, owner_extension_id), persistent_(false), buffer_size_(0), paused_(false) {} ResumableTCPSocket::ResumableTCPSocket( - std::unique_ptr<net::TCPClientSocket> tcp_client_socket, - const std::string& owner_extension_id, - bool is_connected) - : TCPSocket(std::move(tcp_client_socket), owner_extension_id, is_connected), + network::mojom::TCPConnectedSocketPtr socket, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream, + const base::Optional<net::IPEndPoint>& remote_addr, + const std::string& owner_extension_id) + : TCPSocket(std::move(socket), + std::move(receive_stream), + std::move(send_stream), + remote_addr, + owner_extension_id), persistent_(false), buffer_size_(0), paused_(false) {} @@ -377,8 +583,11 @@ bool ResumableTCPSocket::IsPersistent() const { return persistent(); } ResumableTCPServerSocket::ResumableTCPServerSocket( + content::BrowserContext* browser_context, const std::string& owner_extension_id) - : TCPSocket(owner_extension_id), persistent_(false), paused_(false) {} + : TCPSocket(browser_context, owner_extension_id), + persistent_(false), + paused_(false) {} bool ResumableTCPServerSocket::IsPersistent() const { return persistent(); }
diff --git a/extensions/browser/api/socket/tcp_socket.h b/extensions/browser/api/socket/tcp_socket.h index bdff76ed..f834301 100644 --- a/extensions/browser/api/socket/tcp_socket.h +++ b/extensions/browser/api/socket/tcp_socket.h
@@ -7,76 +7,88 @@ #include <stdint.h> +#include <memory> #include <string> +#include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner.h" #include "extensions/browser/api/socket/socket.h" +#include "extensions/browser/api/socket/tcp_socket.h" +#include "extensions/common/api/socket.h" +#include "net/base/completion_once_callback.h" +#include "services/network/public/mojom/network_service.mojom.h" +#include "services/network/public/mojom/tcp_socket.mojom.h" +#include "services/network/public/mojom/tls_socket.mojom.h" -// This looks like it should be forward-declarable, but it does some tricky -// moves that make it easier to just include it. -#include "net/socket/tcp_client_socket.h" -#include "net/socket/tcp_server_socket.h" - -namespace net { -class Socket; +namespace content { +class BrowserContext; +class StoragePartition; } namespace extensions { +class MojoDataPump; + class TCPSocket : public Socket { public: - explicit TCPSocket(const std::string& owner_extension_id); - TCPSocket(std::unique_ptr<net::TCPClientSocket> tcp_client_socket, - const std::string& owner_extension_id, - bool is_connected = false); + using UpgradeToTLSCallback = + base::OnceCallback<void(int, + network::mojom::TLSClientSocketPtr, + const net::IPEndPoint&, + const net::IPEndPoint&, + mojo::ScopedDataPipeConsumerHandle, + mojo::ScopedDataPipeProducerHandle)>; + + // Constuctor for when |socket_mode_| is unknown. The |socket_mode_| will be + // filled in when the consumer calls Listen/Connect. + TCPSocket(content::BrowserContext* browser_context, + const std::string& owner_extension_id); + + // Created using TCPServerSocket::Accept(). + TCPSocket(network::mojom::TCPConnectedSocketPtr socket, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream, + const base::Optional<net::IPEndPoint>& remote_addr, + const std::string& owner_extension_id); ~TCPSocket() override; void Connect(const net::AddressList& address, - const CompletionCallback& callback) override; + net::CompletionOnceCallback callback) override; void Disconnect(bool socket_destroying) override; void Bind(const std::string& address, uint16_t port, const CompletionCallback& callback) override; - void Read(int count, const ReadCompletionCallback& callback) override; + void Read(int count, ReadCompletionCallback callback) override; void RecvFrom(int count, const RecvFromCompletionCallback& callback) override; void SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, const net::IPEndPoint& address, const CompletionCallback& callback) override; - bool SetKeepAlive(bool enable, int delay) override; - bool SetNoDelay(bool no_delay) override; - int Listen(const std::string& address, - uint16_t port, - int backlog, - std::string* error_msg) override; - void Accept(const AcceptCompletionCallback& callback) override; + void SetKeepAlive(bool enable, + int delay, + SetKeepAliveCallback callback) override; + void SetNoDelay(bool no_delay, SetNoDelayCallback callback) override; + void Listen(const std::string& address, + uint16_t port, + int backlog, + ListenCallback callback) override; + void Accept(AcceptCompletionCallback callback) override; bool IsConnected() override; bool GetPeerAddress(net::IPEndPoint* address) override; bool GetLocalAddress(net::IPEndPoint* address) override; - // Like Disconnect(), only Release() doesn't delete the underlying stream - // or attempt to close it. Useful when giving away ownership with - // ClientStream(). - virtual void Release(); - Socket::SocketType GetSocketType() const override; - static TCPSocket* CreateSocketForTesting( - std::unique_ptr<net::TCPClientSocket> tcp_client_socket, - const std::string& owner_extension_id, - bool is_connected = false); - static TCPSocket* CreateServerSocketForTesting( - std::unique_ptr<net::TCPServerSocket> tcp_server_socket, - const std::string& owner_extension_id); + void UpgradeToTLS(api::socket::SecureOptions* options, + UpgradeToTLSCallback callback); - // Returns NULL if GetSocketType() isn't TYPE_TCP or if the connection - // wasn't set up via Connect() (vs Listen()/Accept()). - net::TCPClientSocket* ClientStream(); - - // Whether a Read() has been issued, that hasn't come back yet. - bool HasPendingRead() const; + void SetStoragePartitionForTest( + content::StoragePartition* storage_partition) { + storage_partition_ = storage_partition; + } protected: int WriteImpl(net::IOBuffer* io_buffer, @@ -84,26 +96,101 @@ const net::CompletionCallback& callback) override; private: - void RefreshConnectionStatus(); - void OnConnectComplete(int result); - void OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, int result); - void OnAccept(int result); + // Connects a client TCP socket. This is done on the UI thread because + // StoragePartition::GetNetworkContext() needs to happen on the UI thread. + // The completion callback is posted back to the thread on which |this| lives. + static void ConnectOnUIThread( + content::StoragePartition* storage_partition, + content::BrowserContext* browser_context, + const net::AddressList& remote_address_list, + network::mojom::TCPConnectedSocketRequest request, + network::mojom::NetworkContext::CreateTCPConnectedSocketCallback + callback); + static void OnConnectCompleteOnUIThread( + scoped_refptr<base::SequencedTaskRunner> original_task_runner, + network::mojom::NetworkContext::CreateTCPConnectedSocketCallback callback, + int result, + const base::Optional<net::IPEndPoint>& local_addr, + const base::Optional<net::IPEndPoint>& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream); + void OnConnectComplete(int result, + const base::Optional<net::IPEndPoint>& local_addr, + const base::Optional<net::IPEndPoint>& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream); - TCPSocket(std::unique_ptr<net::TCPServerSocket> tcp_server_socket, - const std::string& owner_extension_id); + // Connects a server TCP socket. This is done on the UI thread because + // StoragePartition::GetNetworkContext() needs to happen on the UI thread. + // The completion callback is posted back to the thread on which |this| lives. + static void ListenOnUIThread( + content::StoragePartition* storage_partition, + content::BrowserContext* browser_context, + const net::IPEndPoint& local_addr, + int backlog, + network::mojom::TCPServerSocketRequest request, + network::mojom::NetworkContext::CreateTCPServerSocketCallback callback); + static void OnListenCompleteOnUIThread( + const scoped_refptr<base::SequencedTaskRunner>& original_task_runner, + network::mojom::NetworkContext::CreateTCPServerSocketCallback callback, + int result, + const base::Optional<net::IPEndPoint>& local_addr); + void OnListenComplete(int result, + const base::Optional<net::IPEndPoint>& local_addr); + void OnAccept(int result, + const base::Optional<net::IPEndPoint>& remote_addr, + network::mojom::TCPConnectedSocketPtr connected_socket, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream); + void OnWriteComplete(const net::CompletionCallback& callback, int result); + void OnReadComplete(int result, scoped_refptr<net::IOBuffer> io_buffer); + void OnUpgradeToTLSComplete(UpgradeToTLSCallback callback, + network::mojom::TLSClientSocketPtr tls_socket, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + int result, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream); - std::unique_ptr<net::TCPClientSocket> socket_; - std::unique_ptr<net::TCPServerSocket> server_socket_; + content::StoragePartition* GetStoragePartitionHelper(); - enum SocketMode { UNKNOWN = 0, CLIENT, SERVER, }; + enum SocketMode { + UNKNOWN = 0, + CLIENT, + SERVER, + }; + + // |this| doesn't outlive |browser_context_| because |this| is owned by + // ApiResourceManager which is a BrowserContextKeyedAPI. + content::BrowserContext* browser_context_; + SocketMode socket_mode_; - CompletionCallback connect_callback_; + // CLIENT mode. + network::mojom::TCPConnectedSocketPtr client_socket_; + // SERVER mode. + network::mojom::TCPServerSocketPtr server_socket_; + net::CompletionOnceCallback connect_callback_; + ListenCallback listen_callback_; + AcceptCompletionCallback accept_callback_; ReadCompletionCallback read_callback_; - std::unique_ptr<net::StreamSocket> accept_socket_; - AcceptCompletionCallback accept_callback_; + std::unique_ptr<MojoDataPump> mojo_data_pump_; + + scoped_refptr<base::SequencedTaskRunner> task_runner_; + + base::Optional<net::IPEndPoint> local_addr_; + base::Optional<net::IPEndPoint> peer_addr_; + + // Only used in tests. + content::StoragePartition* storage_partition_ = nullptr; + + // WeakPtr is used when posting tasks to |task_runner_| which might outlive + // |this|. + base::WeakPtrFactory<TCPSocket> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(TCPSocket); }; // TCP Socket instances from the "sockets.tcp" namespace. These are regular @@ -111,11 +198,14 @@ // the "sockets.tcp" namespace. class ResumableTCPSocket : public TCPSocket { public: - explicit ResumableTCPSocket(const std::string& owner_extension_id); - explicit ResumableTCPSocket( - std::unique_ptr<net::TCPClientSocket> tcp_client_socket, - const std::string& owner_extension_id, - bool is_connected); + ResumableTCPSocket(content::BrowserContext* browser_context, + const std::string& owner_extension_id); + // Created using TCPServerSocket::Accept(). + ResumableTCPSocket(network::mojom::TCPConnectedSocketPtr socket, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream, + const base::Optional<net::IPEndPoint>& remote_addr, + const std::string& owner_extension_id); ~ResumableTCPSocket() override; @@ -155,7 +245,8 @@ // defined in the "sockets.tcpServer" namespace. class ResumableTCPServerSocket : public TCPSocket { public: - explicit ResumableTCPServerSocket(const std::string& owner_extension_id); + ResumableTCPServerSocket(content::BrowserContext* browser_context, + const std::string& owner_extension_id); // Overriden from ApiResource bool IsPersistent() const override;
diff --git a/extensions/browser/api/socket/tls_socket.cc b/extensions/browser/api/socket/tls_socket.cc index aa2a4a0..0c39bf0c 100644 --- a/extensions/browser/api/socket/tls_socket.cc +++ b/extensions/browser/api/socket/tls_socket.cc
@@ -10,307 +10,142 @@ #include "base/logging.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/api/api_resource.h" +#include "extensions/browser/api/socket/mojo_data_pump.h" #include "net/base/address_list.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" -#include "net/base/rand_callback.h" #include "net/base/url_util.h" -#include "net/socket/client_socket_factory.h" -#include "net/socket/client_socket_handle.h" -#include "net/socket/ssl_client_socket.h" -#include "net/socket/tcp_client_socket.h" #include "url/url_canon.h" -namespace { - -// Returns the SSL protocol version (as a uint16_t) represented by a string. -// Returns 0 if the string is invalid. -uint16_t SSLProtocolVersionFromString(const std::string& version_str) { - uint16_t version = 0; // Invalid. - if (version_str == "tls1") { - version = net::SSL_PROTOCOL_VERSION_TLS1; - } else if (version_str == "tls1.1") { - version = net::SSL_PROTOCOL_VERSION_TLS1_1; - } else if (version_str == "tls1.2") { - version = net::SSL_PROTOCOL_VERSION_TLS1_2; - } - return version; -} - -void TlsConnectDone(std::unique_ptr<net::SSLClientSocket> ssl_socket, - const std::string& extension_id, - const extensions::TLSSocket::SecureCallback& callback, - int result) { - DVLOG(1) << "Got back result " << result << " " << net::ErrorToString(result); - - // No matter how the TLS connection attempt went, the underlying socket's - // no longer bound to the original TCPSocket. It belongs to |ssl_socket|, - // which is promoted here to a new API-accessible socket (via a TLSSocket - // wrapper), or deleted. - if (result != net::OK) { - callback.Run(nullptr, result); - return; - }; - - // Wrap the StreamSocket in a TLSSocket, which matches the extension socket - // API. Set the handle of the socket to the new value, so that it can be - // used for read/write/close/etc. - std::unique_ptr<extensions::TLSSocket> wrapper( - new extensions::TLSSocket(std::move(ssl_socket), extension_id)); - - // Caller will end up deleting the prior TCPSocket, once it calls - // SetSocket(..,wrapper). - callback.Run(std::move(wrapper), result); -} - -} // namespace - namespace extensions { const char kTLSSocketTypeInvalidError[] = "Cannot listen on a socket that is already connected."; -TLSSocket::TLSSocket(std::unique_ptr<net::StreamSocket> tls_socket, +TLSSocket::TLSSocket(network::mojom::TLSClientSocketPtr tls_socket, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream, const std::string& owner_extension_id) - : ResumableTCPSocket(owner_extension_id), - tls_socket_(std::move(tls_socket)) {} + : ResumableTCPSocket(nullptr, owner_extension_id), + tls_socket_(std::move(tls_socket)), + local_addr_(local_addr), + peer_addr_(peer_addr), + mojo_data_pump_(std::make_unique<MojoDataPump>(std::move(receive_stream), + std::move(send_stream))) { + DCHECK(tls_socket_); + is_connected_ = true; +} TLSSocket::~TLSSocket() { Disconnect(true /* socket_destroying */); } void TLSSocket::Connect(const net::AddressList& address, - const CompletionCallback& callback) { - callback.Run(net::ERR_CONNECTION_FAILED); + net::CompletionOnceCallback callback) { + std::move(callback).Run(net::ERR_CONNECTION_FAILED); } void TLSSocket::Disconnect(bool socket_destroying) { - if (tls_socket_) { - tls_socket_->Disconnect(); - tls_socket_.reset(); + is_connected_ = false; + tls_socket_.reset(); + local_addr_ = base::nullopt; + peer_addr_ = base::nullopt; + mojo_data_pump_ = nullptr; + // TODO(devlin): Should we do this for all callbacks? + if (read_callback_) { + std::move(read_callback_) + .Run(net::ERR_CONNECTION_CLOSED, nullptr, socket_destroying); } } -void TLSSocket::Read(int count, const ReadCompletionCallback& callback) { - DCHECK(!callback.is_null()); +void TLSSocket::Read(int count, ReadCompletionCallback callback) { + DCHECK(callback); + DCHECK(!read_callback_); const bool socket_destroying = false; - if (!read_callback_.is_null()) { - callback.Run(net::ERR_IO_PENDING, nullptr, socket_destroying); + if (!mojo_data_pump_) { + std::move(callback).Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, + socket_destroying); return; } - - if (count <= 0) { - callback.Run(net::ERR_INVALID_ARGUMENT, nullptr, socket_destroying); + if (mojo_data_pump_->HasPendingRead()) { + std::move(callback).Run(net::ERR_IO_PENDING, nullptr, socket_destroying); return; } - - if (!tls_socket_.get()) { - callback.Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, socket_destroying); - return; - } - - read_callback_ = callback; - scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(count)); - // |tls_socket_| is owned by this class and the callback won't be run once - // |tls_socket_| is gone (as in an a call to Disconnect()). Therefore, it is - // safe to use base::Unretained() here. - int result = tls_socket_->Read( - io_buffer.get(), - count, - base::Bind( - &TLSSocket::OnReadComplete, base::Unretained(this), io_buffer)); - - if (result != net::ERR_IO_PENDING) { - OnReadComplete(io_buffer, result); - } + read_callback_ = std::move(callback); + mojo_data_pump_->Read(count, base::BindOnce(&TLSSocket::OnReadComplete, + base::Unretained(this))); } -void TLSSocket::OnReadComplete(const scoped_refptr<net::IOBuffer>& io_buffer, - int result) { - DCHECK(!read_callback_.is_null()); - base::ResetAndReturn(&read_callback_) - .Run(result, io_buffer, false /* socket_destroying */); -} - -int TLSSocket::WriteImpl(net::IOBuffer* io_buffer, - int io_buffer_size, - const net::CompletionCallback& callback) { - if (!IsConnected()) { - return net::ERR_SOCKET_NOT_CONNECTED; - } - return tls_socket_->Write(io_buffer, io_buffer_size, callback, - Socket::GetNetworkTrafficAnnotationTag()); -} - -bool TLSSocket::SetKeepAlive(bool enable, int delay) { - return false; -} - -bool TLSSocket::SetNoDelay(bool no_delay) { - return false; -} - -int TLSSocket::Listen(const std::string& address, - uint16_t port, - int backlog, - std::string* error_msg) { - *error_msg = kTLSSocketTypeInvalidError; - return net::ERR_NOT_IMPLEMENTED; -} - -void TLSSocket::Accept(const AcceptCompletionCallback& callback) { - callback.Run(net::ERR_FAILED, NULL); +void TLSSocket::Listen(const std::string& address, + uint16_t port, + int backlog, + ListenCallback callback) { + std::move(callback).Run(net::ERR_NOT_IMPLEMENTED, kTLSSocketTypeInvalidError); } bool TLSSocket::IsConnected() { - return tls_socket_.get() && tls_socket_->IsConnected(); + return is_connected_; } bool TLSSocket::GetPeerAddress(net::IPEndPoint* address) { - return IsConnected() && tls_socket_->GetPeerAddress(address); + if (!IsConnected()) + return false; + if (!peer_addr_) + return false; + *address = peer_addr_.value(); + return true; } bool TLSSocket::GetLocalAddress(net::IPEndPoint* address) { - return IsConnected() && tls_socket_->GetLocalAddress(address); + if (!IsConnected()) + return false; + if (!local_addr_) + return false; + *address = local_addr_.value(); + return true; } Socket::SocketType TLSSocket::GetSocketType() const { return Socket::TYPE_TLS; } -// static -void TLSSocket::UpgradeSocketToTLS( - Socket* socket, - net::SSLConfigService* ssl_config_service, - net::CertVerifier* cert_verifier, - net::TransportSecurityState* transport_security_state, - net::CTVerifier* ct_verifier, - net::CTPolicyEnforcer* ct_policy_enforcer, - const std::string& extension_id, - api::socket::SecureOptions* options, - const TLSSocket::SecureCallback& callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - TCPSocket* tcp_socket = static_cast<TCPSocket*>(socket); - std::unique_ptr<net::SSLClientSocket> null_sock; +int TLSSocket::WriteImpl(net::IOBuffer* io_buffer, + int io_buffer_size, + const net::CompletionCallback& callback) { + if (!mojo_data_pump_) + return net::ERR_SOCKET_NOT_CONNECTED; + mojo_data_pump_->Write(io_buffer, io_buffer_size, + base::BindOnce(&TLSSocket::OnWriteComplete, + base::Unretained(this), callback)); + return net::ERR_IO_PENDING; +} - if (!tcp_socket || tcp_socket->GetSocketType() != Socket::TYPE_TCP || - !tcp_socket->ClientStream() || !tcp_socket->IsConnected() || - tcp_socket->HasPendingRead()) { - DVLOG(1) << "Failing before trying. socket is " << tcp_socket; - if (tcp_socket) { - DVLOG(1) << "type: " << tcp_socket->GetSocketType() - << ", ClientStream is " << tcp_socket->ClientStream() - << ", IsConnected: " << tcp_socket->IsConnected() - << ", HasPendingRead: " << tcp_socket->HasPendingRead(); - } - TlsConnectDone(std::move(null_sock), extension_id, callback, - net::ERR_INVALID_ARGUMENT); - return; +void TLSSocket::OnWriteComplete(const net::CompletionCallback& callback, + int result) { + if (result < 0) { + // Write side has terminated. This can be an error or a graceful close. + // TCPSocketEventDispatcher doesn't distinguish between the two. + Disconnect(false /* socket_destroying */); } + callback.Run(result); +} - net::IPEndPoint dest_host_port_pair; - if (!tcp_socket->GetPeerAddress(&dest_host_port_pair)) { - DVLOG(1) << "Could not get peer address."; - TlsConnectDone(std::move(null_sock), extension_id, callback, - net::ERR_INVALID_ARGUMENT); - return; +void TLSSocket::OnReadComplete(int result, + scoped_refptr<net::IOBuffer> io_buffer) { + DCHECK(read_callback_); + + // Use a local variable for |read_callback_|, because otherwise Disconnect() + // will try to invoke |read_callback_| with a hardcoded result code. + ReadCompletionCallback callback = std::move(read_callback_); + if (result < 0) { + // Read side has terminated. This can be an error or a graceful close. + // TCPSocketEventDispatcher doesn't distinguish between the two. + Disconnect(false /* socket_destroying */); } - - // Convert any U-LABELs to A-LABELs. - url::CanonHostInfo host_info; - std::string canon_host = - net::CanonicalizeHost(tcp_socket->hostname(), &host_info); - - // Canonicalization shouldn't fail: the socket is already connected with a - // host, using this hostname. - if (host_info.family == url::CanonHostInfo::BROKEN) { - DVLOG(1) << "Could not canonicalize hostname"; - TlsConnectDone(std::move(null_sock), extension_id, callback, - net::ERR_INVALID_ARGUMENT); - return; - } - - net::HostPortPair host_and_port(canon_host, dest_host_port_pair.port()); - - std::unique_ptr<net::ClientSocketHandle> socket_handle( - new net::ClientSocketHandle()); - - // Set the socket handle to the socket's client stream (that should be the - // only one active here). Then have the old socket release ownership on - // that client stream. - socket_handle->SetSocket( - base::WrapUnique<net::StreamSocket>(tcp_socket->ClientStream())); - tcp_socket->Release(); - - DCHECK(transport_security_state); - net::SSLClientSocketContext context; - context.cert_verifier = cert_verifier; - context.transport_security_state = transport_security_state; - context.cert_transparency_verifier = ct_verifier; - context.ct_policy_enforcer = ct_policy_enforcer; - - // Fill in the SSL socket params. - net::SSLConfig ssl_config; - ssl_config_service->GetSSLConfig(&ssl_config); - if (options && options->tls_version.get()) { - uint16_t version_min = 0, version_max = 0; - api::socket::TLSVersionConstraints* versions = options->tls_version.get(); - if (versions->min.get()) { - version_min = SSLProtocolVersionFromString(*versions->min); - } - if (versions->max.get()) { - version_max = SSLProtocolVersionFromString(*versions->max); - } - if (version_min) { - ssl_config.version_min = version_min; - } - if (version_max) { - ssl_config.version_max = version_max; - } - } - - net::ClientSocketFactory* socket_factory = - net::ClientSocketFactory::GetDefaultFactory(); - - // Create the socket. - std::unique_ptr<net::SSLClientSocket> ssl_socket( - socket_factory->CreateSSLClientSocket( - std::move(socket_handle), host_and_port, ssl_config, context)); - - DVLOG(1) << "Attempting to secure a connection to " << tcp_socket->hostname() - << ":" << dest_host_port_pair.port(); - - // We need the contents of |ssl_socket| in order to invoke its Connect() - // method. It belongs to |ssl_socket|, and we own that until our internal - // callback (|connect_cb|, below) is invoked. - net::SSLClientSocket* saved_ssl_socket = ssl_socket.get(); - - // Try establish a TLS connection. Pass ownership of |ssl_socket| to - // TlsConnectDone, which will pass it on to |callback|. |connect_cb| below - // is only for UpgradeSocketToTLS use, and not be confused with the - // argument |callback|, which gets invoked by TlsConnectDone() after - // Connect() below returns. - base::Callback<void(int)> connect_cb(base::Bind( - &TlsConnectDone, base::Passed(&ssl_socket), extension_id, callback)); - int status = saved_ssl_socket->Connect(connect_cb); - saved_ssl_socket = NULL; - - // Connect completed synchronously, or failed. - if (status != net::ERR_IO_PENDING) { - // Note: this can't recurse -- if |socket| is already a connected - // TLSSocket, it will return TYPE_TLS instead of TYPE_TCP, causing - // UpgradeSocketToTLS() to fail with an error above. If - // UpgradeSocketToTLS() is called on |socket| twice, the call to - // Release() on |socket| above causes the additional call to - // fail with an error above. - if (status != net::OK) { - DVLOG(1) << "Status is not OK or IO-pending: " - << net::ErrorToString(status); - } - connect_cb.Run(status); - } + std::move(callback).Run(result, io_buffer, false /* socket_destroying */); } } // namespace extensions -
diff --git a/extensions/browser/api/socket/tls_socket.h b/extensions/browser/api/socket/tls_socket.h index c3208e2..99846ea 100644 --- a/extensions/browser/api/socket/tls_socket.h +++ b/extensions/browser/api/socket/tls_socket.h
@@ -7,24 +7,19 @@ #include <stdint.h> +#include <memory> #include <string> +#include "extensions/browser/api/socket/mojo_data_pump.h" #include "extensions/browser/api/socket/socket.h" #include "extensions/browser/api/socket/socket_api.h" #include "extensions/browser/api/socket/tcp_socket.h" -#include "net/ssl/ssl_config_service.h" - -namespace net { -class Socket; -class CertVerifier; -class CTPolicyEnforcer; -class CTVerifier; -class TransportSecurityState; -} +#include "mojo/public/cpp/system/data_pipe.h" +#include "services/network/public/mojom/tls_socket.mojom.h" namespace extensions { -class TLSSocket; +class MojoDataPump; // TLS Sockets from the chrome.socket and chrome.sockets.tcp APIs. A regular // TCPSocket is converted to a TLSSocket via chrome.socket.secure() or @@ -38,84 +33,55 @@ // touch any socket state. class TLSSocket : public ResumableTCPSocket { public: - typedef base::Callback<void(std::unique_ptr<TLSSocket>, int)> SecureCallback; - - TLSSocket(std::unique_ptr<net::StreamSocket> tls_socket, + TLSSocket(network::mojom::TLSClientSocketPtr tls_socket, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_stream, + mojo::ScopedDataPipeProducerHandle send_stream, const std::string& owner_extension_id); ~TLSSocket() override; - // Most of these methods either fail or forward the method call on to the - // inner net::StreamSocket. The remaining few do actual TLS work. - // Fails. void Connect(const net::AddressList& address, - const CompletionCallback& callback) override; + net::CompletionOnceCallback callback) override; // Forwards. void Disconnect(bool socket_destroying) override; // Attempts to read |count| bytes of decrypted data from the TLS socket, // invoking |callback| with the actual number of bytes read, or a network // error code if an error occurred. - void Read(int count, const ReadCompletionCallback& callback) override; - - // Fails. This should have been called on the TCP socket before secure() was - // invoked. - bool SetKeepAlive(bool enable, int delay) override; - - // Fails. This should have been called on the TCP socket before secure() was - // invoked. - bool SetNoDelay(bool no_delay) override; + void Read(int count, ReadCompletionCallback callback) override; // Fails. TLSSocket is only a client. - int Listen(const std::string& address, - uint16_t port, - int backlog, - std::string* error_msg) override; - - // Fails. TLSSocket is only a client. - void Accept(const AcceptCompletionCallback& callback) override; + void Listen(const std::string& address, + uint16_t port, + int backlog, + ListenCallback callback) override; // Forwards. bool IsConnected() override; - // Forwards. bool GetPeerAddress(net::IPEndPoint* address) override; - // Forwards. bool GetLocalAddress(net::IPEndPoint* address) override; // Returns TYPE_TLS. SocketType GetSocketType() const override; - // Convert |socket| to a TLS socket. |socket| must be an open TCP client - // socket. |socket| must not have a pending read. UpgradeSocketToTLS() must - // be invoked in the IO thread. |callback| will always be invoked. |options| - // may be NULL. - // Note: |callback| may be synchronously invoked before - // UpgradeSocketToTLS() returns. Currently using the older chrome.socket - // version of SecureOptions, to avoid having the older API implementation - // depend on the newer one. - static void UpgradeSocketToTLS( - Socket* socket, - net::SSLConfigService* config_service, - net::CertVerifier* cert_verifier, - net::TransportSecurityState* transport_security_state, - net::CTVerifier* ct_verifier, - net::CTPolicyEnforcer* ct_policy_enforcer, - const std::string& extension_id, - api::socket::SecureOptions* options, - const SecureCallback& callback); - private: int WriteImpl(net::IOBuffer* io_buffer, int io_buffer_size, const net::CompletionCallback& callback) override; + void OnWriteComplete(const net::CompletionCallback& callback, int result); + void OnReadComplete(int result, scoped_refptr<net::IOBuffer> io_buffer); - void OnReadComplete(const scoped_refptr<net::IOBuffer>& io_buffer, - int result); - - std::unique_ptr<net::StreamSocket> tls_socket_; + network::mojom::TLSClientSocketPtr tls_socket_; + base::Optional<net::IPEndPoint> local_addr_; + base::Optional<net::IPEndPoint> peer_addr_; + std::unique_ptr<MojoDataPump> mojo_data_pump_; ReadCompletionCallback read_callback_; + + DISALLOW_COPY_AND_ASSIGN(TLSSocket); }; } // namespace extensions
diff --git a/extensions/browser/api/socket/udp_socket.cc b/extensions/browser/api/socket/udp_socket.cc index 094508e3..f9b8aa9 100644 --- a/extensions/browser/api/socket/udp_socket.cc +++ b/extensions/browser/api/socket/udp_socket.cc
@@ -5,6 +5,7 @@ #include "extensions/browser/api/socket/udp_socket.h" #include <algorithm> +#include <utility> #include "base/callback_helpers.h" #include "base/lazy_instance.h" @@ -46,9 +47,9 @@ } void UDPSocket::Connect(const net::AddressList& address, - const net::CompletionCallback& callback) { + net::CompletionOnceCallback callback) { if (IsConnectedOrBound()) { - callback.Run(net::ERR_CONNECTION_FAILED); + std::move(callback).Run(net::ERR_CONNECTION_FAILED); return; } // UDP API only connects to the first address received from DNS so @@ -57,7 +58,7 @@ socket_->Connect( ip_end_point, std::move(socket_options_), base::BindOnce(&UDPSocket::OnConnectCompleted, base::Unretained(this), - callback, ip_end_point)); + std::move(callback), ip_end_point)); } void UDPSocket::Bind(const std::string& address, @@ -94,27 +95,28 @@ multicast_groups_.clear(); } -void UDPSocket::Read(int count, const ReadCompletionCallback& callback) { +void UDPSocket::Read(int count, ReadCompletionCallback callback) { DCHECK(!callback.is_null()); if (!read_callback_.is_null()) { - callback.Run(net::ERR_IO_PENDING, nullptr, false /* socket_destroying */); + std::move(callback).Run(net::ERR_IO_PENDING, nullptr, + false /* socket_destroying */); return; } if (count < 0) { - callback.Run(net::ERR_INVALID_ARGUMENT, nullptr, - false /* socket_destroying */); + std::move(callback).Run(net::ERR_INVALID_ARGUMENT, nullptr, + false /* socket_destroying */); return; } if (!IsConnected()) { - callback.Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, - false /* socket_destroying */); + std::move(callback).Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, + false /* socket_destroying */); return; } - read_callback_ = callback; + read_callback_ = std::move(callback); socket_->ReceiveMoreWithBufferSize(1, count); return; } @@ -220,7 +222,7 @@ uint16_t port = 0; if (result != net::OK) { if (!read_callback_.is_null()) { - base::ResetAndReturn(&read_callback_) + std::move(read_callback_) .Run(result, nullptr, false /* socket_destroying */); return; } @@ -234,7 +236,7 @@ memcpy(io_buffer->data(), data.value().data(), data.value().size()); if (!read_callback_.is_null()) { - base::ResetAndReturn(&read_callback_) + std::move(read_callback_) .Run(data.value().size(), io_buffer, false /* socket_destroying */); return; } @@ -246,18 +248,18 @@ } void UDPSocket::OnConnectCompleted( - const net::CompletionCallback& callback, + net::CompletionOnceCallback callback, const net::IPEndPoint& remote_addr, int result, const base::Optional<net::IPEndPoint>& local_addr) { if (result != net::OK) { - callback.Run(result); + std::move(callback).Run(result); return; } local_addr_ = local_addr; peer_addr_ = remote_addr; is_connected_ = true; - callback.Run(result); + std::move(callback).Run(result); } void UDPSocket::OnBindCompleted(
diff --git a/extensions/browser/api/socket/udp_socket.h b/extensions/browser/api/socket/udp_socket.h index 6f46aaa..9c4fdfc 100644 --- a/extensions/browser/api/socket/udp_socket.h +++ b/extensions/browser/api/socket/udp_socket.h
@@ -28,12 +28,12 @@ // Socket implementation. void Connect(const net::AddressList& address, - const CompletionCallback& callback) override; + net::CompletionOnceCallback callback) override; void Disconnect(bool socket_destroying) override; void Bind(const std::string& address, uint16_t port, const CompletionCallback& callback) override; - void Read(int count, const ReadCompletionCallback& callback) override; + void Read(int count, ReadCompletionCallback callback) override; void RecvFrom(int count, const RecvFromCompletionCallback& callback) override; void SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, @@ -76,7 +76,7 @@ const base::Optional<net::IPEndPoint>& src_addr, base::Optional<base::span<const uint8_t>> data) override; - void OnConnectCompleted(const net::CompletionCallback& user_callback, + void OnConnectCompleted(net::CompletionOnceCallback user_callback, const net::IPEndPoint& remote_addr, int result, const base::Optional<net::IPEndPoint>& local_addr);
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc index dbc43166..c0aeac5 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc
@@ -4,6 +4,10 @@ #include "extensions/browser/api/sockets_tcp/sockets_tcp_api.h" +#include <string> +#include <utility> +#include <vector> + #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" @@ -124,7 +128,8 @@ } void SocketsTcpCreateFunction::Work() { - ResumableTCPSocket* socket = new ResumableTCPSocket(extension_->id()); + ResumableTCPSocket* socket = + new ResumableTCPSocket(browser_context(), extension_->id()); sockets_tcp::SocketProperties* properties = params_->properties.get(); if (properties) { @@ -203,20 +208,28 @@ return true; } -void SocketsTcpSetKeepAliveFunction::Work() { +void SocketsTcpSetKeepAliveFunction::AsyncWorkStart() { ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id); if (!socket) { error_ = kSocketNotFoundError; + results_ = sockets_tcp::SetKeepAlive::Results::Create(net::ERR_FAILED); + AsyncWorkCompleted(); return; } int delay = params_->delay ? *params_->delay : 0; - bool success = socket->SetKeepAlive(params_->enable, delay); + socket->SetKeepAlive( + params_->enable, delay, + base::BindOnce(&SocketsTcpSetKeepAliveFunction::OnCompleted, this)); +} + +void SocketsTcpSetKeepAliveFunction::OnCompleted(bool success) { int net_result = (success ? net::OK : net::ERR_FAILED); + results_ = sockets_tcp::SetKeepAlive::Results::Create(net_result); if (net_result != net::OK) error_ = net::ErrorToString(net_result); - results_ = sockets_tcp::SetKeepAlive::Results::Create(net_result); + AsyncWorkCompleted(); } SocketsTcpSetNoDelayFunction::SocketsTcpSetNoDelayFunction() {} @@ -229,18 +242,25 @@ return true; } -void SocketsTcpSetNoDelayFunction::Work() { +void SocketsTcpSetNoDelayFunction::AsyncWorkStart() { ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id); if (!socket) { error_ = kSocketNotFoundError; + results_ = sockets_tcp::SetNoDelay::Results::Create(net::ERR_FAILED); + AsyncWorkCompleted(); return; } + socket->SetNoDelay( + params_->no_delay, + base::BindOnce(&SocketsTcpSetNoDelayFunction::OnCompleted, this)); +} - bool success = socket->SetNoDelay(params_->no_delay); +void SocketsTcpSetNoDelayFunction::OnCompleted(bool success) { int net_result = (success ? net::OK : net::ERR_FAILED); + results_ = sockets_tcp::SetNoDelay::Results::Create(net_result); if (net_result != net::OK) error_ = net::ErrorToString(net_result); - results_ = sockets_tcp::SetNoDelay::Results::Create(net_result); + AsyncWorkCompleted(); } SocketsTcpConnectFunction::SocketsTcpConnectFunction() @@ -458,8 +478,6 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); params_ = api::sockets_tcp::Secure::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params_.get()); - url_request_getter_ = content::BrowserContext::GetDefaultStoragePartition( - browser_context())->GetURLRequestContext(); return true; } @@ -481,8 +499,7 @@ // Make sure it's a connected TCP client socket. Error out if it's already // secure()'d. - if (socket->GetSocketType() != Socket::TYPE_TCP || - socket->ClientStream() == NULL) { + if (socket->GetSocketType() != Socket::TYPE_TCP) { SetResult(std::make_unique<base::Value>(net::ERR_INVALID_ARGUMENT)); error_ = kInvalidSocketStateError; AsyncWorkCompleted(); @@ -496,9 +513,6 @@ return; } - net::URLRequestContext* url_request_context = - url_request_getter_->GetURLRequestContext(); - // UpgradeSocketToTLS() uses the older API's SecureOptions. Copy over the // only values inside -- TLSVersionConstraints's |min| and |max|, api::socket::SecureOptions legacy_params; @@ -514,29 +528,33 @@ } } - TLSSocket::UpgradeSocketToTLS( - socket, url_request_context->ssl_config_service(), - url_request_context->cert_verifier(), - url_request_context->transport_security_state(), - url_request_context->cert_transparency_verifier(), - url_request_context->ct_policy_enforcer(), extension_id(), &legacy_params, - base::Bind(&SocketsTcpSecureFunction::TlsConnectDone, this)); + network::mojom::TLSClientSocketPtr tls_socket; + socket->UpgradeToTLS( + &legacy_params, + base::BindOnce(&SocketsTcpSecureFunction::TlsConnectDone, this)); } -void SocketsTcpSecureFunction::TlsConnectDone(std::unique_ptr<TLSSocket> socket, - int result) { - // If an error occurred, socket MUST be NULL - DCHECK(result == net::OK || socket == NULL); - - if (socket && result == net::OK) { - socket->set_persistent(persistent_); - socket->set_paused(paused_); - ReplaceSocket(params_->socket_id, socket.release()); - } else { +void SocketsTcpSecureFunction::TlsConnectDone( + int result, + network::mojom::TLSClientSocketPtr tls_socket, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle) { + if (result != net::OK) { RemoveSocket(params_->socket_id); error_ = net::ErrorToString(result); + results_ = api::sockets_tcp::Secure::Results::Create(result); + AsyncWorkCompleted(); + return; } - + auto socket = + std::make_unique<TLSSocket>(std::move(tls_socket), local_addr, peer_addr, + std::move(receive_pipe_handle), + std::move(send_pipe_handle), extension_id()); + socket->set_persistent(persistent_); + socket->set_paused(paused_); + ReplaceSocket(params_->socket_id, socket.release()); results_ = api::sockets_tcp::Secure::Results::Create(result); AsyncWorkCompleted(); }
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api.h b/extensions/browser/api/sockets_tcp/sockets_tcp_api.h index c4b3ee8..fd004e7 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_api.h +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api.h
@@ -7,14 +7,16 @@ #include <stddef.h> +#include <memory> + #include "base/gtest_prod_util.h" #include "base/macros.h" #include "extensions/browser/api/socket/socket_api.h" #include "extensions/common/api/sockets_tcp.h" +#include "services/network/public/mojom/tcp_socket.mojom.h" namespace extensions { class ResumableTCPSocket; -class TLSSocket; } namespace extensions { @@ -108,9 +110,11 @@ // AsyncApiFunction bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(bool success); + std::unique_ptr<sockets_tcp::SetKeepAlive::Params> params_; }; @@ -125,9 +129,11 @@ // AsyncApiFunction bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(bool success); + std::unique_ptr<sockets_tcp::SetNoDelay::Params> params_; }; @@ -255,13 +261,16 @@ void AsyncWorkStart() override; private: - virtual void TlsConnectDone(std::unique_ptr<extensions::TLSSocket> sock, - int result); + void TlsConnectDone(int result, + network::mojom::TLSClientSocketPtr tls_socket, + const net::IPEndPoint& local_addr, + const net::IPEndPoint& peer_addr, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle); bool paused_; bool persistent_; std::unique_ptr<sockets_tcp::Secure::Params> params_; - scoped_refptr<net::URLRequestContextGetter> url_request_getter_; DISALLOW_COPY_AND_ASSIGN(SocketsTcpSecureFunction); };
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc index 4d62b093..918b2a0e 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc
@@ -4,8 +4,14 @@ #include <utility> +#include "base/command_line.h" #include "base/memory/ref_counted.h" #include "base/strings/stringprintf.h" +#include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/service_manager_connection.h" +#include "content/public/common/service_names.mojom.h" +#include "content/public/test/network_service_test_helper.h" #include "extensions/browser/api/dns/host_resolver_wrapper.h" #include "extensions/browser/api/dns/mock_host_resolver_creator.h" #include "extensions/browser/api/sockets_tcp/sockets_tcp_api.h" @@ -16,8 +22,11 @@ #include "extensions/shell/test/shell_test.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" +#include "mojo/public/cpp/bindings/sync_call_restrictions.h" #include "net/dns/mock_host_resolver.h" #include "net/test/spawned_test_server/spawned_test_server.h" +#include "services/network/public/cpp/features.h" +#include "services/service_manager/public/cpp/connector.h" namespace extensions { @@ -25,14 +34,18 @@ class SocketsTcpApiTest : public ShellApiTest { public: - SocketsTcpApiTest() - : resolver_event_(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED), - resolver_creator_(new MockHostResolverCreator()) {} + SocketsTcpApiTest() : resolver_creator_(new MockHostResolverCreator()) { + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kUseMockCertVerifierForTesting); + } + } void SetUpOnMainThread() override { ShellApiTest::SetUpOnMainThread(); + // TODO(xunjieli): Figure out what to do with this in-process host resolver + // which doesn't work with the out-of-process network service. HostResolverWrapper::GetInstance()->SetHostResolverForTesting( resolver_creator_->CreateMockHostResolver()); } @@ -45,8 +58,6 @@ } private: - base::WaitableEvent resolver_event_; - // The MockHostResolver asserts that it's used on the same thread on which // it's created, which is actually a stronger rule than its real counterpart. // But that's fine; it's good practice. @@ -101,6 +112,19 @@ } IN_PROC_BROWSER_TEST_F(SocketsTcpApiTest, SocketTcpExtensionTLS) { + network::mojom::NetworkServiceTestPtr network_service_test; + // If network service is running in a utility process, the cert of the + // SpawnedTestServer won't be recognized, so inject mock cert verifier through + // the test helper interface. + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->BindInterface(content::mojom::kNetworkServiceName, + &network_service_test); + mojo::ScopedAllowSyncCallForTesting allow_sync_call; + network_service_test->MockCertVerifierSetDefaultResult(net::OK); + } + std::unique_ptr<net::SpawnedTestServer> test_https_server( new net::SpawnedTestServer( net::SpawnedTestServer::TYPE_HTTPS, net::BaseTestServer::SSLOptions(),
diff --git a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc index 021ea5f..45b8a780 100644 --- a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc +++ b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.cc
@@ -4,6 +4,8 @@ #include "extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h" +#include <vector> + #include "content/public/common/socket_permission_request.h" #include "extensions/browser/api/socket/tcp_socket.h" #include "extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h" @@ -84,8 +86,8 @@ } void SocketsTcpServerCreateFunction::Work() { - ResumableTCPServerSocket* socket = - new ResumableTCPServerSocket(extension_->id()); + auto* socket = + new ResumableTCPServerSocket(browser_context(), extension_->id()); sockets_tcp_server::SocketProperties* properties = params_->properties.get(); if (properties) { @@ -190,10 +192,23 @@ return; } - int net_result = socket->Listen( + socket->Listen( params_->address, params_->port, params_->backlog.get() ? *params_->backlog : kDefaultListenBacklog, - &error_); + base::BindOnce(&SocketsTcpServerListenFunction::OnCompleted, this)); +} + +void SocketsTcpServerListenFunction::OnCompleted( + int net_result, + const std::string& /* error_msg */) { + DCHECK_NE(net::ERR_IO_PENDING, net_result); + + ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id); + if (!socket) { + error_ = kSocketNotFoundError; + AsyncWorkCompleted(); + return; + } results_ = sockets_tcp_server::Listen::Results::Create(net_result); if (net_result == net::OK) { socket_event_dispatcher_->OnServerSocketListen(extension_->id(),
diff --git a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h index b5f93c63..96ed487 100644 --- a/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h +++ b/extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h
@@ -5,6 +5,9 @@ #ifndef EXTENSIONS_BROWSER_API_SOCKETS_TCP_SERVER_SOCKETS_TCP_SERVER_API_H_ #define EXTENSIONS_BROWSER_API_SOCKETS_TCP_SERVER_SOCKETS_TCP_SERVER_API_H_ +#include <memory> +#include <string> + #include "base/gtest_prod_util.h" #include "extensions/browser/api/socket/socket_api.h" #include "extensions/common/api/sockets_tcp_server.h" @@ -98,6 +101,8 @@ void AsyncWorkStart() override; private: + void OnCompleted(int result, const std::string& error_msg); + std::unique_ptr<sockets_tcp_server::Listen::Params> params_; TCPServerSocketEventDispatcher* socket_event_dispatcher_; };
diff --git a/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.cc b/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.cc index 4854e8b7..565a037 100644 --- a/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.cc +++ b/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.cc
@@ -117,19 +117,24 @@ return; socket->Accept( - base::Bind(&TCPServerSocketEventDispatcher::AcceptCallback, params)); + base::BindOnce(&TCPServerSocketEventDispatcher::AcceptCallback, params)); } // static void TCPServerSocketEventDispatcher::AcceptCallback( const AcceptParams& params, int result_code, - std::unique_ptr<net::TCPClientSocket> socket) { + network::mojom::TCPConnectedSocketPtr socket, + const base::Optional<net::IPEndPoint>& remote_addr, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle) { DCHECK_CURRENTLY_ON(params.thread_id); + DCHECK_GE(net::OK, result_code); - if (result_code >= 0) { - ResumableTCPSocket* client_socket = - new ResumableTCPSocket(std::move(socket), params.extension_id, true); + if (result_code == net::OK) { + ResumableTCPSocket* client_socket = new ResumableTCPSocket( + std::move(socket), std::move(receive_pipe_handle), + std::move(send_pipe_handle), remote_addr, params.extension_id); client_socket->set_paused(true); int client_socket_id = params.client_sockets->Add(client_socket);
diff --git a/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h b/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h index 98fc928d..3da1e491 100644 --- a/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h +++ b/extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h
@@ -5,10 +5,14 @@ #ifndef EXTENSIONS_BROWSER_API_SOCKETS_TCP_SERVER_TCP_SERVER_SOCKET_EVENT_DISPATCHER_H_ #define EXTENSIONS_BROWSER_API_SOCKETS_TCP_SERVER_TCP_SERVER_SOCKET_EVENT_DISPATCHER_H_ +#include <memory> +#include <string> + #include "content/public/browser/browser_thread.h" #include "extensions/browser/api/api_resource_manager.h" #include "extensions/browser/api/sockets_tcp/sockets_tcp_api.h" #include "extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h" +#include "services/network/public/mojom/tcp_socket.mojom.h" namespace content { class BrowserContext; @@ -77,9 +81,13 @@ static void StartAccept(const AcceptParams& params); // Called when socket accepts a new connection. - static void AcceptCallback(const AcceptParams& params, - int result_code, - std::unique_ptr<net::TCPClientSocket> socket); + static void AcceptCallback( + const AcceptParams& params, + int result, + network::mojom::TCPConnectedSocketPtr socket, + const base::Optional<net::IPEndPoint>& remote_addr, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle); // Post an extension event from |thread_id| to UI thread static void PostEvent(const AcceptParams& params,
diff --git a/extensions/browser/api/system_display/system_display_apitest.cc b/extensions/browser/api/system_display/system_display_apitest.cc index 455341ea..54d9f99 100644 --- a/extensions/browser/api/system_display/system_display_apitest.cc +++ b/extensions/browser/api/system_display/system_display_apitest.cc
@@ -244,7 +244,13 @@ #if !defined(OS_CHROMEOS) -IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, SetDisplay) { +// TODO(crbug.com/866904): Fails sometimes on Win 10 dbg bots. +#if defined(OS_WIN) +#define MAYBE_SetDisplay DISABLED_SetDisplay +#else +#define MAYBE_SetDisplay SetDisplay +#endif // defined(OS_WIN) +IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, MAYBE_SetDisplay) { scoped_refptr<SystemDisplaySetDisplayPropertiesFunction> set_info_function( new SystemDisplaySetDisplayPropertiesFunction());
diff --git a/gin/arguments.cc b/gin/arguments.cc index b492fae6..82d5f43 100644 --- a/gin/arguments.cc +++ b/gin/arguments.cc
@@ -48,7 +48,7 @@ return info_->Holder()->CreationContext(); } -std::string V8TypeAsString(v8::Local<v8::Value> value) { +std::string V8TypeAsString(v8::Isolate* isolate, v8::Local<v8::Value> value) { if (value.IsEmpty()) return "<empty handle>"; if (value->IsUndefined()) @@ -56,7 +56,7 @@ if (value->IsNull()) return "null"; std::string result; - if (!ConvertFromV8(NULL, value, &result)) + if (!ConvertFromV8(isolate, value, &result)) return std::string(); return result; } @@ -67,7 +67,7 @@ return ThrowTypeError(base::StringPrintf( "Error processing argument at index %d, conversion failure from %s", - next_ - 1, V8TypeAsString((*info_)[next_ - 1]).c_str())); + next_ - 1, V8TypeAsString(isolate_, (*info_)[next_ - 1]).c_str())); } void Arguments::ThrowTypeError(const std::string& message) const {
diff --git a/gin/converter.h b/gin/converter.h index 72c1d70..a501714 100644 --- a/gin/converter.h +++ b/gin/converter.h
@@ -255,6 +255,7 @@ template<typename T> bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input, T* result) { + DCHECK(isolate); return Converter<T>::FromV8(isolate, input, result); }
diff --git a/google_apis/gcm/base/socket_stream.cc b/google_apis/gcm/base/socket_stream.cc index 776813b..6674d9c 100644 --- a/google_apis/gcm/base/socket_stream.cc +++ b/google_apis/gcm/base/socket_stream.cc
@@ -216,9 +216,7 @@ net::StreamSocket* socket, const net::NetworkTrafficAnnotationTag& traffic_annotation) : socket_(socket), - io_buffer_(new net::IOBuffer(kDefaultBufferSize)), - write_buffer_( - new net::DrainableIOBuffer(io_buffer_.get(), kDefaultBufferSize)), + io_buffer_(new net::IOBufferWithSize(kDefaultBufferSize)), next_pos_(0), last_error_(net::OK), traffic_annotation_(traffic_annotation), @@ -232,12 +230,12 @@ bool SocketOutputStream::Next(void** data, int* size) { DCHECK_NE(GetState(), CLOSED); DCHECK_NE(GetState(), FLUSHING); - if (next_pos_ == write_buffer_->size()) + if (next_pos_ == io_buffer_->size()) return false; - *data = write_buffer_->data() + next_pos_; - *size = write_buffer_->size() - next_pos_; - next_pos_ = write_buffer_->size(); + *data = io_buffer_->data() + next_pos_; + *size = io_buffer_->size() - next_pos_; + next_pos_ = io_buffer_->size(); return true; } @@ -259,15 +257,21 @@ net::Error SocketOutputStream::Flush(const base::Closure& callback) { DCHECK_EQ(GetState(), READY); + if (!write_buffer_) { + write_buffer_ = base::MakeRefCounted<net::DrainableIOBuffer>( + io_buffer_.get(), next_pos_); + } + if (!socket_->IsConnected()) { LOG(ERROR) << "Socket was disconnected, closing output stream"; last_error_ = net::ERR_CONNECTION_CLOSED; return net::OK; } - DVLOG(1) << "Flushing " << next_pos_ << " bytes into socket."; + DVLOG(1) << "Flushing " << write_buffer_->BytesRemaining() + << " bytes into socket."; int result = - socket_->Write(write_buffer_.get(), next_pos_, + socket_->Write(write_buffer_.get(), write_buffer_->BytesRemaining(), base::Bind(&SocketOutputStream::FlushCompletionCallback, weak_ptr_factory_.GetWeakPtr(), callback), traffic_annotation_); @@ -322,17 +326,17 @@ DCHECK_GT(result, net::OK); last_error_ = net::OK; + write_buffer_->DidConsume(result); - if (write_buffer_->BytesConsumed() + result < next_pos_) { + if (write_buffer_->BytesRemaining() > 0) { DVLOG(1) << "Partial flush complete. Retrying."; - // Only a partial write was completed. Flush again to finish the write. - write_buffer_->DidConsume(result); + // Only a partial write was completed. Flush again to finish the write. Flush(callback); return; } DVLOG(1) << "Socket flush complete."; - write_buffer_->SetOffset(0); + write_buffer_ = nullptr; next_pos_ = 0; if (!callback.is_null()) callback.Run();
diff --git a/google_apis/gcm/base/socket_stream.h b/google_apis/gcm/base/socket_stream.h index 2b85088..c68acd00 100644 --- a/google_apis/gcm/base/socket_stream.h +++ b/google_apis/gcm/base/socket_stream.h
@@ -23,6 +23,7 @@ namespace net { class DrainableIOBuffer; class IOBuffer; +class IOBufferWithSize; class StreamSocket; } // namespace net @@ -186,10 +187,10 @@ // Internal net components. net::StreamSocket* const socket_; - const scoped_refptr<net::IOBuffer> io_buffer_; + const scoped_refptr<net::IOBufferWithSize> io_buffer_; // IOBuffer implementation that wraps the data within |io_buffer_| that hasn't // been written to the socket yet. - const scoped_refptr<net::DrainableIOBuffer> write_buffer_; + scoped_refptr<net::DrainableIOBuffer> write_buffer_; // Starting position of the data within |io_buffer_| to consume on subsequent // Next(..) call. 0 <= write_buffer_.BytesConsumed() <= next_pos_
diff --git a/google_apis/gcm/base/socket_stream_unittest.cc b/google_apis/gcm/base/socket_stream_unittest.cc index 5f263e9f..7da26d1 100644 --- a/google_apis/gcm/base/socket_stream_unittest.cc +++ b/google_apis/gcm/base/socket_stream_unittest.cc
@@ -7,6 +7,9 @@ #include <stdint.h> #include <memory> +#include <string> +#include <utility> +#include <vector> #include "base/bind.h" #include "base/macros.h" @@ -32,6 +35,77 @@ const char kWriteData[] = "write_data"; const int kWriteDataSize = arraysize(kWriteData) - 1; +// A net::StreamSocket that returns a partial write only for the first time. +class FirstWritePartialSocket : public net::StreamSocket { + public: + FirstWritePartialSocket() {} + ~FirstWritePartialSocket() override {} + + // Returns the data that is actually written to the socket. + const std::string& actual_data_written() { return actual_data_written_; } + + // net::Socket implementation. + int Write( + net::IOBuffer* buf, + int buf_len, + net::CompletionOnceCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation) override { + // Make the first write as a partial write. + if (!write_invoked_) { + write_invoked_ = true; + actual_data_written_.append(buf->data(), buf_len / 2); + return buf_len / 2; + } + // For subsequent writes, write everything that caller has passed to us. + actual_data_written_.append(buf->data(), buf_len); + return buf_len; + } + int Read(net::IOBuffer* buf, + int buf_len, + net::CompletionOnceCallback callback) override { + return net::ERR_IO_PENDING; + } + int ReadIfReady(net::IOBuffer* buf, + int buf_len, + net::CompletionOnceCallback callback) override { + return net::ERR_IO_PENDING; + } + int CancelReadIfReady() override { return net::OK; } + int SetReceiveBufferSize(int32_t size) override { return net::OK; } + int SetSendBufferSize(int32_t size) override { return net::OK; } + + // net::StreamSocket implementation. + int Connect(net::CompletionOnceCallback callback) override { return net::OK; } + void Disconnect() override {} + bool IsConnected() const override { return true; } + bool IsConnectedAndIdle() const override { return true; }; + int GetPeerAddress(net::IPEndPoint* address) const override { + return net::OK; + } + int GetLocalAddress(net::IPEndPoint* address) const override { + return net::OK; + } + const net::NetLogWithSource& NetLog() const override { return net_log_; } + bool WasEverUsed() const override { return true; } + bool WasAlpnNegotiated() const override { return false; } + net::NextProto GetNegotiatedProtocol() const override { + return net::kProtoUnknown; + } + bool GetSSLInfo(net::SSLInfo* ssl_info) override { return false; } + void GetConnectionAttempts(net::ConnectionAttempts* out) const override {} + void ClearConnectionAttempts() override {} + void AddConnectionAttempts(const net::ConnectionAttempts& attempts) override { + } + int64_t GetTotalReceivedBytes() const override { return 0; } + void ApplySocketTag(const net::SocketTag& tag) override {} + + private: + net::NetLogWithSource net_log_; + std::string actual_data_written_; + // Whether Write() has been invoked before. + bool write_invoked_ = false; +}; + class GCMSocketStreamTest : public testing::Test { public: GCMSocketStreamTest(); @@ -59,6 +133,10 @@ SocketOutputStream* output_stream() { return socket_output_stream_.get(); } net::StreamSocket* socket() { return socket_.get(); } + void set_socket_output_stream(std::unique_ptr<SocketOutputStream> stream) { + socket_output_stream_ = std::move(stream); + } + private: void OpenConnection(); void ResetInputStream(); @@ -329,6 +407,17 @@ kWriteDataSize))); } +// Regression test for crbug.com/866635. +TEST_F(GCMSocketStreamTest, WritePartialWithLengthChecking) { + auto socket = std::make_unique<FirstWritePartialSocket>(); + auto socket_output_stream = std::make_unique<SocketOutputStream>( + socket.get(), TRAFFIC_ANNOTATION_FOR_TESTS); + set_socket_output_stream(std::move(socket_output_stream)); + ASSERT_EQ(kWriteDataSize, + DoOutputStreamWrite(base::StringPiece(kWriteData, kWriteDataSize))); + EXPECT_EQ(kWriteData, socket->actual_data_written()); +} + // Write a message completely asynchronously (returns IO_PENDING before // finishing the write in two go's). TEST_F(GCMSocketStreamTest, WriteNone) {
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 33cd9dc..cd23a01 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -41,6 +41,7 @@ #include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/command_buffer/client/vertex_array_object_manager.h" #include "gpu/command_buffer/common/context_creation_attribs.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/id_allocator.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/command_buffer/common/sync_token.h" @@ -124,11 +125,6 @@ } } -// A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. -GLuint ToGLuint(const void* ptr) { - return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); -} - static base::AtomicSequenceNumber g_flush_id; uint32_t GenerateNextFlushId() {
diff --git a/gpu/command_buffer/client/vertex_array_object_manager.cc b/gpu/command_buffer/client/vertex_array_object_manager.cc index 453de8c..0690c5e 100644 --- a/gpu/command_buffer/client/vertex_array_object_manager.cc +++ b/gpu/command_buffer/client/vertex_array_object_manager.cc
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" namespace gpu { namespace gles2 { @@ -19,11 +20,6 @@ return (size + 3) & ~3; } -// A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. -static GLuint ToGLuint(const void* ptr) { - return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); -} - // This class tracks VertexAttribPointers and helps emulate client side buffers. // // The way client side buffers work is we shadow all the Vertex Attribs so we
diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h index e959a0e5..61ffa634 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/gpu/command_buffer/common/gles2_cmd_utils.h
@@ -53,6 +53,12 @@ return checked.IsValid(); } +// A 32-bit and 64-bit compatible way of converting a pointer to a +// 32-bit usigned integer, suitable to be stored in a GLuint. +inline uint32_t ToGLuint(const void* ptr) { + return static_cast<uint32_t>(reinterpret_cast<size_t>(ptr)); +} + // Returns the address of the first byte after a struct. template <typename T> const volatile void* AddressAfterStruct(const volatile T& pod) {
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 4c4b7c60..bf9a384 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc
@@ -387,11 +387,6 @@ return feature_info->IsWebGL2OrES3Context(); } -// A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. -GLuint ToGLuint(const void* ptr) { - return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); -} - base::LazyInstance<const FormatTypeValidator>::Leaky g_format_type_validator = LAZY_INSTANCE_INITIALIZER;
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index d3b824d7..d9d588a 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -2866,8 +2866,8 @@ "os": { "type": "linux" }, - "vendor_id": "0x15ad", - "device_id": ["0x0405"], + "gl_vendor": "VMware.*", + "gl_renderer": "Gallium.*", "features": [ "disable_timestamp_queries" ],
diff --git a/gpu/vulkan/vulkan_command_pool.h b/gpu/vulkan/vulkan_command_pool.h index b54d5917..bd1b84c 100644 --- a/gpu/vulkan/vulkan_command_pool.h +++ b/gpu/vulkan/vulkan_command_pool.h
@@ -10,13 +10,14 @@ #include <memory> #include "base/macros.h" +#include "gpu/vulkan/vulkan_export.h" namespace gpu { class VulkanCommandBuffer; class VulkanDeviceQueue; -class VulkanCommandPool { +class VULKAN_EXPORT VulkanCommandPool { public: explicit VulkanCommandPool(VulkanDeviceQueue* device_queue); ~VulkanCommandPool();
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 191b4e1..da96b98 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -417,7 +417,7 @@ // |currentBVC| can be made active. - (void)activateBVCAndMakeCurrentBVCPrimary; // Sets |currentBVC| as the root view controller for the window. -- (void)displayCurrentBVC; +- (void)displayCurrentBVCAndFocusOmnibox:(BOOL)focusOmnibox; // Shows the tab switcher UI. - (void)showTabSwitcher; // Starts a voice search on the current BVC. @@ -458,8 +458,10 @@ - (bool)mustShowRestoreInfobar; // Begins the process of dismissing the tab switcher with the given current // model, switching which BVC is suspended if necessary, but not updating the -// UI. -- (void)beginDismissingTabSwitcherWithCurrentModel:(TabModel*)tabModel; +// UI. The omnibox will be focused after the tab switcher dismissal is +// completed if |focusOmnibox| is YES. +- (void)beginDismissingTabSwitcherWithCurrentModel:(TabModel*)tabModel + focusOmnibox:(BOOL)focusOmnibox; // Completes the process of dismissing the tab switcher, removing it from the // screen and showing the appropriate BVC. - (void)finishDismissingTabSwitcher; @@ -1800,7 +1802,7 @@ [_browserViewWrangler setCurrentBVC:bvc storageSwitcher:self]; if (!_dismissingTabSwitcher) - [self displayCurrentBVC]; + [self displayCurrentBVCAndFocusOmnibox:NO]; // Tell the BVC that was made current that it can use the web. [self activateBVCAndMakeCurrentBVCPrimary]; @@ -1894,9 +1896,16 @@ [self switchGlobalStateToMode:mode]; } -- (void)displayCurrentBVC { +- (void)displayCurrentBVCAndFocusOmnibox:(BOOL)focusOmnibox { + ProceduralBlock completion = nil; + if (focusOmnibox) { + __weak BrowserViewController* weakCurrentBVC = self.currentBVC; + completion = ^{ + [weakCurrentBVC.dispatcher focusOmnibox]; + }; + } [self.viewControllerSwapper showTabViewController:self.currentBVC - completion:nil]; + completion:completion]; [self.currentBVC.dispatcher setIncognitoContentVisible:(self.currentBVC == self.otrBVC)]; } @@ -2016,7 +2025,7 @@ [self dismissModalDialogsWithCompletion:nil dismissOmnibox:YES]; [_tabSwitcher tabSwitcherDismissWithModel:tabModel animated:NO]; } else { - [self beginDismissingTabSwitcherWithCurrentModel:tabModel]; + [self beginDismissingTabSwitcherWithCurrentModel:tabModel focusOmnibox:NO]; [self finishDismissingTabSwitcher]; } } @@ -2024,8 +2033,10 @@ #pragma mark - TabSwitcherDelegate - (void)tabSwitcher:(id<TabSwitcher>)tabSwitcher - shouldFinishWithActiveModel:(TabModel*)tabModel { - [self beginDismissingTabSwitcherWithCurrentModel:tabModel]; + shouldFinishWithActiveModel:(TabModel*)tabModel + focusOmnibox:(BOOL)focusOmnibox { + [self beginDismissingTabSwitcherWithCurrentModel:tabModel + focusOmnibox:focusOmnibox]; } - (void)tabSwitcherDismissTransitionDidEnd:(id<TabSwitcher>)tabSwitcher { @@ -2041,7 +2052,8 @@ #pragma mark - TabSwitcherDelegate helper methods -- (void)beginDismissingTabSwitcherWithCurrentModel:(TabModel*)tabModel { +- (void)beginDismissingTabSwitcherWithCurrentModel:(TabModel*)tabModel + focusOmnibox:(BOOL)focusOmnibox { DCHECK(tabModel == self.mainTabModel || tabModel == self.otrTabModel); _dismissingTabSwitcher = YES; @@ -2059,7 +2071,7 @@ // _dismissingTabSwitcher is YES. When the presentation experiment is // enabled, force the BVC transition to start. if (TabSwitcherPresentsBVCEnabled()) { - [self displayCurrentBVC]; + [self displayCurrentBVCAndFocusOmnibox:focusOmnibox]; } } @@ -2092,7 +2104,7 @@ _modeToDisplayOnTabSwitcherDismissal = TabSwitcherDismissalMode::NONE; // Displaying the current BVC dismisses the tab switcher. - [self displayCurrentBVC]; + [self displayCurrentBVCAndFocusOmnibox:NO]; ProceduralBlock action = [self completionBlockForTriggeringAction: self.NTPActionAfterTabSwitcherDismissal];
diff --git a/ios/chrome/app/resources/ios_resources.grd b/ios/chrome/app/resources/ios_resources.grd index 9c7dbfa..2cb2ac88 100644 --- a/ios/chrome/app/resources/ios_resources.grd +++ b/ios/chrome/app/resources/ios_resources.grd
@@ -11,6 +11,8 @@ <include name="IDR_IOS_OMAHA_HTML" file="omaha/omaha.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> <include name="IDR_IOS_OMAHA_JS" file="omaha/omaha.js" type="BINDATA" compress="gzip" /> <include name="IDR_CHROME_BROWSER_MANIFEST_OVERLAY" file="${root_gen_dir}/ios/chrome/app/chrome_browser_manifest_overlay.json" use_base_dir="false" type="BINDATA" /> + <include name="IDR_IOS_UKM_INTERNALS_HTML" file="../../../../components/ukm/debug/ukm_internals.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" /> + <include name="IDR_IOS_UKM_INTERNALS_JS" file="../../../../components/ukm/debug/ukm_internals.js" flattenhtml="true" compress="gzip" type="BINDATA" /> </includes> </release> </grit>
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn index 89f891f9..75658a2 100644 --- a/ios/chrome/browser/autofill/BUILD.gn +++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -14,7 +14,6 @@ "form_input_accessory_view_controller.h", "form_input_accessory_view_controller.mm", "form_input_accessory_view_delegate.h", - "form_input_accessory_view_provider.h", "form_suggestion_controller.h", "form_suggestion_controller.mm", "form_suggestion_label.h", @@ -30,6 +29,7 @@ "validation_rules_storage_factory.h", ] deps = [ + ":autofill_shared", "resources:autofill_close", "resources:autofill_close_pressed", "resources:autofill_keyboard_background", @@ -72,6 +72,14 @@ libs = [ "QuartzCore.framework" ] } +source_set("autofill_shared") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "form_input_accessory_view_provider.h", + ] + libs = [ "UIKit.framework" ] +} + source_set("autofill_internal") { configs += [ "//build/config/compiler:enable_arc" ] sources = [
diff --git a/ios/chrome/browser/metrics/ukm_egtest.mm b/ios/chrome/browser/metrics/ukm_egtest.mm index 50674449..09cd952 100644 --- a/ios/chrome/browser/metrics/ukm_egtest.mm +++ b/ios/chrome/browser/metrics/ukm_egtest.mm
@@ -38,6 +38,7 @@ #endif using chrome_test_util::AccountsSyncButton; +using chrome_test_util::ButtonWithAccessibilityLabel; using chrome_test_util::ButtonWithAccessibilityLabelId; using chrome_test_util::ClearBrowsingDataCollectionView; using chrome_test_util::GetIncognitoTabCount; @@ -194,13 +195,17 @@ // Signs out of sync. void SignOut() { [ChromeEarlGreyUI openSettingsMenu]; - [[EarlGrey selectElementWithMatcher:SettingsAccountButton()] + [ChromeEarlGreyUI tapSettingsMenuButton:SettingsAccountButton()]; + + // Remove |identity| from the device. + ChromeIdentity* identity = [SigninEarlGreyUtils fakeIdentity1]; + [[EarlGrey + selectElementWithMatcher:ButtonWithAccessibilityLabel(identity.userEmail)] performAction:grey_tap()]; - [ChromeEarlGreyUI tapAccountsMenuButton:SignOutAccountsButton()]; - [[EarlGrey selectElementWithMatcher: - ButtonWithAccessibilityLabelId( - IDS_IOS_DISCONNECT_DIALOG_CONTINUE_BUTTON_MOBILE)] + [[EarlGrey + selectElementWithMatcher:ButtonWithAccessibilityLabel(@"Remove account")] performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] performAction:grey_tap()]; @@ -216,11 +221,6 @@ @implementation UKMTestCase -// Per crbug.com/853992, Entire test suite is failing regularly. -+ (NSArray*)testInvocations { - return @[]; -} - + (void)setUp { [super setUp]; if (!base::FeatureList::IsEnabled(ukm::kUkmFeature)) { @@ -466,7 +466,8 @@ // testMetricsReporting not needed, since iOS doesn't use sampling. -- (void)testHistoryDelete { +// TODO(crbug.com/866598): Re-enable this test. +- (void)DISABLED_testHistoryDelete { uint64_t original_client_id = metrics::UkmEGTestHelper::client_id(); const ukm::SourceId kDummySourceId = 0x54321;
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn index 451a166..0bb9fa0 100644 --- a/ios/chrome/browser/ui/authentication/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -52,6 +52,7 @@ "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/alert_coordinator", + "//ios/chrome/browser/ui/authentication/consent_bump", "//ios/chrome/browser/ui/collection_view/cells", "//ios/chrome/browser/ui/colors", "//ios/chrome/browser/ui/commands", @@ -179,6 +180,7 @@ "//components/signin/core/browser", "//components/signin/core/browser:account_info", "//components/unified_consent", + "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/signin", "//ios/chrome/browser/ui/authentication/unified_consent:unified_consent_ui",
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/BUILD.gn b/ios/chrome/browser/ui/authentication/consent_bump/BUILD.gn new file mode 100644 index 0000000..a0ed320 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/BUILD.gn
@@ -0,0 +1,26 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chrome_build.gni") + +source_set("consent_bump") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "consent_bump_coordinator.h", + "consent_bump_coordinator.mm", + "consent_bump_personalization_coordinator.h", + "consent_bump_personalization_coordinator.mm", + "consent_bump_personalization_view_controller.h", + "consent_bump_personalization_view_controller.mm", + "consent_bump_view_controller.h", + "consent_bump_view_controller.mm", + "consent_bump_view_controller_delegate.h", + ] + deps = [ + "//base", + "//ios/chrome/browser/ui/authentication/unified_consent", + "//ios/chrome/browser/ui/coordinators:chrome_coordinators", + "//ios/chrome/common/ui_util", + ] +}
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator.h b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator.h new file mode 100644 index 0000000..181289c0 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator.h
@@ -0,0 +1,18 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_COORDINATOR_H_ + +#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" + +// Coordinator handling the consent bump. +@interface ConsentBumpCoordinator : ChromeCoordinator + +// ViewController associated with this coordinator. +@property(nonatomic, strong, readonly) UIViewController* viewController; + +@end + +#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator.mm b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator.mm new file mode 100644 index 0000000..d704b09 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator.mm
@@ -0,0 +1,115 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator.h" + +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_coordinator.h" +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller.h" +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller_delegate.h" +#import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +// Type of child coordinator presented by this coordinator. +typedef NS_ENUM(NSInteger, PresentedCoordinator) { + PresentedCoordinatorUnifiedConsent, + PresentedCoordinatorPersonalization, +}; +} // namespace + +@interface ConsentBumpCoordinator ()<ConsentBumpViewControllerDelegate> + +// Which child coordinator is currently presented. +@property(nonatomic, assign) PresentedCoordinator presentedCoordinator; + +// The ViewController of this coordinator, redefined as a +// ConsentBumpViewController. +@property(nonatomic, strong) + ConsentBumpViewController* consentBumpViewController; +// The child coordinator presenting the unified consent. +@property(nonatomic, strong) + UnifiedConsentCoordinator* unifiedConsentCoordinator; +// The child coordinator presenting the presonalization content. +@property(nonatomic, strong) + ConsentBumpPersonalizationCoordinator* personalizationCoordinator; + +@end + +@implementation ConsentBumpCoordinator + +@synthesize presentedCoordinator = _presentedCoordinator; +@synthesize consentBumpViewController = _consentBumpViewController; +@synthesize unifiedConsentCoordinator = _unifiedConsentCoordinator; +@synthesize personalizationCoordinator = _personalizationCoordinator; + +#pragma mark - Properties + +- (UIViewController*)viewController { + return self.consentBumpViewController; +} + +#pragma mark - ChromeCoordinator + +- (void)start { + self.consentBumpViewController = [[ConsentBumpViewController alloc] init]; + self.consentBumpViewController.delegate = self; + + self.unifiedConsentCoordinator = [[UnifiedConsentCoordinator alloc] init]; + [self.unifiedConsentCoordinator start]; + self.presentedCoordinator = PresentedCoordinatorUnifiedConsent; + + self.consentBumpViewController.contentViewController = + self.unifiedConsentCoordinator.viewController; +} + +- (void)stop { + self.consentBumpViewController = nil; + self.unifiedConsentCoordinator = nil; + self.personalizationCoordinator = nil; +} + +#pragma mark - ConsentBumpViewControllerDelegate + +- (void)consentBumpViewControllerDidTapPrimaryButton: + (ConsentBumpViewController*)consentBumpViewController { + switch (self.presentedCoordinator) { + case PresentedCoordinatorUnifiedConsent: + // TODO(crbug.com/866506): Consent bump accepted. + break; + case PresentedCoordinatorPersonalization: + // TODO(crbug.com/866506): Clarify what should be the behavior at this + // point. + break; + } +} + +- (void)consentBumpViewControllerDidTapSecondaryButton: + (ConsentBumpViewController*)consentBumpViewController { + switch (self.presentedCoordinator) { + case PresentedCoordinatorUnifiedConsent: + // Present the personlization. + if (!self.personalizationCoordinator) { + self.personalizationCoordinator = + [[ConsentBumpPersonalizationCoordinator alloc] + initWithBaseViewController:nil]; + [self.personalizationCoordinator start]; + } + self.consentBumpViewController.contentViewController = + self.personalizationCoordinator.viewController; + self.presentedCoordinator = PresentedCoordinatorPersonalization; + break; + + case PresentedCoordinatorPersonalization: + // Go back to the unified consent. + self.consentBumpViewController.contentViewController = + self.unifiedConsentCoordinator.viewController; + self.presentedCoordinator = PresentedCoordinatorUnifiedConsent; + break; + } +} + +@end
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_coordinator.h b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_coordinator.h new file mode 100644 index 0000000..4611b12d --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_coordinator.h
@@ -0,0 +1,18 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_COORDINATOR_H_ + +#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" + +// Coordinator for handling the ConsentBump Personalization screen. +@interface ConsentBumpPersonalizationCoordinator : ChromeCoordinator + +// The view Controller for this coordinator. +@property(nonatomic, strong, readonly) UIViewController* viewController; + +@end + +#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_coordinator.mm b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_coordinator.mm new file mode 100644 index 0000000..9dff249 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_coordinator.mm
@@ -0,0 +1,42 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_coordinator.h" + +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_view_controller.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface ConsentBumpPersonalizationCoordinator () + +// The view controller, redefined as ConsentBumpPersonalizationViewController. +@property(nonatomic, strong) + ConsentBumpPersonalizationViewController* personalizationViewController; + +@end + +@implementation ConsentBumpPersonalizationCoordinator + +@synthesize personalizationViewController = _personalizationViewController; + +#pragma mark - Properties + +- (UIViewController*)viewController { + return self.personalizationViewController; +} + +#pragma mark - ChromeCoordinator + +- (void)start { + self.personalizationViewController = + [[ConsentBumpPersonalizationViewController alloc] init]; +} + +- (void)stop { + self.personalizationViewController = nil; +} + +@end
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_view_controller.h b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_view_controller.h new file mode 100644 index 0000000..064ba0f --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_view_controller.h
@@ -0,0 +1,15 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_VIEW_CONTROLLER_H_ + +#import <UIKit/UIKit.h> + +// View controller displaying the Personalization screen. +@interface ConsentBumpPersonalizationViewController : UIViewController + +@end + +#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_view_controller.mm b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_view_controller.mm new file mode 100644 index 0000000..b1d3f554 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_view_controller.mm
@@ -0,0 +1,17 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_personalization_view_controller.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation ConsentBumpPersonalizationViewController + +- (void)viewDidLoad { + self.view.backgroundColor = [UIColor blueColor]; +} + +@end
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller.h b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller.h new file mode 100644 index 0000000..3640b4a --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller.h
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_VIEW_CONTROLLER_H_ + +#import <UIKit/UIKit.h> + +@protocol ConsentBumpViewControllerDelegate; + +// View Controller handling the ConsentBump screen. +@interface ConsentBumpViewController : UIViewController + +// Delegate for the view controller. +@property(nonatomic, weak) id<ConsentBumpViewControllerDelegate> delegate; + +// View controller displayed as child view controller for this ViewController. +@property(nonatomic, strong) UIViewController* contentViewController; + +@end + +#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller.mm b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller.mm new file mode 100644 index 0000000..ef7f439 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller.mm
@@ -0,0 +1,182 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller.h" + +#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller_delegate.h" +#import "ios/chrome/common/ui_util/constraints_ui_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +const CGFloat kMargin = 16; +const CGFloat kGradientHeight = 40; +} // namespace + +@interface ConsentBumpViewController () + +@property(nonatomic, strong) UIView* buttonContainer; +@property(nonatomic, strong) UIButton* primaryButton; +@property(nonatomic, strong) UIButton* secondaryButton; +@property(nonatomic, strong) UIView* gradientView; +@property(nonatomic, strong) CAGradientLayer* gradientLayer; + +@end + +@implementation ConsentBumpViewController + +@synthesize delegate = _delegate; +@synthesize contentViewController = _contentViewController; +@synthesize buttonContainer = _buttonContainer; +@synthesize primaryButton = _primaryButton; +@synthesize secondaryButton = _secondaryButton; +@synthesize gradientView = _gradientView; +@synthesize gradientLayer = _gradientLayer; + +#pragma mark - Public + +- (void)setContentViewController:(UIViewController*)contentViewController { + if (_contentViewController == contentViewController) + return; + + // Remove previous VC. + [_contentViewController willMoveToParentViewController:nil]; + [_contentViewController.view removeFromSuperview]; + [_contentViewController removeFromParentViewController]; + + _contentViewController = contentViewController; + + if (!contentViewController) + return; + + [self addChildViewController:contentViewController]; + + contentViewController.view.translatesAutoresizingMaskIntoConstraints = NO; + [self.view insertSubview:contentViewController.view + belowSubview:self.gradientView]; + AddSameConstraintsToSides( + self.view, contentViewController.view, + LayoutSides::kTop | LayoutSides::kLeading | LayoutSides::kTrailing); + [contentViewController.view.bottomAnchor + constraintEqualToAnchor:self.buttonContainer.topAnchor] + .active = YES; + + [contentViewController didMoveToParentViewController:self]; +} + +#pragma mark - Property + +- (UIButton*)primaryButton { + if (!_primaryButton) { + _primaryButton = [UIButton buttonWithType:UIButtonTypeSystem]; + _primaryButton.translatesAutoresizingMaskIntoConstraints = NO; + [_primaryButton setTitle:@"Primary Button" forState:UIControlStateNormal]; + _primaryButton.backgroundColor = [UIColor blueColor]; + [_primaryButton setContentHuggingPriority:UILayoutPriorityDefaultHigh + forAxis:UILayoutConstraintAxisVertical]; + [_primaryButton addTarget:self + action:@selector(primaryButtonCallback) + forControlEvents:UIControlEventTouchUpInside]; + } + return _primaryButton; +} + +- (UIButton*)secondaryButton { + if (!_secondaryButton) { + _secondaryButton = [UIButton buttonWithType:UIButtonTypeSystem]; + _secondaryButton.translatesAutoresizingMaskIntoConstraints = NO; + [_secondaryButton setTitle:@"Secondary Button" + forState:UIControlStateNormal]; + [_secondaryButton setContentHuggingPriority:UILayoutPriorityDefaultHigh + forAxis:UILayoutConstraintAxisVertical]; + [_secondaryButton addTarget:self + action:@selector(secondaryButtonCallback) + forControlEvents:UIControlEventTouchUpInside]; + } + return _secondaryButton; +} + +- (UIView*)buttonContainer { + if (!_buttonContainer) { + _buttonContainer = [[UIView alloc] init]; + _buttonContainer.translatesAutoresizingMaskIntoConstraints = NO; + } + return _buttonContainer; +} + +- (UIView*)gradientView { + if (!_gradientView) { + _gradientView = [[UIView alloc] initWithFrame:CGRectZero]; + _gradientView.userInteractionEnabled = NO; + _gradientView.translatesAutoresizingMaskIntoConstraints = NO; + [_gradientView.layer insertSublayer:self.gradientLayer atIndex:0]; + } + return _gradientView; +} + +- (CAGradientLayer*)gradientLayer { + if (!_gradientLayer) { + _gradientLayer = [CAGradientLayer layer]; + _gradientLayer.colors = @[ + (id)[[UIColor colorWithWhite:1 alpha:0] CGColor], + (id)[self.view.backgroundColor CGColor] + ]; + } + return _gradientLayer; +} + +#pragma mark - UIViewController + +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + self.gradientLayer.frame = self.gradientView.bounds; +} + +- (void)viewDidLoad { + self.view.backgroundColor = [UIColor whiteColor]; + + // Add subviews. + [self.buttonContainer addSubview:self.primaryButton]; + [self.buttonContainer addSubview:self.secondaryButton]; + [self.view addSubview:self.buttonContainer]; + [self.view addSubview:self.gradientView]; + + // Constraints. + id<LayoutGuideProvider> safeArea = SafeAreaLayoutGuideForView(self.view); + AddSameConstraintsToSides(self.view, self.gradientView, + LayoutSides::kLeading | LayoutSides::kTrailing); + AddSameConstraintsToSides( + safeArea, self.buttonContainer, + LayoutSides::kBottom | LayoutSides::kLeading | LayoutSides::kTrailing); + AddSameConstraintsToSidesWithInsets( + self.secondaryButton, self.buttonContainer, + LayoutSides::kLeading | LayoutSides::kTop | LayoutSides::kBottom, + ChromeDirectionalEdgeInsetsMake(kMargin, kMargin, kMargin, 0)); + AddSameConstraintsToSidesWithInsets( + self.primaryButton, self.buttonContainer, + LayoutSides::kTrailing | LayoutSides::kTop | LayoutSides::kBottom, + ChromeDirectionalEdgeInsetsMake(kMargin, 0, kMargin, kMargin)); + [NSLayoutConstraint activateConstraints:@[ + [self.gradientView.heightAnchor constraintEqualToConstant:kGradientHeight], + [self.gradientView.bottomAnchor + constraintEqualToAnchor:self.buttonContainer.topAnchor], + [self.primaryButton.leadingAnchor + constraintGreaterThanOrEqualToAnchor:self.secondaryButton + .trailingAnchor], + ]]; +} + +#pragma mark - Private + +- (void)primaryButtonCallback { + [self.delegate consentBumpViewControllerDidTapPrimaryButton:self]; +} + +- (void)secondaryButtonCallback { + [self.delegate consentBumpViewControllerDidTapSecondaryButton:self]; +} + +@end
diff --git a/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller_delegate.h b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller_delegate.h new file mode 100644 index 0000000..8a35f48 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/consent_bump/consent_bump_view_controller_delegate.h
@@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_VIEW_CONTROLLER_DELEGATE_H_ + +#import <UIKit/UIKit.h> + +@class ConsentBumpViewController; + +// Protocol for the delegate of the ConsentBumpViewController. +@protocol ConsentBumpViewControllerDelegate<NSObject> + +// Notifies the delegate that the primary button of the view controller has been +// pressed. +- (void)consentBumpViewControllerDidTapPrimaryButton: + (ConsentBumpViewController*)consentBumpViewController; +// Notifies the delegate that the secondary button of the view controller has +// been pressed. +- (void)consentBumpViewControllerDidTapSecondaryButton: + (ConsentBumpViewController*)consentBumpViewController; + +@end + +#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.mm b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.mm index 85ada002..d1c976fe 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.mm +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui.mm
@@ -6,12 +6,14 @@ #import <EarlGrey/EarlGrey.h> +#include "base/mac/foundation_util.h" #include "components/unified_consent/feature.h" #include "ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.h" #import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h" #import "ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_cell.h" #import "ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.h" #import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.h" +#include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" @@ -21,6 +23,27 @@ #error "This file requires ARC support." #endif +namespace { + +// Returns a matcher to test whether the element is a scroll view with a content +// smaller than the scroll view bounds. +id<GREYMatcher> ContentViewSmallerThanScrollView() { + MatchesBlock matches = ^BOOL(UIView* view) { + UIScrollView* scrollView = base::mac::ObjCCast<UIScrollView>(view); + return scrollView && + scrollView.contentSize.height < scrollView.bounds.size.height; + }; + DescribeToBlock describe = ^void(id<GREYDescription> description) { + [description appendText: + @"Not a scroll view or the scroll view content is bigger " + @"than the scroll view bounds"]; + }; + return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches + descriptionBlock:describe]; +} + +} // namespace + using chrome_test_util::AccountConsistencyConfirmationOkButton; using chrome_test_util::AccountConsistencySetupSigninButton; using chrome_test_util::ButtonWithAccessibilityLabel; @@ -66,27 +89,42 @@ } + (void)confirmSigninConfirmationDialog { - // Confirm sign in. "More" button is shown on short devices (e.g. iPhone 5s, - // iPhone SE), so needs to scroll first to dismiss the "More" button before - // taping on "OK". - // Cannot directly scroll on |kSignInConfirmationCollectionViewId| because it - // is a MDC collection view, not a UICollectionView, so itself is not - // scrollable. - // Wait until the sync confirmation is displayed. - id<GREYMatcher> signinUICollectionViewMatcher = nil; + // To confirm the dialog, the scroll view content has to be scrolled to the + // bottom to transform "MORE" button into the validation button. + // EarlGrey fails to scroll to the bottom, using grey_scrollToContentEdge(), + // if the scroll view doesn't bounce and by default a scroll view doesn't + // bounce when the content fits into the scroll view (the scroll never ends). + // To test if the content fits into the scroll view, + // ContentViewSmallerThanScrollView() matcher is used on the signin scroll + // view. + // If the matcher fails, then the scroll view should be scrolled to the + // bottom. + // Once to the bottom, the consent can be confirmed. + id<GREYMatcher> confirmationScrollViewMatcher = nil; [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; if (base::FeatureList::IsEnabled(unified_consent::kUnifiedConsent)) { - signinUICollectionViewMatcher = + confirmationScrollViewMatcher = grey_accessibilityID(kUnifiedConsentScrollViewIdentifier); } else { - signinUICollectionViewMatcher = grey_allOf( + confirmationScrollViewMatcher = grey_allOf( grey_ancestor( grey_accessibilityID(kSigninConfirmationCollectionViewId)), grey_kindOfClass([UICollectionView class]), nil); } - [[EarlGrey selectElementWithMatcher:signinUICollectionViewMatcher] - performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)]; - + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:confirmationScrollViewMatcher] + assertWithMatcher:ContentViewSmallerThanScrollView() + error:&error]; + if (error) { + // If the consent is bigger than the scroll view, the primary button should + // be "MORE". + [[EarlGrey selectElementWithMatcher: + chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SCROLL_BUTTON)] + assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:confirmationScrollViewMatcher] + performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)]; + } [[EarlGrey selectElementWithMatcher:AccountConsistencyConfirmationOkButton()] performAction:grey_tap()]; }
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm index f261b31a..cf0c232 100644 --- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
@@ -171,7 +171,6 @@ self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; self.scrollView.translatesAutoresizingMaskIntoConstraints = NO; self.scrollView.accessibilityIdentifier = kUnifiedConsentScrollViewIdentifier; - self.scrollView.alwaysBounceVertical = YES; if (@available(iOS 11, *)) { // The observed behavior was buggy. When the view appears on the screen, // the scrollvie was not scrolled all the way to the top. Adjusting the
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 5faac3fd..faeb2ae 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -1753,6 +1753,15 @@ [self.primaryToolbarCoordinator.viewController.view setNeedsLayout]; [self.primaryToolbarCoordinator.viewController.view layoutIfNeeded]; } + + // Native content pages depend on |self.view|'s safeArea. If the BVC is + // presented underneath another view (such as the first time welcome view), + // the BVC has no safe area set during webController's layout initial, and + // won't automatically get another layout without forcing it here. + Tab* currentTab = [_model currentTab]; + if ([self isTabNativePage:currentTab]) { + [currentTab.webController.view setNeedsLayout]; + } } - (void)viewDidLayoutSubviews {
diff --git a/ios/chrome/browser/ui/settings/autofill_settings_egtest.mm b/ios/chrome/browser/ui/settings/autofill_settings_egtest.mm index f129259..99c2bb1 100644 --- a/ios/chrome/browser/ui/settings/autofill_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/autofill_settings_egtest.mm
@@ -127,9 +127,6 @@ // Test that submitting a form ensures saving the data as an autofill profile. - (void)testAutofillProfileSaving { - // TODO(crbug.com/866730): Re-enable when fixed - EARL_GREY_TEST_DISABLED(@"Test broken."); - [self loadAndSubmitTheForm]; [self openEditAddress:@"George Washington, 1600 Pennsylvania Ave NW"]; @@ -150,9 +147,6 @@ // Test that editing country names is followed by validating the value and // replacing it with a canonical one. - (void)testAutofillProfileEditing { - // TODO(crbug.com/866730): Re-enable when fixed - EARL_GREY_TEST_DISABLED(@"Test broken."); - [self loadAndSubmitTheForm]; [self openEditAddress:@"George Washington, 1600 Pennsylvania Ave NW"]; @@ -187,9 +181,6 @@ // Test that the page for viewing autofill profile details is accessible. - (void)testAccessibilityOnAutofillProfileViewPage { - // TODO(crbug.com/866730): Re-enable when fixed - EARL_GREY_TEST_DISABLED(@"Test broken."); - [self loadAndSubmitTheForm]; [self openEditAddress:@"George Washington, 1600 Pennsylvania Ave NW"]; chrome_test_util::VerifyAccessibilityForCurrentScreen(); @@ -199,9 +190,6 @@ // Test that the page for editing autofill profile details is accessible. - (void)testAccessibilityOnAutofillProfileEditPage { - // TODO(crbug.com/866730): Re-enable when fixed - EARL_GREY_TEST_DISABLED(@"Test broken."); - [self loadAndSubmitTheForm]; [self openEditAddress:@"George Washington, 1600 Pennsylvania Ave NW"]; // Switch on edit mode. @@ -216,9 +204,6 @@ // Checks that if the autofill profiles and credit cards list view is in edit // mode, the "autofill" and "wallet" switch items are disabled. - (void)testListViewEditMode { - // TODO(crbug.com/866730): Re-enable when fixed - EARL_GREY_TEST_DISABLED(@"Test broken."); - [self loadAndSubmitTheForm]; [ChromeEarlGreyUI openSettingsMenu];
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm index 5e2c131..e8146e4 100644 --- a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm +++ b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
@@ -2085,7 +2085,8 @@ [NSObject cancelPreviousPerformRequestsWithTarget:self]; [_delegate tabSwitcher:self - shouldFinishWithActiveModel:_activeCardSet.tabModel]; + shouldFinishWithActiveModel:_activeCardSet.tabModel + focusOmnibox:NO]; [self animateTransitionWithStyle:STACK_TRANSITION_STYLE_DISMISSING]; } @@ -2200,7 +2201,8 @@ [_activeCardSet.tabModel setCurrentTab:tab]; [_delegate tabSwitcher:self - shouldFinishWithActiveModel:_activeCardSet.tabModel]; + shouldFinishWithActiveModel:_activeCardSet.tabModel + focusOmnibox:NO]; CGFloat statusBarHeight = StatusBarHeight(); CGRect viewBounds, remainder;
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm index 2409a3e..74382d8 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm
@@ -85,7 +85,9 @@ // Tell the delegate to display the tab. DCHECK(self.delegate); - [self.delegate tabSwitcher:self shouldFinishWithActiveModel:targetModel]; + [self.delegate tabSwitcher:self + shouldFinishWithActiveModel:targetModel + focusOmnibox:NO]; return tab; }
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm index 224674f..a8cf93c 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
@@ -338,7 +338,7 @@ #pragma mark - TabPresentationDelegate -- (void)showActiveTabInPage:(TabGridPage)page { +- (void)showActiveTabInPage:(TabGridPage)page focusOmnibox:(BOOL)focusOmnibox { DCHECK(self.regularTabModel && self.incognitoTabModel); TabModel* activeTabModel; switch (page) { @@ -357,7 +357,8 @@ // Trigger the transition through the TabSwitcher delegate. This will in turn // call back into this coordinator via the ViewControllerSwapping protocol. [self.tabSwitcher.delegate tabSwitcher:self.tabSwitcher - shouldFinishWithActiveModel:activeTabModel]; + shouldFinishWithActiveModel:activeTabModel + focusOmnibox:focusOmnibox]; } #pragma mark - BrowserCommands @@ -399,19 +400,22 @@ - (void)showActiveRegularTabFromRecentTabs { [self.tabSwitcher.delegate tabSwitcher:self.tabSwitcher - shouldFinishWithActiveModel:self.regularTabModel]; + shouldFinishWithActiveModel:self.regularTabModel + focusOmnibox:NO]; } #pragma mark - HistoryPresentationDelegate - (void)showActiveRegularTabFromHistory { [self.tabSwitcher.delegate tabSwitcher:self.tabSwitcher - shouldFinishWithActiveModel:self.regularTabModel]; + shouldFinishWithActiveModel:self.regularTabModel + focusOmnibox:NO]; } - (void)showActiveIncognitoTabFromHistory { [self.tabSwitcher.delegate tabSwitcher:self.tabSwitcher - shouldFinishWithActiveModel:self.incognitoTabModel]; + shouldFinishWithActiveModel:self.incognitoTabModel + focusOmnibox:NO]; } @end
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator_unittest.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator_unittest.mm index ace48fdb..845b86ef 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator_unittest.mm
@@ -23,7 +23,8 @@ @implementation TestTabSwitcherDelegate @synthesize didEndCalled = _didEndCalled; - (void)tabSwitcher:(id<TabSwitcher>)tabSwitcher - shouldFinishWithActiveModel:(TabModel*)tabModel { + shouldFinishWithActiveModel:(TabModel*)tabModel + focusOmnibox:(BOOL)focusOmnibox { // No-op. }
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.mm index 120b075d..1b2df4c 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.mm
@@ -20,7 +20,7 @@ // Structure of this control: // -// The page control is similar to a UISegmentedCoffee in appearance, but not in +// The page control is similar to a UISegmentedControl in appearance, but not in // function. This control doesn't have segments that highlight; instead there // is a white "slider" that moves across the view onto whichever segment is // active. Each segment has an image and (optionally) a label. When the slider @@ -302,13 +302,11 @@ CGPoint position = [touch locationInView:self]; CGFloat deltaX = position.x - self.dragStart.x; // Convert to position change. - CGFloat postionChange = deltaX / self.sliderRange; + CGFloat positionChange = deltaX / self.sliderRange; - self.sliderPosition = self.dragStartPosition + postionChange; + self.sliderPosition = self.dragStartPosition + positionChange; [self sendActionsForControlEvents:UIControlEventValueChanged]; - - // If the touch is now outside of the control, stop tracking it. - return self.touchInside; + return YES; } - (void)endTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event {
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h index d051c80..447ffe2 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h
@@ -20,8 +20,9 @@ // Delegate protocol for an object that can handle presenting ("opening") tabs // from the tab grid. @protocol TabPresentationDelegate<NSObject> -// Show the active tab in |page|, presented on top of the tab grid. -- (void)showActiveTabInPage:(TabGridPage)page; +// Show the active tab in |page|, presented on top of the tab grid. The +// omnibox will be focused after the animation if |focusOmnibox| is YES. +- (void)showActiveTabInPage:(TabGridPage)page focusOmnibox:(BOOL)focusOmnibox; @end // View controller representing a tab switcher. The tab switcher has an
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm index f9645b0a..78b612d 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
@@ -886,7 +886,7 @@ // Tells the appropriate delegate to create a new item, and then tells the // presentation delegate to show the new item. -- (void)openNewTabInPage:(TabGridPage)page { +- (void)openNewTabInPage:(TabGridPage)page focusOmnibox:(BOOL)focusOmnibox { switch (page) { case TabGridPageIncognitoTabs: [self.incognitoTabsDelegate addNewItem]; @@ -907,22 +907,23 @@ break; } self.activePage = page; - [self.tabPresentationDelegate showActiveTabInPage:page]; + [self.tabPresentationDelegate showActiveTabInPage:page + focusOmnibox:focusOmnibox]; } // Creates and shows a new regular tab. -- (void)openNewRegularTab { - [self openNewTabInPage:TabGridPageRegularTabs]; +- (void)openNewRegularTabForKeyboardCommand { + [self openNewTabInPage:TabGridPageRegularTabs focusOmnibox:YES]; } // Creates and shows a new incognito tab. -- (void)openNewIncognitoTab { - [self openNewTabInPage:TabGridPageIncognitoTabs]; +- (void)openNewIncognitoTabForKeyboardCommand { + [self openNewTabInPage:TabGridPageIncognitoTabs focusOmnibox:YES]; } // Creates and shows a new tab in the current page. -- (void)openNewTabInCurrentPage { - [self openNewTabInPage:self.currentPage]; +- (void)openNewTabInCurrentPageForKeyboardCommand { + [self openNewTabInPage:self.currentPage focusOmnibox:YES]; } // Broadcasts whether incognito tabs are showing. @@ -957,7 +958,8 @@ base::UserMetricsAction("MobileTabSwitcherOpenIncognitoTab")); } self.activePage = self.currentPage; - [self.tabPresentationDelegate showActiveTabInPage:self.currentPage]; + [self.tabPresentationDelegate showActiveTabInPage:self.currentPage + focusOmnibox:NO]; gridViewController.showsSelectionUpdates = YES; } @@ -1009,7 +1011,8 @@ // being triggered on release after tabs have been closed and the button // disabled. Ensure that action is only taken on a valid state. if (![[self gridViewControllerForPage:newActivePage] isGridEmpty]) { - [self.tabPresentationDelegate showActiveTabInPage:newActivePage]; + [self.tabPresentationDelegate showActiveTabInPage:newActivePage + focusOmnibox:NO]; // Record when users exit the tab grid to return to the current foreground // tab. // TODO(crbug.com/856965) : Rename metrics. @@ -1041,7 +1044,7 @@ } - (void)newTabButtonTapped:(id)sender { - [self openNewTabInCurrentPage]; + [self openNewTabInPage:self.currentPage focusOmnibox:NO]; // Record only when a new tab is created through the + button. // TODO(crbug.com/856965) : Rename metrics. base::RecordAction(base::UserMetricsAction("MobileToolbarStackViewNewTab")); @@ -1075,24 +1078,24 @@ #pragma mark - UIResponder - (NSArray*)keyCommands { - UIKeyCommand* newWindowShortcut = - [UIKeyCommand keyCommandWithInput:@"n" - modifierFlags:UIKeyModifierCommand - action:@selector(openNewRegularTab) - discoverabilityTitle:l10n_util::GetNSStringWithFixup( - IDS_IOS_TOOLS_MENU_NEW_TAB)]; + UIKeyCommand* newWindowShortcut = [UIKeyCommand + keyCommandWithInput:@"n" + modifierFlags:UIKeyModifierCommand + action:@selector(openNewRegularTabForKeyboardCommand) + discoverabilityTitle:l10n_util::GetNSStringWithFixup( + IDS_IOS_TOOLS_MENU_NEW_TAB)]; UIKeyCommand* newIncognitoWindowShortcut = [UIKeyCommand keyCommandWithInput:@"n" modifierFlags:UIKeyModifierCommand | UIKeyModifierShift - action:@selector(openNewIncognitoTab) + action:@selector(openNewIncognitoTabForKeyboardCommand) discoverabilityTitle:l10n_util::GetNSStringWithFixup( IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB)]; - UIKeyCommand* newTabShortcut = - [UIKeyCommand keyCommandWithInput:@"t" - modifierFlags:UIKeyModifierCommand - action:@selector(openNewTabInCurrentPage) - discoverabilityTitle:l10n_util::GetNSStringWithFixup( - IDS_IOS_TOOLS_MENU_NEW_TAB)]; + UIKeyCommand* newTabShortcut = [UIKeyCommand + keyCommandWithInput:@"t" + modifierFlags:UIKeyModifierCommand + action:@selector(openNewTabInCurrentPageForKeyboardCommand) + discoverabilityTitle:l10n_util::GetNSStringWithFixup( + IDS_IOS_TOOLS_MENU_NEW_TAB)]; return @[ newWindowShortcut, newIncognitoWindowShortcut, newTabShortcut ]; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher.h index 282bab0..8b1da3d 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher.h
@@ -28,7 +28,8 @@ // Informs the delegate the stack controller should be dismissed with the given // active model. - (void)tabSwitcher:(id<TabSwitcher>)tabSwitcher - shouldFinishWithActiveModel:(TabModel*)tabModel; + shouldFinishWithActiveModel:(TabModel*)tabModel + focusOmnibox:(BOOL)focusOmnibox; // Informs the delegate that the stack controller is done and should be // dismissed.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm index 1269ec2..bef8d3c 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm
@@ -872,7 +872,9 @@ DCHECK(model); [[self presentedViewController] dismissViewControllerAnimated:NO completion:nil]; - [self.delegate tabSwitcher:self shouldFinishWithActiveModel:model]; + [self.delegate tabSwitcher:self + shouldFinishWithActiveModel:model + focusOmnibox:NO]; [self performTabSwitcherTransition:TransitionType::TRANSITION_DISMISS withModel:model animated:animated
diff --git a/ios/chrome/browser/ui/webui/BUILD.gn b/ios/chrome/browser/ui/webui/BUILD.gn index ed080bd5..468737f 100644 --- a/ios/chrome/browser/ui/webui/BUILD.gn +++ b/ios/chrome/browser/ui/webui/BUILD.gn
@@ -20,8 +20,8 @@ "suggestions_ui.h", "terms_ui.h", "terms_ui.mm", - "url_keyed_metrics_ui.cc", - "url_keyed_metrics_ui.h", + "ukm_internals_ui.cc", + "ukm_internals_ui.h", "version_handler.cc", "version_handler.h", "version_ui.h", @@ -46,6 +46,7 @@ "//components/version_info", "//components/version_ui", "//google_apis", + "//ios/chrome/app/resources:ios_resources", "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm b/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm index 2b8b130..77fd1b9 100644 --- a/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm +++ b/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm
@@ -20,7 +20,7 @@ #include "ios/chrome/browser/ui/webui/suggestions_ui.h" #include "ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.h" #include "ios/chrome/browser/ui/webui/terms_ui.h" -#include "ios/chrome/browser/ui/webui/url_keyed_metrics_ui.h" +#include "ios/chrome/browser/ui/webui/ukm_internals_ui.h" #include "ios/chrome/browser/ui/webui/version_ui.h" #include "url/gurl.h" @@ -91,7 +91,7 @@ if (url_host == kChromeUIFlagsHost) return &NewWebUIIOS<FlagsUI>; if (url_host == kChromeUIURLKeyedMetricsHost) - return &NewWebUIIOSWithHost<URLKeyedMetricsUI>; + return &NewWebUIIOS<UkmInternalsUI>; return nullptr; }
diff --git a/ios/chrome/browser/ui/webui/ukm_internals_ui.cc b/ios/chrome/browser/ui/webui/ukm_internals_ui.cc new file mode 100644 index 0000000..477780b2 --- /dev/null +++ b/ios/chrome/browser/ui/webui/ukm_internals_ui.cc
@@ -0,0 +1,88 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/ui/webui/ukm_internals_ui.h" + +#include <string> + +#include "base/memory/ref_counted_memory.h" +#include "components/metrics_services_manager/metrics_services_manager.h" +#include "components/ukm/debug/ukm_debug_data_extractor.h" +#include "components/ukm/ukm_service.h" +#include "ios/chrome/browser/application_context.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/chrome_url_constants.h" +#include "ios/chrome/grit/ios_resources.h" +#include "ios/web/public/url_data_source_ios.h" +#include "ios/web/public/web_ui_ios_data_source.h" +#include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_message_handler.h" + +namespace { + +web::WebUIIOSDataSource* CreateUkmInternalsUIHTMLSource() { + web::WebUIIOSDataSource* source = + web::WebUIIOSDataSource::Create(kChromeUIURLKeyedMetricsHost); + + source->AddResourcePath("ukm_internals.js", IDR_IOS_UKM_INTERNALS_JS); + source->SetDefaultResource(IDR_IOS_UKM_INTERNALS_HTML); + source->UseGzip(); + return source; +} + +// The handler for Javascript messages for the chrome://ukm/ page. +class UkmMessageHandler : public web::WebUIIOSMessageHandler { + public: + explicit UkmMessageHandler(const ukm::UkmService* ukm_service); + ~UkmMessageHandler() override; + + // web::WebUIIOSMessageHandler implementation. + void RegisterMessages() override; + + private: + void HandleRequestUkmData(const base::ListValue* args); + + const ukm::UkmService* ukm_service_; + + DISALLOW_COPY_AND_ASSIGN(UkmMessageHandler); +}; + +UkmMessageHandler::UkmMessageHandler(const ukm::UkmService* ukm_service) + : ukm_service_(ukm_service) {} + +UkmMessageHandler::~UkmMessageHandler() {} + +void UkmMessageHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "requestUkmData", + base::BindRepeating(&UkmMessageHandler::HandleRequestUkmData, + base::Unretained(this))); +} + +void UkmMessageHandler::HandleRequestUkmData(const base::ListValue* args) { + base::Value ukm_debug_data = + ukm::debug::UkmDebugDataExtractor::GetStructuredData(ukm_service_); + + std::string callback_id; + args->GetString(0, &callback_id); + web_ui()->ResolveJavascriptCallback(base::Value(callback_id), + std::move(ukm_debug_data)); +} + +} // namespace + +// Changes to this class should be in sync with its non-iOS equivalent +// chrome/browser/ui/webui/ukm/ukm_internals_ui.cc +UkmInternalsUI::UkmInternalsUI(web::WebUIIOS* web_ui) + : web::WebUIIOSController(web_ui) { + ukm::UkmService* ukm_service = + GetApplicationContext()->GetMetricsServicesManager()->GetUkmService(); + web_ui->AddMessageHandler(std::make_unique<UkmMessageHandler>(ukm_service)); + + // Set up the chrome://ukm/ source. + web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui), + CreateUkmInternalsUIHTMLSource()); +} + +UkmInternalsUI::~UkmInternalsUI() {}
diff --git a/ios/chrome/browser/ui/webui/ukm_internals_ui.h b/ios/chrome/browser/ui/webui/ukm_internals_ui.h new file mode 100644 index 0000000..73e583d --- /dev/null +++ b/ios/chrome/browser/ui/webui/ukm_internals_ui.h
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_WEBUI_UKM_INTERNALS_UI_H_ +#define IOS_CHROME_BROWSER_UI_WEBUI_UKM_INTERNALS_UI_H_ + +#include "base/macros.h" +#include "ios/web/public/webui/web_ui_ios_controller.h" + +namespace web { +class WebUIIOS; +} + +// The WebUI controller for chrome://ukm. +class UkmInternalsUI : public web::WebUIIOSController { + public: + explicit UkmInternalsUI(web::WebUIIOS* web_ui); + ~UkmInternalsUI() override; + + private: + DISALLOW_COPY_AND_ASSIGN(UkmInternalsUI); +}; + +#endif // IOS_CHROME_BROWSER_UI_WEBUI_UKM_INTERNALS_UI_H_
diff --git a/ios/chrome/browser/ui/webui/url_keyed_metrics_ui.cc b/ios/chrome/browser/ui/webui/url_keyed_metrics_ui.cc deleted file mode 100644 index d9851e6..0000000 --- a/ios/chrome/browser/ui/webui/url_keyed_metrics_ui.cc +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/webui/url_keyed_metrics_ui.h" - -#include <string> - -#include "base/memory/ref_counted_memory.h" -#include "components/metrics_services_manager/metrics_services_manager.h" -#include "components/ukm/debug/ukm_debug_data_extractor.h" -#include "components/ukm/ukm_service.h" -#include "ios/chrome/browser/application_context.h" -#include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/web/public/url_data_source_ios.h" - -namespace { - -class URLKeyedMetricsUIHTMLSource : public web::URLDataSourceIOS { - public: - // Construct a data source for the specified |source_name|. - explicit URLKeyedMetricsUIHTMLSource(const std::string& source_name); - - // web::URLDataSourceIOS implementation. - std::string GetSource() const override; - void StartDataRequest( - const std::string& path, - const web::URLDataSourceIOS::GotDataCallback& callback) override; - std::string GetMimeType(const std::string& path) const override; - bool ShouldDenyXFrameOptions() const override; - - private: - ~URLKeyedMetricsUIHTMLSource() override; - - ukm::UkmService* GetUkmService(); - std::string source_name_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(URLKeyedMetricsUIHTMLSource); -}; - -} // namespace - -// URLKeyedMetricsUIHTMLSource ------------------------------------------------- - -URLKeyedMetricsUIHTMLSource::URLKeyedMetricsUIHTMLSource( - const std::string& source_name) - : source_name_(source_name) {} - -URLKeyedMetricsUIHTMLSource::~URLKeyedMetricsUIHTMLSource() {} - -std::string URLKeyedMetricsUIHTMLSource::GetSource() const { - return source_name_; -} - -void URLKeyedMetricsUIHTMLSource::StartDataRequest( - const std::string& path, - const web::URLDataSourceIOS::GotDataCallback& callback) { - // TODO(crbug.com/843181): Use GetStructuredData() instead. - std::string data = - ukm::debug::UkmDebugDataExtractor::GetHTMLData(GetUkmService()); - callback.Run(base::RefCountedString::TakeString(&data)); -} - -std::string URLKeyedMetricsUIHTMLSource::GetMimeType( - const std::string& path) const { - return "text/html"; -} - -bool URLKeyedMetricsUIHTMLSource::ShouldDenyXFrameOptions() const { - return web::URLDataSourceIOS::ShouldDenyXFrameOptions(); -} - -ukm::UkmService* URLKeyedMetricsUIHTMLSource::GetUkmService() { - return GetApplicationContext()->GetMetricsServicesManager()->GetUkmService(); -} - -// URLKeyedMetricsUI ----------------------------------------------------------- - -URLKeyedMetricsUI::URLKeyedMetricsUI(web::WebUIIOS* web_ui, - const std::string& name) - : web::WebUIIOSController(web_ui) { - web::URLDataSourceIOS::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui), - new URLKeyedMetricsUIHTMLSource(name)); -} - -URLKeyedMetricsUI::~URLKeyedMetricsUI() {}
diff --git a/ios/chrome/browser/ui/webui/url_keyed_metrics_ui.h b/ios/chrome/browser/ui/webui/url_keyed_metrics_ui.h deleted file mode 100644 index 90a65d9..0000000 --- a/ios/chrome/browser/ui/webui/url_keyed_metrics_ui.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_WEBUI_URL_KEYED_METRICS_UI_H_ -#define IOS_CHROME_BROWSER_UI_WEBUI_URL_KEYED_METRICS_UI_H_ - -#include "base/macros.h" -#include "ios/web/public/webui/web_ui_ios_controller.h" - -namespace web { -class WebUIIOS; -} - -// The WebUI controller for chrome://ukm. -class URLKeyedMetricsUI : public web::WebUIIOSController { - public: - URLKeyedMetricsUI(web::WebUIIOS* web_ui, const std::string& name); - ~URLKeyedMetricsUI() override; - - private: - DISALLOW_COPY_AND_ASSIGN(URLKeyedMetricsUI); -}; - -#endif // IOS_CHROME_BROWSER_UI_WEBUI_URL_KEYED_METRICS_UI_H_
diff --git a/ios/web/public/webui/web_ui_ios.h b/ios/web/public/webui/web_ui_ios.h index cc97807..feaf67b 100644 --- a/ios/web/public/webui/web_ui_ios.h +++ b/ios/web/public/webui/web_ui_ios.h
@@ -81,6 +81,18 @@ virtual void CallJavascriptFunction( const std::string& function_name, const std::vector<const base::Value*>& args) = 0; + + // Helper method for responding to Javascript requests initiated with + // cr.sendWithPromise() (defined in cr.js) for the case where the returned + // promise should be resolved (request succeeded). + virtual void ResolveJavascriptCallback(const base::Value& callback_id, + const base::Value& response) = 0; + + // Helper method for responding to Javascript requests initiated with + // cr.sendWithPromise() (defined in cr.js), for the case where the returned + // promise should be rejected (request failed). + virtual void RejectJavascriptCallback(const base::Value& callback_id, + const base::Value& response) = 0; }; } // namespace web
diff --git a/ios/web/web_state/navigation_context_impl.h b/ios/web/web_state/navigation_context_impl.h index 0af55de..76e1034 100644 --- a/ios/web/web_state/navigation_context_impl.h +++ b/ios/web/web_state/navigation_context_impl.h
@@ -73,6 +73,11 @@ bool IsLoadingErrorPage() const; void SetLoadingErrorPage(bool is_loading_error_page); + // true if this navigation context is a placeholder navigation associated with + // a native view URL and the native content is already presented. + bool IsNativeContentPresented() const; + void SetIsNativeContentPresented(bool is_native_content_presented); + private: NavigationContextImpl(WebState* web_state, const GURL& url, @@ -95,6 +100,7 @@ int navigation_item_unique_id_ = -1; WKNavigationType wk_navigation_type_ = WKNavigationTypeOther; bool is_loading_error_page_ = false; + bool is_native_content_presented_ = false; DISALLOW_COPY_AND_ASSIGN(NavigationContextImpl); };
diff --git a/ios/web/web_state/navigation_context_impl.mm b/ios/web/web_state/navigation_context_impl.mm index f7c20a17..322929a 100644 --- a/ios/web/web_state/navigation_context_impl.mm +++ b/ios/web/web_state/navigation_context_impl.mm
@@ -158,6 +158,15 @@ is_loading_error_page_ = is_loading_error_page; } +bool NavigationContextImpl::IsNativeContentPresented() const { + return is_native_content_presented_; +} + +void NavigationContextImpl::SetIsNativeContentPresented( + bool is_native_content_presented) { + is_native_content_presented_ = is_native_content_presented; +} + NavigationContextImpl::NavigationContextImpl(WebState* web_state, const GURL& url, bool has_user_gesture,
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index a4c59f1..4e48ec8 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -568,14 +568,13 @@ - (void)updateCurrentBackForwardListItemHolder; // Presents native content using the native controller for |item| without -// notifying WebStateObservers. This is used when loading native view for a new -// navigation to avoid the delay introduced by placeholder navigation. +// notifying WebStateObservers. This method does not modify the underlying web +// view. It simply covers the web view with the native content. +// |-didLoadNativeContentForNavigationItem| must be called some time later +// to notify WebStateObservers. - (void)presentNativeContentForNavigationItem:(web::NavigationItem*)item; -// Presents native content using the native controller for |item| and notifies -// WebStateObservers the completion of this navigation. This method does not -// modify the underlying web view. It simply covers the web view with the native -// content. -- (void)loadNativeContentForNavigationItem:(web::NavigationItem*)item; +// Notifies WebStateObservers the completion of this navigation. +- (void)didLoadNativeContentForNavigationItem:(web::NavigationItem*)item; // Loads a blank page directly into WKWebView as a placeholder for a Native View // or WebUI URL. This page has the URL about:blank?for=<encoded original URL>. // The completion handler is called in the |webView:didFinishNavigation| @@ -1799,12 +1798,15 @@ if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { // Free the web view. [self removeWebView]; - [self loadNativeContentForNavigationItem:self.currentNavItem]; + [self presentNativeContentForNavigationItem:self.currentNavItem]; + [self didLoadNativeContentForNavigationItem:self.currentNavItem]; } else { // Just present the native view now. Leave the rest of native content load // until the placeholder navigation finishes. [self presentNativeContentForNavigationItem:self.currentNavItem]; - [self loadPlaceholderInWebViewForURL:self.currentNavItem->GetVirtualURL()]; + web::NavigationContextImpl* context = [self + loadPlaceholderInWebViewForURL:self.currentNavItem->GetVirtualURL()]; + context->SetIsNativeContentPresented(true); } } @@ -1826,9 +1828,7 @@ } } -- (void)loadNativeContentForNavigationItem:(web::NavigationItem*)item { - [self presentNativeContentForNavigationItem:item]; - +- (void)didLoadNativeContentForNavigationItem:(web::NavigationItem*)item { const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); const web::Referrer referrer; std::unique_ptr<web::NavigationContextImpl> navigationContext = @@ -1915,8 +1915,9 @@ if (!_containerView) return; - // WKBasedNavigationManagerImpl requires web usage to be enabled to load any - // URL. So bail if web usage is disabled, and let the URL be loaded when web + // WKBasedNavigationManagerImpl needs WKWebView to load native views, but + // WKWebView cannot be created while web usage is disabled to avoid breaking + // clearing browser data. Bail now and let the URL be loaded when web // usage is enabled again. This can happen when purging web pages when an // interstitial is presented over a native view. See https://crbug.com/865985 // for details. @@ -4900,7 +4901,12 @@ } if ([self shouldLoadURLInNativeView:item->GetURL()]) { - [self loadNativeContentForNavigationItem:item]; + // Native content may have already been presented if this navigation is + // started in |-loadCurrentURLInNativeView|. If not, present it now. + if (!context || !context->IsNativeContentPresented()) { + [self presentNativeContentForNavigationItem:item]; + } + [self didLoadNativeContentForNavigationItem:item]; } else if (isWebUIURL) { DCHECK(_webUIManager); [_webUIManager loadWebUIForURL:item->GetURL()];
diff --git a/ios/web/webui/web_ui_ios_impl.h b/ios/web/webui/web_ui_ios_impl.h index 5a8e27fc..a431a4f 100644 --- a/ios/web/webui/web_ui_ios_impl.h +++ b/ios/web/webui/web_ui_ios_impl.h
@@ -56,6 +56,10 @@ void CallJavascriptFunction( const std::string& function_name, const std::vector<const base::Value*>& args) override; + void ResolveJavascriptCallback(const base::Value& callback_id, + const base::Value& response) override; + void RejectJavascriptCallback(const base::Value& callback_id, + const base::Value& response) override; private: // Executes JavaScript asynchronously on the page.
diff --git a/ios/web/webui/web_ui_ios_impl.mm b/ios/web/webui/web_ui_ios_impl.mm index 3345d08..3056181 100644 --- a/ios/web/webui/web_ui_ios_impl.mm +++ b/ios/web/webui/web_ui_ios_impl.mm
@@ -121,6 +121,20 @@ ExecuteJavascript(GetJavascriptCall(function_name, args)); } +void WebUIIOSImpl::ResolveJavascriptCallback(const base::Value& callback_id, + const base::Value& response) { + // cr.webUIResponse is a global JS function exposed from cr.js. + CallJavascriptFunction("cr.webUIResponse", callback_id, base::Value(true), + response); +} + +void WebUIIOSImpl::RejectJavascriptCallback(const base::Value& callback_id, + const base::Value& response) { + // cr.webUIResponse is a global JS function exposed from cr.js. + CallJavascriptFunction("cr.webUIResponse", callback_id, base::Value(false), + response); +} + void WebUIIOSImpl::RegisterMessageCallback(const std::string& message, const MessageCallback& callback) { message_callbacks_.insert(std::make_pair(message, callback));
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java index 45f1fc7..54612093 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java
@@ -158,7 +158,11 @@ private void onError(MojoException exception) { close(); if (mErrorHandler != null) { - mErrorHandler.onConnectionError(exception); + try { + mErrorHandler.onConnectionError(exception); + } catch (RuntimeException e) { + ExceptionHandler.DefaultExceptionHandler.getInstance().handleException(e); + } } }
diff --git a/net/BUILD.gn b/net/BUILD.gn index 380809e6..9c8dee6 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1351,6 +1351,24 @@ "third_party/quic/core/frames/quic_stream_id_blocked_frame.h", "third_party/quic/core/frames/quic_window_update_frame.cc", "third_party/quic/core/frames/quic_window_update_frame.h", + "third_party/quic/core/http/quic_client_promised_info.cc", + "third_party/quic/core/http/quic_client_promised_info.h", + "third_party/quic/core/http/quic_client_push_promise_index.cc", + "third_party/quic/core/http/quic_client_push_promise_index.h", + "third_party/quic/core/http/quic_header_list.cc", + "third_party/quic/core/http/quic_header_list.h", + "third_party/quic/core/http/quic_headers_stream.cc", + "third_party/quic/core/http/quic_headers_stream.h", + "third_party/quic/core/http/quic_server_session_base.cc", + "third_party/quic/core/http/quic_server_session_base.h", + "third_party/quic/core/http/quic_spdy_client_session_base.cc", + "third_party/quic/core/http/quic_spdy_client_session_base.h", + "third_party/quic/core/http/quic_spdy_session.cc", + "third_party/quic/core/http/quic_spdy_session.h", + "third_party/quic/core/http/quic_spdy_stream.cc", + "third_party/quic/core/http/quic_spdy_stream.h", + "third_party/quic/core/http/spdy_utils.cc", + "third_party/quic/core/http/spdy_utils.h", "third_party/quic/core/packet_number_indexed_queue.h", "third_party/quic/core/quic_ack_listener_interface.cc", "third_party/quic/core/quic_ack_listener_interface.h", @@ -1365,10 +1383,6 @@ "third_party/quic/core/quic_buffer_allocator.h", "third_party/quic/core/quic_buffered_packet_store.cc", "third_party/quic/core/quic_buffered_packet_store.h", - "third_party/quic/core/quic_client_promised_info.cc", - "third_party/quic/core/quic_client_promised_info.h", - "third_party/quic/core/quic_client_push_promise_index.cc", - "third_party/quic/core/quic_client_push_promise_index.h", "third_party/quic/core/quic_config.cc", "third_party/quic/core/quic_config.h", "third_party/quic/core/quic_connection.cc", @@ -1401,10 +1415,6 @@ "third_party/quic/core/quic_flow_controller.h", "third_party/quic/core/quic_framer.cc", "third_party/quic/core/quic_framer.h", - "third_party/quic/core/quic_header_list.cc", - "third_party/quic/core/quic_header_list.h", - "third_party/quic/core/quic_headers_stream.cc", - "third_party/quic/core/quic_headers_stream.h", "third_party/quic/core/quic_one_block_arena.h", "third_party/quic/core/quic_packet_creator.cc", "third_party/quic/core/quic_packet_creator.h", @@ -1420,20 +1430,12 @@ "third_party/quic/core/quic_sent_packet_manager.h", "third_party/quic/core/quic_server_id.cc", "third_party/quic/core/quic_server_id.h", - "third_party/quic/core/quic_server_session_base.cc", - "third_party/quic/core/quic_server_session_base.h", "third_party/quic/core/quic_session.cc", "third_party/quic/core/quic_session.h", "third_party/quic/core/quic_simple_buffer_allocator.cc", "third_party/quic/core/quic_simple_buffer_allocator.h", "third_party/quic/core/quic_socket_address_coder.cc", "third_party/quic/core/quic_socket_address_coder.h", - "third_party/quic/core/quic_spdy_client_session_base.cc", - "third_party/quic/core/quic_spdy_client_session_base.h", - "third_party/quic/core/quic_spdy_session.cc", - "third_party/quic/core/quic_spdy_session.h", - "third_party/quic/core/quic_spdy_stream.cc", - "third_party/quic/core/quic_spdy_stream.h", "third_party/quic/core/quic_stream.cc", "third_party/quic/core/quic_stream.h", "third_party/quic/core/quic_stream_frame_data_producer.h", @@ -1463,8 +1465,6 @@ "third_party/quic/core/quic_versions.h", "third_party/quic/core/quic_write_blocked_list.cc", "third_party/quic/core/quic_write_blocked_list.h", - "third_party/quic/core/spdy_utils.cc", - "third_party/quic/core/spdy_utils.h", "third_party/quic/core/tls_client_handshaker.cc", "third_party/quic/core/tls_client_handshaker.h", "third_party/quic/core/tls_handshaker.cc", @@ -3105,8 +3105,6 @@ "third_party/quic/test_tools/quic_session_peer.h", "third_party/quic/test_tools/quic_spdy_session_peer.cc", "third_party/quic/test_tools/quic_spdy_session_peer.h", - "third_party/quic/test_tools/quic_spdy_stream_peer.cc", - "third_party/quic/test_tools/quic_spdy_stream_peer.h", "third_party/quic/test_tools/quic_stream_peer.cc", "third_party/quic/test_tools/quic_stream_peer.h", "third_party/quic/test_tools/quic_stream_send_buffer_peer.cc", @@ -3197,17 +3195,17 @@ sources = [ "third_party/quic/core/chlo_extractor.cc", "third_party/quic/core/chlo_extractor.h", + "third_party/quic/core/http/quic_spdy_client_session.cc", + "third_party/quic/core/http/quic_spdy_client_session.h", + "third_party/quic/core/http/quic_spdy_client_stream.cc", + "third_party/quic/core/http/quic_spdy_client_stream.h", + "third_party/quic/core/http/quic_spdy_server_stream_base.cc", + "third_party/quic/core/http/quic_spdy_server_stream_base.h", "third_party/quic/core/quic_dispatcher.cc", "third_party/quic/core/quic_dispatcher.h", "third_party/quic/core/quic_packet_writer_wrapper.cc", "third_party/quic/core/quic_packet_writer_wrapper.h", "third_party/quic/core/quic_process_packet_interface.h", - "third_party/quic/core/quic_spdy_client_session.cc", - "third_party/quic/core/quic_spdy_client_session.h", - "third_party/quic/core/quic_spdy_client_stream.cc", - "third_party/quic/core/quic_spdy_client_stream.h", - "third_party/quic/core/quic_spdy_server_stream_base.cc", - "third_party/quic/core/quic_spdy_server_stream_base.h", "third_party/quic/core/quic_time_wait_list_manager.cc", "third_party/quic/core/quic_time_wait_list_manager.h", "third_party/quic/core/stateless_rejector.cc", @@ -4975,13 +4973,15 @@ "third_party/quic/core/crypto/quic_tls_adapter_test.cc", "third_party/quic/core/crypto/transport_parameters_test.cc", "third_party/quic/core/frames/quic_frames_test.cc", + "third_party/quic/core/http/quic_client_promised_info_test.cc", + "third_party/quic/core/http/quic_client_push_promise_index_test.cc", + "third_party/quic/core/http/quic_header_list_test.cc", + "third_party/quic/core/http/quic_headers_stream_test.cc", "third_party/quic/core/packet_number_indexed_queue_test.cc", "third_party/quic/core/quic_alarm_test.cc", "third_party/quic/core/quic_arena_scoped_ptr_test.cc", "third_party/quic/core/quic_bandwidth_test.cc", "third_party/quic/core/quic_buffered_packet_store_test.cc", - "third_party/quic/core/quic_client_promised_info_test.cc", - "third_party/quic/core/quic_client_push_promise_index_test.cc", "third_party/quic/core/quic_config_test.cc", "third_party/quic/core/quic_connection_test.cc", "third_party/quic/core/quic_control_frame_manager_test.cc", @@ -4992,8 +4992,6 @@ "third_party/quic/core/quic_error_codes_test.cc", "third_party/quic/core/quic_flow_controller_test.cc", "third_party/quic/core/quic_framer_test.cc", - "third_party/quic/core/quic_header_list_test.cc", - "third_party/quic/core/quic_headers_stream_test.cc", "third_party/quic/core/quic_ietf_framer_test.cc", "third_party/quic/core/tls_handshaker_test.cc", @@ -5065,6 +5063,10 @@ "test/run_all_unittests.cc", "test/tcp_socket_proxy_unittest.cc", "third_party/nist-pkits/pkits_testcases-inl.h", + "third_party/quic/core/http/quic_server_session_base_test.cc", + "third_party/quic/core/http/quic_spdy_session_test.cc", + "third_party/quic/core/http/quic_spdy_stream_test.cc", + "third_party/quic/core/http/spdy_utils_test.cc", "third_party/quic/core/quic_dispatcher_test.cc", "third_party/quic/core/quic_one_block_arena_test.cc", "third_party/quic/core/quic_packet_creator_test.cc", @@ -5072,12 +5074,9 @@ "third_party/quic/core/quic_received_packet_manager_test.cc", "third_party/quic/core/quic_sent_packet_manager_test.cc", "third_party/quic/core/quic_server_id_test.cc", - "third_party/quic/core/quic_server_session_base_test.cc", "third_party/quic/core/quic_session_test.cc", "third_party/quic/core/quic_simple_buffer_allocator_test.cc", "third_party/quic/core/quic_socket_address_coder_test.cc", - "third_party/quic/core/quic_spdy_session_test.cc", - "third_party/quic/core/quic_spdy_stream_test.cc", "third_party/quic/core/quic_stream_send_buffer_test.cc", "third_party/quic/core/quic_stream_sequencer_buffer_test.cc", "third_party/quic/core/quic_stream_sequencer_test.cc", @@ -5092,7 +5091,6 @@ "third_party/quic/core/quic_version_manager_test.cc", "third_party/quic/core/quic_versions_test.cc", "third_party/quic/core/quic_write_blocked_list_test.cc", - "third_party/quic/core/spdy_utils_test.cc", "third_party/quic/platform/api/quic_endian_test.cc", "third_party/quic/platform/api/quic_hostname_utils_test.cc", "third_party/quic/platform/api/quic_lru_cache_test.cc", @@ -5271,12 +5269,12 @@ if (is_linux) { sources += [ "third_party/quic/core/chlo_extractor_test.cc", - "third_party/quic/core/end_to_end_test.cc", + "third_party/quic/core/http/end_to_end_test.cc", + "third_party/quic/core/http/quic_spdy_client_session_test.cc", + "third_party/quic/core/http/quic_spdy_client_stream_test.cc", + "third_party/quic/core/http/quic_spdy_server_stream_base_test.cc", "third_party/quic/core/quic_epoll_alarm_factory_test.cc", "third_party/quic/core/quic_epoll_connection_helper_test.cc", - "third_party/quic/core/quic_spdy_client_session_test.cc", - "third_party/quic/core/quic_spdy_client_stream_test.cc", - "third_party/quic/core/quic_spdy_server_stream_base_test.cc", "third_party/quic/core/stateless_rejector_test.cc", "third_party/quic/platform/impl/quic_epoll_clock_test.cc", "third_party/quic/platform/impl/quic_socket_utils_test.cc",
diff --git a/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc b/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc index d943b472..4a3475a 100644 --- a/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc +++ b/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
@@ -38,8 +38,8 @@ #include "net/third_party/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quic/core/crypto/quic_encrypter.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_connection.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/quic/platform/api/quic_text_utils.h"
diff --git a/net/quic/chromium/quic_chromium_client_session.cc b/net/quic/chromium/quic_chromium_client_session.cc index 1cc80d6..7de78f8 100644 --- a/net/quic/chromium/quic_chromium_client_session.cc +++ b/net/quic/chromium/quic_chromium_client_session.cc
@@ -39,8 +39,8 @@ #include "net/ssl/ssl_connection_status_flags.h" #include "net/ssl/ssl_info.h" #include "net/ssl/token_binding.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "third_party/boringssl/src/include/openssl/ssl.h"
diff --git a/net/quic/chromium/quic_chromium_client_session.h b/net/quic/chromium/quic_chromium_client_session.h index ecae249..43af292 100644 --- a/net/quic/chromium/quic_chromium_client_session.h +++ b/net/quic/chromium/quic_chromium_client_session.h
@@ -38,11 +38,11 @@ #include "net/spdy/http2_priority_dependencies.h" #include "net/spdy/multiplexed_session.h" #include "net/spdy/server_push_delegate.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" #include "net/third_party/quic/core/quic_crypto_client_stream.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" #include "net/third_party/quic/core/quic_time.h" #include "net/traffic_annotation/network_traffic_annotation.h"
diff --git a/net/quic/chromium/quic_chromium_client_session_test.cc b/net/quic/chromium/quic_chromium_client_session_test.cc index f6d2b78..68d0b3c 100644 --- a/net/quic/chromium/quic_chromium_client_session_test.cc +++ b/net/quic/chromium/quic_chromium_client_session_test.cc
@@ -39,7 +39,7 @@ #include "net/third_party/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quic/core/crypto/quic_encrypter.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" #include "net/third_party/quic/core/quic_packet_writer.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_flags.h"
diff --git a/net/quic/chromium/quic_chromium_client_stream.cc b/net/quic/chromium/quic_chromium_client_stream.cc index 8a7e629..fae140f 100644 --- a/net/quic/chromium/quic_chromium_client_stream.cc +++ b/net/quic/chromium/quic_chromium_client_stream.cc
@@ -16,9 +16,9 @@ #include "net/quic/chromium/quic_chromium_client_session.h" #include "net/quic/chromium/quic_http_utils.h" #include "net/spdy/spdy_log_util.h" -#include "net/third_party/quic/core/quic_spdy_session.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_write_blocked_list.h" -#include "net/third_party/quic/core/spdy_utils.h" namespace net { namespace {
diff --git a/net/quic/chromium/quic_chromium_client_stream.h b/net/quic/chromium/quic_chromium_client_stream.h index 75ce4f9..dea459f1 100644 --- a/net/quic/chromium/quic_chromium_client_stream.h +++ b/net/quic/chromium/quic_chromium_client_stream.h
@@ -22,7 +22,7 @@ #include "net/http/http_response_info.h" #include "net/http/http_stream.h" #include "net/log/net_log_with_source.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/traffic_annotation/network_traffic_annotation.h"
diff --git a/net/quic/chromium/quic_chromium_client_stream_test.cc b/net/quic/chromium/quic_chromium_client_stream_test.cc index 39a97df..39de871 100644 --- a/net/quic/chromium/quic_chromium_client_stream_test.cc +++ b/net/quic/chromium/quic_chromium_client_stream_test.cc
@@ -15,10 +15,10 @@ #include "net/quic/chromium/quic_chromium_client_session.h" #include "net/test/gtest_util.h" #include "net/test/test_with_scoped_task_environment.h" -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_utils.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quic/test_tools/crypto_test_utils.h"
diff --git a/net/quic/chromium/quic_connection_logger.h b/net/quic/chromium/quic_connection_logger.h index 9716677..2763935 100644 --- a/net/quic/chromium/quic_connection_logger.h +++ b/net/quic/chromium/quic_connection_logger.h
@@ -18,9 +18,9 @@ #include "net/log/net_log_with_source.h" #include "net/socket/socket_performance_watcher.h" #include "net/third_party/quic/core/crypto/crypto_handshake_message.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_packets.h" -#include "net/third_party/quic/core/quic_spdy_session.h" namespace base { class HistogramBase;
diff --git a/net/quic/chromium/quic_http_stream.cc b/net/quic/chromium/quic_http_stream.cc index d097326..69aef5b 100644 --- a/net/quic/chromium/quic_http_stream.cc +++ b/net/quic/chromium/quic_http_stream.cc
@@ -21,10 +21,10 @@ #include "net/quic/chromium/quic_http_utils.h" #include "net/spdy/spdy_http_utils.h" #include "net/ssl/ssl_info.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_stream_sequencer.h" #include "net/third_party/quic/core/quic_utils.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/spdy/core/spdy_frame_builder.h" #include "net/third_party/spdy/core/spdy_framer.h"
diff --git a/net/quic/chromium/quic_http_stream.h b/net/quic/chromium/quic_http_stream.h index 38c805c6..44be6562 100644 --- a/net/quic/chromium/quic_http_stream.h +++ b/net/quic/chromium/quic_http_stream.h
@@ -24,7 +24,7 @@ #include "net/quic/chromium/quic_chromium_client_session.h" #include "net/quic/chromium/quic_chromium_client_stream.h" #include "net/spdy/multiplexed_http_stream.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" #include "net/third_party/quic/core/quic_packets.h" namespace net {
diff --git a/net/quic/chromium/quic_http_stream_test.cc b/net/quic/chromium/quic_http_stream_test.cc index 2eea213..94686e0 100644 --- a/net/quic/chromium/quic_http_stream_test.cc +++ b/net/quic/chromium/quic_http_stream_test.cc
@@ -48,9 +48,9 @@ #include "net/third_party/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quic/core/crypto/quic_encrypter.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_write_blocked_list.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/quic/test_tools/crypto_test_utils.h"
diff --git a/net/quic/chromium/quic_stream_factory.cc b/net/quic/chromium/quic_stream_factory.cc index 74af500..56929b42 100644 --- a/net/quic/chromium/quic_stream_factory.cc +++ b/net/quic/chromium/quic_stream_factory.cc
@@ -53,7 +53,7 @@ #include "net/ssl/token_binding.h" #include "net/third_party/quic/core/crypto/proof_verifier.h" #include "net/third_party/quic/core/crypto/quic_random.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_clock.h"
diff --git a/net/quic/chromium/quic_stream_factory.h b/net/quic/chromium/quic_stream_factory.h index 7fe42c6..29db22a 100644 --- a/net/quic/chromium/quic_stream_factory.h +++ b/net/quic/chromium/quic_stream_factory.h
@@ -35,7 +35,7 @@ #include "net/quic/chromium/quic_session_key.h" #include "net/socket/client_socket_pool.h" #include "net/ssl/ssl_config_service.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" #include "net/third_party/quic/core/quic_config.h" #include "net/third_party/quic/core/quic_crypto_stream.h" #include "net/third_party/quic/core/quic_packets.h"
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index f550b40b..65eab8e 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -49,7 +49,7 @@ #include "net/third_party/quic/core/crypto/quic_crypto_client_config.h" #include "net/third_party/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quic/core/crypto/quic_encrypter.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" #include "net/third_party/quic/platform/api/quic_test.h" #include "net/third_party/quic/test_tools/mock_clock.h" #include "net/third_party/quic/test_tools/mock_random.h"
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index c48e02f..2049ec2 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc
@@ -54,7 +54,7 @@ #include "net/ssl/channel_id_service.h" #include "net/ssl/ssl_cipher_suite_names.h" #include "net/ssl/ssl_connection_status_flags.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/spdy/core/spdy_frame_builder.h" #include "net/third_party/spdy/core/spdy_protocol.h" #include "url/url_constants.h"
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender.h b/net/third_party/quic/core/congestion_control/bbr_sender.h index ba1595aa..6e1f275 100644 --- a/net/third_party/quic/core/congestion_control/bbr_sender.h +++ b/net/third_party/quic/core/congestion_control/bbr_sender.h
@@ -96,6 +96,8 @@ QuicPacketCount initial_tcp_congestion_window, QuicPacketCount max_tcp_congestion_window, QuicRandom* random); + BbrSender(const BbrSender&) = delete; + BbrSender& operator=(const BbrSender&) = delete; ~BbrSender() override; // Start implementation of SendAlgorithmInterface. @@ -384,8 +386,6 @@ bool probe_rtt_disabled_if_app_limited_; bool app_limited_since_last_probe_rtt_; QuicTime::Delta min_rtt_since_last_probe_rtt_; - - DISALLOW_COPY_AND_ASSIGN(BbrSender); }; QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
diff --git a/net/third_party/quic/core/congestion_control/cubic_bytes.h b/net/third_party/quic/core/congestion_control/cubic_bytes.h index ef1e382..990dae8f 100644 --- a/net/third_party/quic/core/congestion_control/cubic_bytes.h +++ b/net/third_party/quic/core/congestion_control/cubic_bytes.h
@@ -26,6 +26,8 @@ class QUIC_EXPORT_PRIVATE CubicBytes { public: explicit CubicBytes(const QuicClock* clock); + CubicBytes(const CubicBytes&) = delete; + CubicBytes& operator=(const CubicBytes&) = delete; void SetNumConnections(int num_connections); @@ -94,8 +96,6 @@ // Last congestion window in packets computed by cubic function. QuicByteCount last_target_congestion_window_; - - DISALLOW_COPY_AND_ASSIGN(CubicBytes); }; } // namespace quic
diff --git a/net/third_party/quic/core/congestion_control/general_loss_algorithm.h b/net/third_party/quic/core/congestion_control/general_loss_algorithm.h index 3409279f..e69e0c7 100644 --- a/net/third_party/quic/core/congestion_control/general_loss_algorithm.h +++ b/net/third_party/quic/core/congestion_control/general_loss_algorithm.h
@@ -27,6 +27,8 @@ GeneralLossAlgorithm(); explicit GeneralLossAlgorithm(LossDetectionType loss_type); + GeneralLossAlgorithm(const GeneralLossAlgorithm&) = delete; + GeneralLossAlgorithm& operator=(const GeneralLossAlgorithm&) = delete; ~GeneralLossAlgorithm() override {} LossDetectionType GetLossDetectionType() const override; @@ -70,8 +72,6 @@ QuicPacketNumber largest_previously_acked_; // The largest lost packet. QuicPacketNumber largest_lost_; - - DISALLOW_COPY_AND_ASSIGN(GeneralLossAlgorithm); }; } // namespace quic
diff --git a/net/third_party/quic/core/congestion_control/hybrid_slow_start.h b/net/third_party/quic/core/congestion_control/hybrid_slow_start.h index cbc2b890..a171bcc 100644 --- a/net/third_party/quic/core/congestion_control/hybrid_slow_start.h +++ b/net/third_party/quic/core/congestion_control/hybrid_slow_start.h
@@ -28,6 +28,8 @@ class QUIC_EXPORT_PRIVATE HybridSlowStart { public: HybridSlowStart(); + HybridSlowStart(const HybridSlowStart&) = delete; + HybridSlowStart& operator=(const HybridSlowStart&) = delete; void OnPacketAcked(QuicPacketNumber acked_packet_number); @@ -75,8 +77,6 @@ QuicPacketNumber end_packet_number_; // End of the receive round. uint32_t rtt_sample_count_; // Number of rtt samples in the current round. QuicTime::Delta current_min_rtt_; // The minimum rtt of current round. - - DISALLOW_COPY_AND_ASSIGN(HybridSlowStart); }; } // namespace quic
diff --git a/net/third_party/quic/core/congestion_control/pacing_sender.h b/net/third_party/quic/core/congestion_control/pacing_sender.h index f8eddcd..bb018b5 100644 --- a/net/third_party/quic/core/congestion_control/pacing_sender.h +++ b/net/third_party/quic/core/congestion_control/pacing_sender.h
@@ -32,6 +32,8 @@ class QUIC_EXPORT_PRIVATE PacingSender { public: PacingSender(); + PacingSender(const PacingSender&) = delete; + PacingSender& operator=(const PacingSender&) = delete; ~PacingSender(); // Sets the underlying sender. Does not take ownership of |sender|. |sender| @@ -99,8 +101,6 @@ // Indicates whether pacing throttles the sending. If true, make up for lost // time. bool pacing_limited_; - - DISALLOW_COPY_AND_ASSIGN(PacingSender); }; } // namespace quic
diff --git a/net/third_party/quic/core/congestion_control/rtt_stats.h b/net/third_party/quic/core/congestion_control/rtt_stats.h index 168de9d..93d10166 100644 --- a/net/third_party/quic/core/congestion_control/rtt_stats.h +++ b/net/third_party/quic/core/congestion_control/rtt_stats.h
@@ -25,6 +25,8 @@ class QUIC_EXPORT_PRIVATE RttStats { public: RttStats(); + RttStats(const RttStats&) = delete; + RttStats& operator=(const RttStats&) = delete; // Updates the RTT from an incoming ack which is received |send_delta| after // the packet is sent and the peer reports the ack being delayed |ack_delay|. @@ -101,8 +103,6 @@ QuicTime::Delta max_ack_delay_; // Whether to ignore the peer's max ack delay. bool ignore_max_ack_delay_; - - DISALLOW_COPY_AND_ASSIGN(RttStats); }; } // namespace quic
diff --git a/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes.h index 9651db5..4d550ec 100644 --- a/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes.h +++ b/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -40,6 +40,8 @@ QuicPacketCount initial_tcp_congestion_window, QuicPacketCount max_congestion_window, QuicConnectionStats* stats); + TcpCubicSenderBytes(const TcpCubicSenderBytes&) = delete; + TcpCubicSenderBytes& operator=(const TcpCubicSenderBytes&) = delete; ~TcpCubicSenderBytes() override; // Start implementation of SendAlgorithmInterface. @@ -164,8 +166,6 @@ // The minimum window when exiting slow start with large reduction. QuicByteCount min_slow_start_exit_window_; - - DISALLOW_COPY_AND_ASSIGN(TcpCubicSenderBytes); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/aead_base_decrypter.h b/net/third_party/quic/core/crypto/aead_base_decrypter.h index e8467e1..5650cf3 100644 --- a/net/third_party/quic/core/crypto/aead_base_decrypter.h +++ b/net/third_party/quic/core/crypto/aead_base_decrypter.h
@@ -26,6 +26,8 @@ size_t auth_tag_size, size_t nonce_size, bool use_ietf_nonce_construction); + AeadBaseDecrypter(const AeadBaseDecrypter&) = delete; + AeadBaseDecrypter& operator=(const AeadBaseDecrypter&) = delete; ~AeadBaseDecrypter() override; // QuicDecrypter implementation @@ -67,8 +69,6 @@ unsigned char iv_[kMaxNonceSize]; ScopedEVPAEADCtx ctx_; - - DISALLOW_COPY_AND_ASSIGN(AeadBaseDecrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/aead_base_encrypter.h b/net/third_party/quic/core/crypto/aead_base_encrypter.h index 3bf975e..41ea7f4c 100644 --- a/net/third_party/quic/core/crypto/aead_base_encrypter.h +++ b/net/third_party/quic/core/crypto/aead_base_encrypter.h
@@ -26,6 +26,8 @@ size_t auth_tag_size, size_t nonce_size, bool use_ietf_nonce_construction); + AeadBaseEncrypter(const AeadBaseEncrypter&) = delete; + AeadBaseEncrypter& operator=(const AeadBaseEncrypter&) = delete; ~AeadBaseEncrypter() override; // QuicEncrypter implementation @@ -74,8 +76,6 @@ unsigned char iv_[kMaxNonceSize]; ScopedEVPAEADCtx ctx_; - - DISALLOW_COPY_AND_ASSIGN(AeadBaseEncrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/aes_128_gcm_12_decrypter.h b/net/third_party/quic/core/crypto/aes_128_gcm_12_decrypter.h index 78f3b22..a9027695 100644 --- a/net/third_party/quic/core/crypto/aes_128_gcm_12_decrypter.h +++ b/net/third_party/quic/core/crypto/aes_128_gcm_12_decrypter.h
@@ -27,12 +27,11 @@ }; Aes128Gcm12Decrypter(); + Aes128Gcm12Decrypter(const Aes128Gcm12Decrypter&) = delete; + Aes128Gcm12Decrypter& operator=(const Aes128Gcm12Decrypter&) = delete; ~Aes128Gcm12Decrypter() override; uint32_t cipher_id() const override; - - private: - DISALLOW_COPY_AND_ASSIGN(Aes128Gcm12Decrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h b/net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h index d24c21e..06939bb 100644 --- a/net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h +++ b/net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h
@@ -25,10 +25,9 @@ }; Aes128Gcm12Encrypter(); + Aes128Gcm12Encrypter(const Aes128Gcm12Encrypter&) = delete; + Aes128Gcm12Encrypter& operator=(const Aes128Gcm12Encrypter&) = delete; ~Aes128Gcm12Encrypter() override; - - private: - DISALLOW_COPY_AND_ASSIGN(Aes128Gcm12Encrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/aes_128_gcm_decrypter.h b/net/third_party/quic/core/crypto/aes_128_gcm_decrypter.h index bca4fad..347af07 100644 --- a/net/third_party/quic/core/crypto/aes_128_gcm_decrypter.h +++ b/net/third_party/quic/core/crypto/aes_128_gcm_decrypter.h
@@ -25,12 +25,11 @@ }; Aes128GcmDecrypter(); + Aes128GcmDecrypter(const Aes128GcmDecrypter&) = delete; + Aes128GcmDecrypter& operator=(const Aes128GcmDecrypter&) = delete; ~Aes128GcmDecrypter() override; uint32_t cipher_id() const override; - - private: - DISALLOW_COPY_AND_ASSIGN(Aes128GcmDecrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/aes_128_gcm_encrypter.h b/net/third_party/quic/core/crypto/aes_128_gcm_encrypter.h index e78d6fd..8682db5 100644 --- a/net/third_party/quic/core/crypto/aes_128_gcm_encrypter.h +++ b/net/third_party/quic/core/crypto/aes_128_gcm_encrypter.h
@@ -23,10 +23,9 @@ }; Aes128GcmEncrypter(); + Aes128GcmEncrypter(const Aes128GcmEncrypter&) = delete; + Aes128GcmEncrypter& operator=(const Aes128GcmEncrypter&) = delete; ~Aes128GcmEncrypter() override; - - private: - DISALLOW_COPY_AND_ASSIGN(Aes128GcmEncrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/aes_256_gcm_decrypter.h b/net/third_party/quic/core/crypto/aes_256_gcm_decrypter.h index 16618eb..1e5d094 100644 --- a/net/third_party/quic/core/crypto/aes_256_gcm_decrypter.h +++ b/net/third_party/quic/core/crypto/aes_256_gcm_decrypter.h
@@ -25,12 +25,11 @@ }; Aes256GcmDecrypter(); + Aes256GcmDecrypter(const Aes256GcmDecrypter&) = delete; + Aes256GcmDecrypter& operator=(const Aes256GcmDecrypter&) = delete; ~Aes256GcmDecrypter() override; uint32_t cipher_id() const override; - - private: - DISALLOW_COPY_AND_ASSIGN(Aes256GcmDecrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/aes_256_gcm_encrypter.h b/net/third_party/quic/core/crypto/aes_256_gcm_encrypter.h index 5169b7b..6feb94d7 100644 --- a/net/third_party/quic/core/crypto/aes_256_gcm_encrypter.h +++ b/net/third_party/quic/core/crypto/aes_256_gcm_encrypter.h
@@ -23,10 +23,9 @@ }; Aes256GcmEncrypter(); + Aes256GcmEncrypter(const Aes256GcmEncrypter&) = delete; + Aes256GcmEncrypter& operator=(const Aes256GcmEncrypter&) = delete; ~Aes256GcmEncrypter() override; - - private: - DISALLOW_COPY_AND_ASSIGN(Aes256GcmEncrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/cert_compressor.h b/net/third_party/quic/core/crypto/cert_compressor.h index daa6cc9..0669519 100644 --- a/net/third_party/quic/core/crypto/cert_compressor.h +++ b/net/third_party/quic/core/crypto/cert_compressor.h
@@ -30,6 +30,8 @@ // methods and a small chunk of common substrings. class QUIC_EXPORT_PRIVATE CertCompressor { public: + CertCompressor() = delete; + // CompressChain compresses the certificates in |certs| and returns a // compressed representation. |common_sets| contains the common certificate // sets known locally and |client_common_set_hashes| contains the hashes of @@ -48,9 +50,6 @@ const std::vector<QuicString>& cached_certs, const CommonCertSets* common_sets, std::vector<QuicString>* out_certs); - - private: - DISALLOW_COPY_AND_ASSIGN(CertCompressor); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/chacha20_poly1305_decrypter.h b/net/third_party/quic/core/crypto/chacha20_poly1305_decrypter.h index 9707b3ad..fc9b36a 100644 --- a/net/third_party/quic/core/crypto/chacha20_poly1305_decrypter.h +++ b/net/third_party/quic/core/crypto/chacha20_poly1305_decrypter.h
@@ -27,12 +27,12 @@ }; ChaCha20Poly1305Decrypter(); + ChaCha20Poly1305Decrypter(const ChaCha20Poly1305Decrypter&) = delete; + ChaCha20Poly1305Decrypter& operator=(const ChaCha20Poly1305Decrypter&) = + delete; ~ChaCha20Poly1305Decrypter() override; uint32_t cipher_id() const override; - - private: - DISALLOW_COPY_AND_ASSIGN(ChaCha20Poly1305Decrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/chacha20_poly1305_encrypter.h b/net/third_party/quic/core/crypto/chacha20_poly1305_encrypter.h index a995631..d5d762ec 100644 --- a/net/third_party/quic/core/crypto/chacha20_poly1305_encrypter.h +++ b/net/third_party/quic/core/crypto/chacha20_poly1305_encrypter.h
@@ -25,10 +25,10 @@ }; ChaCha20Poly1305Encrypter(); + ChaCha20Poly1305Encrypter(const ChaCha20Poly1305Encrypter&) = delete; + ChaCha20Poly1305Encrypter& operator=(const ChaCha20Poly1305Encrypter&) = + delete; ~ChaCha20Poly1305Encrypter() override; - - private: - DISALLOW_COPY_AND_ASSIGN(ChaCha20Poly1305Encrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/chacha20_poly1305_tls_decrypter.h b/net/third_party/quic/core/crypto/chacha20_poly1305_tls_decrypter.h index b6b477d8..07feb50 100644 --- a/net/third_party/quic/core/crypto/chacha20_poly1305_tls_decrypter.h +++ b/net/third_party/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
@@ -26,12 +26,12 @@ }; ChaCha20Poly1305TlsDecrypter(); + ChaCha20Poly1305TlsDecrypter(const ChaCha20Poly1305TlsDecrypter&) = delete; + ChaCha20Poly1305TlsDecrypter& operator=(const ChaCha20Poly1305TlsDecrypter&) = + delete; ~ChaCha20Poly1305TlsDecrypter() override; uint32_t cipher_id() const override; - - private: - DISALLOW_COPY_AND_ASSIGN(ChaCha20Poly1305TlsDecrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/chacha20_poly1305_tls_encrypter.h b/net/third_party/quic/core/crypto/chacha20_poly1305_tls_encrypter.h index 930956c..2db7c9b 100644 --- a/net/third_party/quic/core/crypto/chacha20_poly1305_tls_encrypter.h +++ b/net/third_party/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
@@ -24,10 +24,10 @@ }; ChaCha20Poly1305TlsEncrypter(); + ChaCha20Poly1305TlsEncrypter(const ChaCha20Poly1305TlsEncrypter&) = delete; + ChaCha20Poly1305TlsEncrypter& operator=(const ChaCha20Poly1305TlsEncrypter&) = + delete; ~ChaCha20Poly1305TlsEncrypter() override; - - private: - DISALLOW_COPY_AND_ASSIGN(ChaCha20Poly1305TlsEncrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/channel_id.h b/net/third_party/quic/core/crypto/channel_id.h index 99a5ee3..2a91474 100644 --- a/net/third_party/quic/core/crypto/channel_id.h +++ b/net/third_party/quic/core/crypto/channel_id.h
@@ -66,6 +66,8 @@ // ChannelIDVerifier verifies ChannelID signatures. class QUIC_EXPORT_PRIVATE ChannelIDVerifier { public: + ChannelIDVerifier() = delete; + // kContextStr is prepended to the data to be signed in order to ensure that // a ChannelID signature cannot be used in a different context. (The // terminating NUL byte is inclued.) @@ -89,9 +91,6 @@ QuicStringPiece signed_data, QuicStringPiece signature, bool is_channel_id_signature); - - private: - DISALLOW_COPY_AND_ASSIGN(ChannelIDVerifier); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/common_cert_set.cc b/net/third_party/quic/core/crypto/common_cert_set.cc index 4151d39..e81d111b 100644 --- a/net/third_party/quic/core/crypto/common_cert_set.cc +++ b/net/third_party/quic/core/crypto/common_cert_set.cc
@@ -148,10 +148,11 @@ private: CommonCertSetsQUIC() {} + CommonCertSetsQUIC(const CommonCertSetsQUIC&) = delete; + CommonCertSetsQUIC& operator=(const CommonCertSetsQUIC&) = delete; ~CommonCertSetsQUIC() override {} friend QuicSingletonFriend<CommonCertSetsQUIC>; - DISALLOW_COPY_AND_ASSIGN(CommonCertSetsQUIC); }; } // anonymous namespace
diff --git a/net/third_party/quic/core/crypto/crypto_handshake.h b/net/third_party/quic/core/crypto/crypto_handshake.h index 129b733..77d8599 100644 --- a/net/third_party/quic/core/crypto/crypto_handshake.h +++ b/net/third_party/quic/core/crypto/crypto_handshake.h
@@ -168,6 +168,8 @@ static const char kForwardSecureLabel[]; QuicCryptoConfig(); + QuicCryptoConfig(const QuicCryptoConfig&) = delete; + QuicCryptoConfig& operator=(const QuicCryptoConfig&) = delete; ~QuicCryptoConfig(); // Key exchange methods. The following two members' values correspond by @@ -181,9 +183,6 @@ QuicTagVector tb_key_params; const CommonCertSets* common_cert_sets; - - private: - DISALLOW_COPY_AND_ASSIGN(QuicCryptoConfig); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/crypto_secret_boxer.h b/net/third_party/quic/core/crypto/crypto_secret_boxer.h index 33beb208c..8723045f 100644 --- a/net/third_party/quic/core/crypto/crypto_secret_boxer.h +++ b/net/third_party/quic/core/crypto/crypto_secret_boxer.h
@@ -25,6 +25,8 @@ class QUIC_EXPORT_PRIVATE CryptoSecretBoxer { public: CryptoSecretBoxer(); + CryptoSecretBoxer(const CryptoSecretBoxer&) = delete; + CryptoSecretBoxer& operator=(const CryptoSecretBoxer&) = delete; ~CryptoSecretBoxer(); // GetKeySize returns the number of bytes in a key. @@ -59,8 +61,6 @@ // state_ is an opaque pointer to whatever additional state the concrete // implementation of CryptoSecretBoxer requires. std::unique_ptr<State> state_ GUARDED_BY(lock_); - - DISALLOW_COPY_AND_ASSIGN(CryptoSecretBoxer); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/crypto_utils.h b/net/third_party/quic/core/crypto/crypto_utils.h index f4930ec7..59294fd 100644 --- a/net/third_party/quic/core/crypto/crypto_utils.h +++ b/net/third_party/quic/core/crypto/crypto_utils.h
@@ -27,6 +27,8 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { public: + CryptoUtils() = delete; + // Diversification is a utility class that's used to act like a union type. // Values can be created by calling the functions like |NoDiversification|, // below. @@ -218,9 +220,6 @@ static void HashHandshakeMessage(const CryptoHandshakeMessage& message, QuicString* output, Perspective perspective); - - private: - DISALLOW_COPY_AND_ASSIGN(CryptoUtils); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/null_decrypter.h b/net/third_party/quic/core/crypto/null_decrypter.h index 97bc337e..49d22fe 100644 --- a/net/third_party/quic/core/crypto/null_decrypter.h +++ b/net/third_party/quic/core/crypto/null_decrypter.h
@@ -25,6 +25,8 @@ class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter { public: explicit NullDecrypter(Perspective perspective); + NullDecrypter(const NullDecrypter&) = delete; + NullDecrypter& operator=(const NullDecrypter&) = delete; ~NullDecrypter() override {} // QuicDecrypter implementation @@ -54,8 +56,6 @@ QuicStringPiece data2) const; Perspective perspective_; - - DISALLOW_COPY_AND_ASSIGN(NullDecrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/null_encrypter.h b/net/third_party/quic/core/crypto/null_encrypter.h index 1ad9e25..a549d466 100644 --- a/net/third_party/quic/core/crypto/null_encrypter.h +++ b/net/third_party/quic/core/crypto/null_encrypter.h
@@ -22,6 +22,8 @@ class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter { public: explicit NullEncrypter(Perspective perspective); + NullEncrypter(const NullEncrypter&) = delete; + NullEncrypter& operator=(const NullEncrypter&) = delete; ~NullEncrypter() override {} // QuicEncrypter implementation @@ -47,8 +49,6 @@ size_t GetHashLength() const; Perspective perspective_; - - DISALLOW_COPY_AND_ASSIGN(NullEncrypter); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/p256_key_exchange.h b/net/third_party/quic/core/crypto/p256_key_exchange.h index ae01620..c7496829 100644 --- a/net/third_party/quic/core/crypto/p256_key_exchange.h +++ b/net/third_party/quic/core/crypto/p256_key_exchange.h
@@ -54,12 +54,12 @@ // |kUncompressedP256PointBytes| bytes. P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key, const uint8_t* public_key); + P256KeyExchange(const P256KeyExchange&) = delete; + P256KeyExchange& operator=(const P256KeyExchange&) = delete; bssl::UniquePtr<EC_KEY> private_key_; // The public key stored as an uncompressed P-256 point. uint8_t public_key_[kUncompressedP256PointBytes]; - - DISALLOW_COPY_AND_ASSIGN(P256KeyExchange); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/proof_source.h b/net/third_party/quic/core/crypto/proof_source.h index 3a683dc1..938a4c6 100644 --- a/net/third_party/quic/core/crypto/proof_source.h +++ b/net/third_party/quic/core/crypto/proof_source.h
@@ -26,14 +26,13 @@ // certificates. struct QUIC_EXPORT_PRIVATE Chain : public QuicReferenceCounted { explicit Chain(const std::vector<QuicString>& certs); + Chain(const Chain&) = delete; + Chain& operator=(const Chain&) = delete; const std::vector<QuicString> certs; protected: ~Chain() override; - - private: - DISALLOW_COPY_AND_ASSIGN(Chain); }; // Details is an abstract class which acts as a container for any
diff --git a/net/third_party/quic/core/crypto/quic_crypto_client_config.h b/net/third_party/quic/core/crypto/quic_crypto_client_config.h index 0f4cb3d..6882d2a 100644 --- a/net/third_party/quic/core/crypto/quic_crypto_client_config.h +++ b/net/third_party/quic/core/crypto/quic_crypto_client_config.h
@@ -58,6 +58,8 @@ }; CachedState(); + CachedState(const CachedState&) = delete; + CachedState& operator=(const CachedState&) = delete; ~CachedState(); // IsComplete returns true if this object contains enough information to @@ -192,8 +194,6 @@ // nonces and connection_ids together in one queue. QuicQueue<QuicConnectionId> server_designated_connection_ids_; QuicQueue<QuicString> server_nonces_; - - DISALLOW_COPY_AND_ASSIGN(CachedState); }; // Used to filter server ids for partial config deletion. @@ -207,6 +207,8 @@ QuicCryptoClientConfig(std::unique_ptr<ProofVerifier> proof_verifier, bssl::UniquePtr<SSL_CTX> ssl_ctx); + QuicCryptoClientConfig(const QuicCryptoClientConfig&) = delete; + QuicCryptoClientConfig& operator=(const QuicCryptoClientConfig&) = delete; ~QuicCryptoClientConfig(); // LookupOrCreate returns a CachedState for the given |server_id|. If no such @@ -405,8 +407,6 @@ // If non-empty, the client will operate in the pre-shared key mode by // incorporating |pre_shared_key_| into the key schedule. QuicString pre_shared_key_; - - DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientConfig); }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/quic_crypto_server_config.cc b/net/third_party/quic/core/crypto/quic_crypto_server_config.cc index 540dd02..b3a0473 100644 --- a/net/third_party/quic/core/crypto/quic_crypto_server_config.cc +++ b/net/third_party/quic/core/crypto/quic_crypto_server_config.cc
@@ -77,6 +77,9 @@ result, std::unique_ptr<ValidateClientHelloResultCallback>* done_cb) : result_(std::move(result)), done_cb_(done_cb) {} + ValidateClientHelloHelper(const ValidateClientHelloHelper&) = delete; + ValidateClientHelloHelper& operator=(const ValidateClientHelloHelper&) = + delete; ~ValidateClientHelloHelper() { QUIC_BUG_IF(done_cb_ != nullptr) @@ -102,8 +105,6 @@ QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> result_; std::unique_ptr<ValidateClientHelloResultCallback>* done_cb_; - - DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); }; // static
diff --git a/net/third_party/quic/core/crypto/quic_crypto_server_config.h b/net/third_party/quic/core/crypto/quic_crypto_server_config.h index d8f81a63..56bee07 100644 --- a/net/third_party/quic/core/crypto/quic_crypto_server_config.h +++ b/net/third_party/quic/core/crypto/quic_crypto_server_config.h
@@ -73,11 +73,11 @@ class PrimaryConfigChangedCallback { public: PrimaryConfigChangedCallback(); + PrimaryConfigChangedCallback(const PrimaryConfigChangedCallback&) = delete; + PrimaryConfigChangedCallback& operator=(const PrimaryConfigChangedCallback&) = + delete; virtual ~PrimaryConfigChangedCallback(); virtual void Run(const QuicString& scid) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(PrimaryConfigChangedCallback); }; // Callback used to accept the result of the |client_hello| validation step. @@ -103,27 +103,29 @@ }; ValidateClientHelloResultCallback(); + ValidateClientHelloResultCallback(const ValidateClientHelloResultCallback&) = + delete; + ValidateClientHelloResultCallback& operator=( + const ValidateClientHelloResultCallback&) = delete; virtual ~ValidateClientHelloResultCallback(); virtual void Run(QuicReferenceCountedPointer<Result> result, std::unique_ptr<ProofSource::Details> details) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloResultCallback); }; // Callback used to accept the result of the ProcessClientHello method. class QUIC_EXPORT_PRIVATE ProcessClientHelloResultCallback { public: ProcessClientHelloResultCallback(); + ProcessClientHelloResultCallback(const ProcessClientHelloResultCallback&) = + delete; + ProcessClientHelloResultCallback& operator=( + const ProcessClientHelloResultCallback&) = delete; virtual ~ProcessClientHelloResultCallback(); virtual void Run(QuicErrorCode error, const QuicString& error_details, std::unique_ptr<CryptoHandshakeMessage> message, std::unique_ptr<DiversificationNonce> diversification_nonce, std::unique_ptr<ProofSource::Details> details) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(ProcessClientHelloResultCallback); }; // Callback used to receive the results of a call to @@ -132,10 +134,11 @@ public: BuildServerConfigUpdateMessageResultCallback() = default; virtual ~BuildServerConfigUpdateMessageResultCallback() {} + BuildServerConfigUpdateMessageResultCallback( + const BuildServerConfigUpdateMessageResultCallback&) = delete; + BuildServerConfigUpdateMessageResultCallback& operator=( + const BuildServerConfigUpdateMessageResultCallback&) = delete; virtual void Run(bool ok, const CryptoHandshakeMessage& message) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(BuildServerConfigUpdateMessageResultCallback); }; // Object that is interested in built rejections (which include REJ, SREJ and @@ -144,12 +147,11 @@ public: RejectionObserver() = default; virtual ~RejectionObserver() {} + RejectionObserver(const RejectionObserver&) = delete; + RejectionObserver& operator=(const RejectionObserver&) = delete; // Called after a rejection is built. virtual void OnRejectionBuilt(const std::vector<uint32_t>& reasons, CryptoHandshakeMessage* out) const = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(RejectionObserver); }; // QuicCryptoServerConfig contains the crypto configuration of a QUIC server. @@ -200,6 +202,8 @@ QuicRandom* server_nonce_entropy, std::unique_ptr<ProofSource> proof_source, bssl::UniquePtr<SSL_CTX> ssl_ctx); + QuicCryptoServerConfig(const QuicCryptoServerConfig&) = delete; + QuicCryptoServerConfig& operator=(const QuicCryptoServerConfig&) = delete; ~QuicCryptoServerConfig(); // TESTING is a magic parameter for passing to the constructor in tests. @@ -413,6 +417,8 @@ public QuicReferenceCounted { public: Config(); + Config(const Config&) = delete; + Config& operator=(const Config&) = delete; // TODO(rtenneti): since this is a class, we should probably do // getters/setters here. @@ -467,8 +473,6 @@ private: ~Config() override; - - DISALLOW_COPY_AND_ASSIGN(Config); }; typedef std::map<ServerConfigID, QuicReferenceCountedPointer<Config>> @@ -773,8 +777,6 @@ // If non-empty, the server will operate in the pre-shared key mode by // incorporating |pre_shared_key_| into the key schedule. QuicString pre_shared_key_; - - DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerConfig); }; struct QUIC_EXPORT_PRIVATE QuicSignedServerConfig
diff --git a/net/third_party/quic/core/crypto/quic_random.cc b/net/third_party/quic/core/crypto/quic_random.cc index a7a95691..3aa7bc9 100644 --- a/net/third_party/quic/core/crypto/quic_random.cc +++ b/net/third_party/quic/core/crypto/quic_random.cc
@@ -23,10 +23,11 @@ private: DefaultRandom() {} + DefaultRandom(const DefaultRandom&) = delete; + DefaultRandom& operator=(const DefaultRandom&) = delete; ~DefaultRandom() override {} friend QuicSingletonFriend<DefaultRandom>; - DISALLOW_COPY_AND_ASSIGN(DefaultRandom); }; DefaultRandom* DefaultRandom::GetInstance() {
diff --git a/net/third_party/quic/core/crypto/scoped_evp_aead_ctx.h b/net/third_party/quic/core/crypto/scoped_evp_aead_ctx.h index 8de9edd..d0855e8 100644 --- a/net/third_party/quic/core/crypto/scoped_evp_aead_ctx.h +++ b/net/third_party/quic/core/crypto/scoped_evp_aead_ctx.h
@@ -15,14 +15,14 @@ class ScopedEVPAEADCtx { public: ScopedEVPAEADCtx(); + ScopedEVPAEADCtx(const ScopedEVPAEADCtx&) = delete; + ScopedEVPAEADCtx& operator=(const ScopedEVPAEADCtx&) = delete; ~ScopedEVPAEADCtx(); EVP_AEAD_CTX* get(); private: EVP_AEAD_CTX ctx_; - - DISALLOW_COPY_AND_ASSIGN(ScopedEVPAEADCtx); }; } // namespace quic
diff --git a/net/third_party/quic/core/frames/quic_stream_frame.h b/net/third_party/quic/core/frames/quic_stream_frame.h index 0e585cd..cf6d981 100644 --- a/net/third_party/quic/core/frames/quic_stream_frame.h +++ b/net/third_party/quic/core/frames/quic_stream_frame.h
@@ -41,9 +41,8 @@ QuicStreamOffset offset, const char* data_buffer, QuicPacketLength data_length); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicStreamFrame); + QuicStreamFrame(const QuicStreamFrame&) = delete; + QuicStreamFrame& operator=(const QuicStreamFrame&) = delete; }; static_assert(sizeof(QuicStreamFrame) <= 64, "Keep the QuicStreamFrame size to a cacheline.");
diff --git a/net/third_party/quic/core/end_to_end_test.cc b/net/third_party/quic/core/http/end_to_end_test.cc similarity index 99% rename from net/third_party/quic/core/end_to_end_test.cc rename to net/third_party/quic/core/http/end_to_end_test.cc index bb39a7b..d38e060 100644 --- a/net/third_party/quic/core/end_to_end_test.cc +++ b/net/third_party/quic/core/http/end_to_end_test.cc
@@ -22,6 +22,8 @@ #include "net/test/test_with_scoped_task_environment.h" #include "net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h" #include "net/third_party/quic/core/crypto/null_encrypter.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" #include "net/third_party/quic/core/quic_epoll_connection_helper.h" #include "net/third_party/quic/core/quic_framer.h" #include "net/third_party/quic/core/quic_packet_creator.h" @@ -29,8 +31,6 @@ #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_server_id.h" #include "net/third_party/quic/core/quic_session.h" -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" #include "net/third_party/quic/core/quic_utils.h" #include "net/third_party/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quic/platform/api/quic_flags.h"
diff --git a/net/third_party/quic/core/quic_client_promised_info.cc b/net/third_party/quic/core/http/quic_client_promised_info.cc similarity index 97% rename from net/third_party/quic/core/quic_client_promised_info.cc rename to net/third_party/quic/core/http/quic_client_promised_info.cc index ff835e2..b9ecc72 100644 --- a/net/third_party/quic/core/quic_client_promised_info.cc +++ b/net/third_party/quic/core/http/quic_client_promised_info.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" #include <utility> -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quic/platform/api/quic_string.h"
diff --git a/net/third_party/quic/core/quic_client_promised_info.h b/net/third_party/quic/core/http/quic_client_promised_info.h similarity index 86% rename from net/third_party/quic/core/quic_client_promised_info.h rename to net/third_party/quic/core/http/quic_client_promised_info.h index 41e2259..c56eb6e 100644 --- a/net/third_party/quic/core/quic_client_promised_info.h +++ b/net/third_party/quic/core/http/quic_client_promised_info.h
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_CLIENT_PROMISED_INFO_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_CLIENT_PROMISED_INFO_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_ #include <cstddef> +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/core/quic_alarm.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" #include "net/third_party/quic/core/quic_packets.h" -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" #include "net/third_party/quic/platform/api/quic_export.h" #include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/spdy/core/spdy_framer.h" @@ -33,6 +33,8 @@ QuicClientPromisedInfo(QuicSpdyClientSessionBase* session, QuicStreamId id, QuicString url); + QuicClientPromisedInfo(const QuicClientPromisedInfo&) = delete; + QuicClientPromisedInfo& operator=(const QuicClientPromisedInfo&) = delete; virtual ~QuicClientPromisedInfo(); void Init(); @@ -105,10 +107,8 @@ // The promise will commit suicide eventually if it is not claimed by a GET // first. std::unique_ptr<QuicAlarm> cleanup_alarm_; - - DISALLOW_COPY_AND_ASSIGN(QuicClientPromisedInfo); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_CLIENT_PROMISED_INFO_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/net/third_party/quic/core/quic_client_promised_info_test.cc b/net/third_party/quic/core/http/quic_client_promised_info_test.cc similarity index 96% rename from net/third_party/quic/core/quic_client_promised_info_test.cc rename to net/third_party/quic/core/http/quic_client_promised_info_test.cc index 44cd5d6..619b08af 100644 --- a/net/third_party/quic/core/quic_client_promised_info_test.cc +++ b/net/third_party/quic/core/http/quic_client_promised_info_test.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" #include <memory> #include "base/macros.h" -#include "net/third_party/quic/core/quic_spdy_client_session.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" @@ -41,6 +41,9 @@ crypto_config_(crypto_test_utils::ProofVerifierForTesting(), TlsClientHandshaker::CreateSslCtx()), authorized_(true) {} + MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete; + MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) = + delete; ~MockQuicSpdyClientSession() override {} bool IsAuthorized(const QuicString& authority) override { @@ -55,8 +58,6 @@ QuicCryptoClientConfig crypto_config_; bool authorized_; - - DISALLOW_COPY_AND_ASSIGN(MockQuicSpdyClientSession); }; class QuicClientPromisedInfoTest : public QuicTest {
diff --git a/net/third_party/quic/core/quic_client_push_promise_index.cc b/net/third_party/quic/core/http/quic_client_push_promise_index.cc similarity index 86% rename from net/third_party/quic/core/quic_client_push_promise_index.cc rename to net/third_party/quic/core/http/quic_client_push_promise_index.cc index 5b29eaa0..4549123 100644 --- a/net/third_party/quic/core/quic_client_push_promise_index.cc +++ b/net/third_party/quic/core/http/quic_client_push_promise_index.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_string.h" using spdy::SpdyHeaderBlock;
diff --git a/net/third_party/quic/core/quic_client_push_promise_index.h b/net/third_party/quic/core/http/quic_client_push_promise_index.h similarity index 86% rename from net/third_party/quic/core/quic_client_push_promise_index.h rename to net/third_party/quic/core/http/quic_client_push_promise_index.h index fea5178d..bc62419 100644 --- a/net/third_party/quic/core/quic_client_push_promise_index.h +++ b/net/third_party/quic/core/http/quic_client_push_promise_index.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_ -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" #include "net/third_party/quic/core/quic_types.h" #include "net/third_party/quic/platform/api/quic_export.h" #include "net/third_party/quic/platform/api/quic_string.h" @@ -53,13 +53,15 @@ protected: TryHandle() {} + TryHandle(const TryHandle&) = delete; + TryHandle& operator=(const TryHandle&) = delete; ~TryHandle(); - - private: - DISALLOW_COPY_AND_ASSIGN(TryHandle); }; QuicClientPushPromiseIndex(); + QuicClientPushPromiseIndex(const QuicClientPushPromiseIndex&) = delete; + QuicClientPushPromiseIndex& operator=(const QuicClientPushPromiseIndex&) = + delete; virtual ~QuicClientPushPromiseIndex(); // Called by client code, used to enforce affinity between requests @@ -89,10 +91,8 @@ private: QuicPromisedByUrlMap promised_by_url_; - - DISALLOW_COPY_AND_ASSIGN(QuicClientPushPromiseIndex); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
diff --git a/net/third_party/quic/core/quic_client_push_promise_index_test.cc b/net/third_party/quic/core/http/quic_client_push_promise_index_test.cc similarity index 91% rename from net/third_party/quic/core/quic_client_push_promise_index_test.cc rename to net/third_party/quic/core/http/quic_client_push_promise_index_test.cc index 9c7c4d9e..27c3e33 100644 --- a/net/third_party/quic/core/quic_client_push_promise_index_test.cc +++ b/net/third_party/quic/core/http/quic_client_push_promise_index_test.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" -#include "net/third_party/quic/core/quic_spdy_client_session.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/quic/platform/api/quic_test.h" @@ -34,14 +34,15 @@ push_promise_index), crypto_config_(crypto_test_utils::ProofVerifierForTesting(), TlsClientHandshaker::CreateSslCtx()) {} + MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete; + MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) = + delete; ~MockQuicSpdyClientSession() override {} MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id)); private: QuicCryptoClientConfig crypto_config_; - - DISALLOW_COPY_AND_ASSIGN(MockQuicSpdyClientSession); }; class QuicClientPushPromiseIndexTest : public QuicTest {
diff --git a/net/third_party/quic/core/quic_header_list.cc b/net/third_party/quic/core/http/quic_header_list.cc similarity index 97% rename from net/third_party/quic/core/quic_header_list.cc rename to net/third_party/quic/core/http/quic_header_list.cc index 87e2a92..e0589680 100644 --- a/net/third_party/quic/core/quic_header_list.cc +++ b/net/third_party/quic/core/http/quic_header_list.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_header_list.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/platform/api/quic_flags.h"
diff --git a/net/third_party/quic/core/quic_header_list.h b/net/third_party/quic/core/http/quic_header_list.h similarity index 94% rename from net/third_party/quic/core/quic_header_list.h rename to net/third_party/quic/core/http/quic_header_list.h index 88d5e2a..016b484 100644 --- a/net/third_party/quic/core/quic_header_list.h +++ b/net/third_party/quic/core/http/quic_header_list.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_HEADER_LIST_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_HEADER_LIST_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_ #include <algorithm> #include <functional> @@ -85,4 +85,4 @@ } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_HEADER_LIST_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
diff --git a/net/third_party/quic/core/quic_header_list_test.cc b/net/third_party/quic/core/http/quic_header_list_test.cc similarity index 97% rename from net/third_party/quic/core/quic_header_list_test.cc rename to net/third_party/quic/core/http/quic_header_list_test.cc index 9928c7a..af745ac 100644 --- a/net/third_party/quic/core/quic_header_list_test.cc +++ b/net/third_party/quic/core/http/quic_header_list_test.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_header_list.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_string.h"
diff --git a/net/third_party/quic/core/quic_headers_stream.cc b/net/third_party/quic/core/http/quic_headers_stream.cc similarity index 97% rename from net/third_party/quic/core/quic_headers_stream.cc rename to net/third_party/quic/core/http/quic_headers_stream.cc index 115d9a7..b0c914e 100644 --- a/net/third_party/quic/core/quic_headers_stream.cc +++ b/net/third_party/quic/core/http/quic_headers_stream.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_headers_stream.h" +#include "net/third_party/quic/core/http/quic_headers_stream.h" -#include "net/third_party/quic/core/quic_spdy_session.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" #include "net/third_party/quic/platform/api/quic_arraysize.h" #include "net/third_party/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h"
diff --git a/net/third_party/quic/core/quic_headers_stream.h b/net/third_party/quic/core/http/quic_headers_stream.h similarity index 89% rename from net/third_party/quic/core/quic_headers_stream.h rename to net/third_party/quic/core/http/quic_headers_stream.h index 0c0187d1..3221522 100644 --- a/net/third_party/quic/core/quic_headers_stream.h +++ b/net/third_party/quic/core/http/quic_headers_stream.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 NET_THIRD_PARTY_QUIC_CORE_QUIC_HEADERS_STREAM_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_HEADERS_STREAM_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_ #include <cstddef> #include <memory> #include "base/macros.h" -#include "net/third_party/quic/core/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_header_list.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_stream.h" #include "net/third_party/quic/platform/api/quic_containers.h" @@ -30,6 +30,8 @@ class QUIC_EXPORT_PRIVATE QuicHeadersStream : public QuicStream { public: explicit QuicHeadersStream(QuicSpdySession* session); + QuicHeadersStream(const QuicHeadersStream&) = delete; + QuicHeadersStream& operator=(const QuicHeadersStream&) = delete; ~QuicHeadersStream() override; // QuicStream implementation @@ -87,10 +89,8 @@ // Headers that have not been fully acked. QuicDeque<CompressedHeaderInfo> unacked_headers_; - - DISALLOW_COPY_AND_ASSIGN(QuicHeadersStream); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_HEADERS_STREAM_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
diff --git a/net/third_party/quic/core/quic_headers_stream_test.cc b/net/third_party/quic/core/http/quic_headers_stream_test.cc similarity index 98% rename from net/third_party/quic/core/quic_headers_stream_test.cc rename to net/third_party/quic/core/http/quic_headers_stream_test.cc index 8016e2a..441403e 100644 --- a/net/third_party/quic/core/quic_headers_stream_test.cc +++ b/net/third_party/quic/core/http/quic_headers_stream_test.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_headers_stream.h" +#include "net/third_party/quic/core/http/quic_headers_stream.h" #include <cstdint> #include <ostream> @@ -10,9 +10,9 @@ #include <utility> #include <vector> +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_data_writer.h" #include "net/third_party/quic/core/quic_utils.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quic/platform/api/quic_flags.h" @@ -75,11 +75,11 @@ class MockQuicHpackDebugVisitor : public QuicHpackDebugVisitor { public: MockQuicHpackDebugVisitor() : QuicHpackDebugVisitor() {} + MockQuicHpackDebugVisitor(const MockQuicHpackDebugVisitor&) = delete; + MockQuicHpackDebugVisitor& operator=(const MockQuicHpackDebugVisitor&) = + delete; MOCK_METHOD1(OnUseEntry, void(QuicTime::Delta elapsed)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockQuicHpackDebugVisitor); }; namespace {
diff --git a/net/third_party/quic/core/quic_server_session_base.cc b/net/third_party/quic/core/http/quic_server_session_base.cc similarity index 98% rename from net/third_party/quic/core/quic_server_session_base.cc rename to net/third_party/quic/core/http/quic_server_session_base.cc index e9838213..432fafe 100644 --- a/net/third_party/quic/core/quic_server_session_base.cc +++ b/net/third_party/quic/core/http/quic_server_session_base.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_server_session_base.h" +#include "net/third_party/quic/core/http/quic_server_session_base.h" #include "net/third_party/quic/core/proto/cached_network_parameters.pb.h" #include "net/third_party/quic/core/quic_connection.h"
diff --git a/net/third_party/quic/core/quic_server_session_base.h b/net/third_party/quic/core/http/quic_server_session_base.h similarity index 91% rename from net/third_party/quic/core/quic_server_session_base.h rename to net/third_party/quic/core/http/quic_server_session_base.h index dae10a4..1ff4691 100644 --- a/net/third_party/quic/core/quic_server_session_base.h +++ b/net/third_party/quic/core/http/quic_server_session_base.h
@@ -4,8 +4,8 @@ // // A server specific QuicSession subclass. -#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_SERVER_SESSION_BASE_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_SERVER_SESSION_BASE_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_ #include <cstdint> #include <memory> @@ -14,9 +14,9 @@ #include "base/macros.h" #include "net/third_party/quic/core/crypto/quic_compressed_certs_cache.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" #include "net/third_party/quic/core/quic_crypto_server_stream.h" #include "net/third_party/quic/core/quic_packets.h" -#include "net/third_party/quic/core/quic_spdy_session.h" #include "net/third_party/quic/platform/api/quic_export.h" #include "net/third_party/quic/platform/api/quic_string.h" @@ -41,6 +41,8 @@ QuicCryptoServerStream::Helper* helper, const QuicCryptoServerConfig* crypto_config, QuicCompressedCertsCache* compressed_certs_cache); + QuicServerSessionBase(const QuicServerSessionBase&) = delete; + QuicServerSessionBase& operator=(const QuicServerSessionBase&) = delete; // Override the base class to cancel any ongoing asychronous crypto. void OnConnectionClosed(QuicErrorCode error, @@ -129,10 +131,8 @@ // should go away once we fix http://b//27897982 int32_t BandwidthToCachedParameterBytesPerSecond( const QuicBandwidth& bandwidth); - - DISALLOW_COPY_AND_ASSIGN(QuicServerSessionBase); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_SERVER_SESSION_BASE_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
diff --git a/net/third_party/quic/core/quic_server_session_base_test.cc b/net/third_party/quic/core/http/quic_server_session_base_test.cc similarity index 98% rename from net/third_party/quic/core/quic_server_session_base_test.cc rename to net/third_party/quic/core/http/quic_server_session_base_test.cc index 8ef5d3a..3bbef179 100644 --- a/net/third_party/quic/core/quic_server_session_base_test.cc +++ b/net/third_party/quic/core/http/quic_server_session_base_test.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_server_session_base.h" +#include "net/third_party/quic/core/http/quic_server_session_base.h" #include <cstdint> #include <memory> @@ -32,7 +32,6 @@ #include "net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h" #include "net/third_party/quic/test_tools/quic_session_peer.h" #include "net/third_party/quic/test_tools/quic_spdy_session_peer.h" -#include "net/third_party/quic/test_tools/quic_spdy_stream_peer.h" #include "net/third_party/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h" #include "net/third_party/quic/test_tools/quic_test_utils.h" @@ -383,13 +382,13 @@ GetQuicReloadableFlag(enable_quic_stateless_reject_support), session, helper) {} + MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete; + MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) = + delete; ~MockQuicCryptoServerStream() override {} MOCK_METHOD1(SendServerConfigUpdate, void(const CachedNetworkParameters* cached_network_parameters)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); }; TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
diff --git a/net/third_party/quic/core/quic_spdy_client_session.cc b/net/third_party/quic/core/http/quic_spdy_client_session.cc similarity index 95% rename from net/third_party/quic/core/quic_spdy_client_session.cc rename to net/third_party/quic/core/http/quic_spdy_client_session.cc index a6c11a91..d998cf2 100644 --- a/net/third_party/quic/core/quic_spdy_client_session.cc +++ b/net/third_party/quic/core/http/quic_spdy_client_session.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" #include "net/log/net_log_with_source.h" #include "net/quic/chromium/crypto/proof_verifier_chromium.h" #include "net/third_party/quic/core/crypto/crypto_protocol.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h"
diff --git a/net/third_party/quic/core/quic_spdy_client_session.h b/net/third_party/quic/core/http/quic_spdy_client_session.h similarity index 87% rename from net/third_party/quic/core/quic_spdy_client_session.h rename to net/third_party/quic/core/http/quic_spdy_client_session.h index 8a3b1ed..06fe99e 100644 --- a/net/third_party/quic/core/quic_spdy_client_session.h +++ b/net/third_party/quic/core/http/quic_spdy_client_session.h
@@ -4,16 +4,16 @@ // // A client specific QuicSession subclass. -#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_SESSION_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_SESSION_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_ #include <memory> #include "base/macros.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" #include "net/third_party/quic/core/quic_crypto_client_stream.h" #include "net/third_party/quic/core/quic_packets.h" -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" #include "net/third_party/quic/platform/api/quic_string.h" namespace quic { @@ -30,6 +30,8 @@ const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config, QuicClientPushPromiseIndex* push_promise_index); + QuicSpdyClientSession(const QuicSpdyClientSession&) = delete; + QuicSpdyClientSession& operator=(const QuicSpdyClientSession&) = delete; ~QuicSpdyClientSession() override; // Set up the QuicSpdyClientSession. Must be called prior to use. void Initialize() override; @@ -89,10 +91,8 @@ // If this is set to false, the client will ignore server GOAWAYs and allow // the creation of streams regardless of the high chance they will fail. bool respect_goaway_; - - DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientSession); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_SESSION_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
diff --git a/net/third_party/quic/core/quic_spdy_client_session_base.cc b/net/third_party/quic/core/http/quic_spdy_client_session_base.cc similarity index 96% rename from net/third_party/quic/core/quic_spdy_client_session_base.cc rename to net/third_party/quic/core/http/quic_spdy_client_session_base.cc index c1d959f..5080011 100644 --- a/net/third_party/quic/core/quic_spdy_client_session_base.cc +++ b/net/third_party/quic/core/http/quic_spdy_client_session_base.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_string.h"
diff --git a/net/third_party/quic/core/quic_spdy_client_session_base.h b/net/third_party/quic/core/http/quic_spdy_client_session_base.h similarity index 92% rename from net/third_party/quic/core/quic_spdy_client_session_base.h rename to net/third_party/quic/core/http/quic_spdy_client_session_base.h index a97ff63..b40aab9d 100644 --- a/net/third_party/quic/core/quic_spdy_client_session_base.h +++ b/net/third_party/quic/core/http/quic_spdy_client_session_base.h
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_SESSION_BASE_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_SESSION_BASE_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_ #include "base/macros.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" #include "net/third_party/quic/core/quic_crypto_client_stream.h" -#include "net/third_party/quic/core/quic_spdy_session.h" #include "net/third_party/quic/platform/api/quic_containers.h" #include "net/third_party/quic/platform/api/quic_export.h" #include "net/third_party/quic/platform/api/quic_string.h" @@ -41,6 +41,9 @@ QuicSpdyClientSessionBase(QuicConnection* connection, QuicClientPushPromiseIndex* push_promise_index, const QuicConfig& config); + QuicSpdyClientSessionBase(const QuicSpdyClientSessionBase&) = delete; + QuicSpdyClientSessionBase& operator=(const QuicSpdyClientSessionBase&) = + delete; ~QuicSpdyClientSessionBase() override; @@ -129,10 +132,8 @@ QuicClientPushPromiseIndex* push_promise_index_; QuicPromisedByIdMap promised_by_id_; QuicStreamId largest_promised_stream_id_; - - DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientSessionBase); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_SESSION_BASE_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
diff --git a/net/third_party/quic/core/quic_spdy_client_session_test.cc b/net/third_party/quic/core/http/quic_spdy_client_session_test.cc similarity index 99% rename from net/third_party/quic/core/quic_spdy_client_session_test.cc rename to net/third_party/quic/core/http/quic_spdy_client_session_test.cc index 142fe2af..37ab30a 100644 --- a/net/third_party/quic/core/quic_spdy_client_session_test.cc +++ b/net/third_party/quic/core/http/quic_spdy_client_session_test.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" #include <memory> #include <vector> #include "net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_arraysize.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h"
diff --git a/net/third_party/quic/core/quic_spdy_client_stream.cc b/net/third_party/quic/core/http/quic_spdy_client_stream.cc similarity index 94% rename from net/third_party/quic/core/quic_spdy_client_stream.cc rename to net/third_party/quic/core/http/quic_spdy_client_stream.cc index c03f47d..f6a157b 100644 --- a/net/third_party/quic/core/quic_spdy_client_stream.cc +++ b/net/third_party/quic/core/http/quic_spdy_client_stream.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_client_stream.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" #include <utility> +#include "net/third_party/quic/core/http/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_alarm.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" -#include "net/third_party/quic/core/quic_spdy_client_session.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/spdy/core/spdy_protocol.h"
diff --git a/net/third_party/quic/core/quic_spdy_client_stream.h b/net/third_party/quic/core/http/quic_spdy_client_stream.h similarity index 88% rename from net/third_party/quic/core/quic_spdy_client_stream.h rename to net/third_party/quic/core/http/quic_spdy_client_stream.h index 5fe0e36..26d7138 100644 --- a/net/third_party/quic/core/quic_spdy_client_stream.h +++ b/net/third_party/quic/core/http/quic_spdy_client_stream.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 NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_STREAM_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_STREAM_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_ #include <cstddef> #include "base/macros.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/core/quic_packets.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" #include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/spdy/core/spdy_framer.h" @@ -23,6 +23,8 @@ class QuicSpdyClientStream : public QuicSpdyStream { public: QuicSpdyClientStream(QuicStreamId id, QuicSpdyClientSession* session); + QuicSpdyClientStream(const QuicSpdyClientStream&) = delete; + QuicSpdyClientStream& operator=(const QuicSpdyClientStream&) = delete; ~QuicSpdyClientStream() override; // Override the base class to parse and store headers. @@ -87,10 +89,8 @@ // Expect: 100-continue. bool has_preliminary_headers_; spdy::SpdyHeaderBlock preliminary_headers_; - - DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientStream); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_STREAM_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/net/third_party/quic/core/quic_spdy_client_stream_test.cc b/net/third_party/quic/core/http/quic_spdy_client_stream_test.cc similarity index 95% rename from net/third_party/quic/core/quic_spdy_client_stream_test.cc rename to net/third_party/quic/core/http/quic_spdy_client_stream_test.cc index 33c713b..452c164 100644 --- a/net/third_party/quic/core/quic_spdy_client_stream_test.cc +++ b/net/third_party/quic/core/http/quic_spdy_client_stream_test.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_client_stream.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" #include <memory> #include "base/macros.h" -#include "net/third_party/quic/core/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_utils.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" @@ -42,14 +42,15 @@ push_promise_index), crypto_config_(crypto_test_utils::ProofVerifierForTesting(), TlsClientHandshaker::CreateSslCtx()) {} + MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete; + MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) = + delete; ~MockQuicSpdyClientSession() override = default; MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id)); private: QuicCryptoClientConfig crypto_config_; - - DISALLOW_COPY_AND_ASSIGN(MockQuicSpdyClientSession); }; class QuicSpdyClientStreamTest : public QuicTest {
diff --git a/net/third_party/quic/core/quic_spdy_server_stream_base.cc b/net/third_party/quic/core/http/quic_spdy_server_stream_base.cc similarity index 94% rename from net/third_party/quic/core/quic_spdy_server_stream_base.cc rename to net/third_party/quic/core/http/quic_spdy_server_stream_base.cc index 8ac9c6a..7da7f89 100644 --- a/net/third_party/quic/core/quic_spdy_server_stream_base.cc +++ b/net/third_party/quic/core/http/quic_spdy_server_stream_base.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_server_stream_base.h" +#include "net/third_party/quic/core/http/quic_spdy_server_stream_base.h" #include "net/third_party/quic/core/quic_error_codes.h" #include "net/third_party/quic/platform/api/quic_logging.h"
diff --git a/net/third_party/quic/core/http/quic_spdy_server_stream_base.h b/net/third_party/quic/core/http/quic_spdy_server_stream_base.h new file mode 100644 index 0000000..56006b0 --- /dev/null +++ b/net/third_party/quic/core/http/quic_spdy_server_stream_base.h
@@ -0,0 +1,26 @@ +// Copyright (c) 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 NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_ + +#include "net/third_party/quic/core/http/quic_spdy_stream.h" + +namespace quic { + +class QuicSpdyServerStreamBase : public QuicSpdyStream { + public: + QuicSpdyServerStreamBase(QuicStreamId id, QuicSpdySession* session); + QuicSpdyServerStreamBase(const QuicSpdyServerStreamBase&) = delete; + QuicSpdyServerStreamBase& operator=(const QuicSpdyServerStreamBase&) = delete; + + // Override the base class to send QUIC_STREAM_NO_ERROR to the peer + // when the stream has not received all the data. + void CloseWriteSide() override; + void StopReading() override; +}; + +} // namespace quic + +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
diff --git a/net/third_party/quic/core/quic_spdy_server_stream_base_test.cc b/net/third_party/quic/core/http/quic_spdy_server_stream_base_test.cc similarity index 96% rename from net/third_party/quic/core/quic_spdy_server_stream_base_test.cc rename to net/third_party/quic/core/http/quic_spdy_server_stream_base_test.cc index 032914a..44f4039 100644 --- a/net/third_party/quic/core/quic_spdy_server_stream_base_test.cc +++ b/net/third_party/quic/core/http/quic_spdy_server_stream_base_test.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_server_stream_base.h" +#include "net/third_party/quic/core/http/quic_spdy_server_stream_base.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quic/platform/api/quic_test.h"
diff --git a/net/third_party/quic/core/quic_spdy_session.cc b/net/third_party/quic/core/http/quic_spdy_session.cc similarity index 97% rename from net/third_party/quic/core/quic_spdy_session.cc rename to net/third_party/quic/core/http/quic_spdy_session.cc index 9127014..d600c519 100644 --- a/net/third_party/quic/core/quic_spdy_session.cc +++ b/net/third_party/quic/core/http/quic_spdy_session.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_session.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" #include <algorithm> #include <cstdint> #include <utility> -#include "net/third_party/quic/core/quic_headers_stream.h" +#include "net/third_party/quic/core/http/quic_headers_stream.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quic/platform/api/quic_flag_utils.h" @@ -55,6 +55,8 @@ HeaderTableDebugVisitor(const QuicClock* clock, std::unique_ptr<QuicHpackDebugVisitor> visitor) : clock_(clock), headers_stream_hpack_visitor_(std::move(visitor)) {} + HeaderTableDebugVisitor(const HeaderTableDebugVisitor&) = delete; + HeaderTableDebugVisitor& operator=(const HeaderTableDebugVisitor&) = delete; int64_t OnNewEntry(const HpackEntry& entry) override { QUIC_DVLOG(1) << entry.GetDebugString(); @@ -74,8 +76,6 @@ private: const QuicClock* clock_; std::unique_ptr<QuicHpackDebugVisitor> headers_stream_hpack_visitor_; - - DISALLOW_COPY_AND_ASSIGN(HeaderTableDebugVisitor); }; } // namespace @@ -87,6 +87,8 @@ public SpdyFramerDebugVisitorInterface { public: explicit SpdyFramerVisitor(QuicSpdySession* session) : session_(session) {} + SpdyFramerVisitor(const SpdyFramerVisitor&) = delete; + SpdyFramerVisitor& operator=(const SpdyFramerVisitor&) = delete; SpdyHeadersHandlerInterface* OnHeaderFrameStart( SpdyStreamId /* stream_id */) override { @@ -289,8 +291,6 @@ private: QuicSpdySession* session_; QuicHeaderList header_list_; - - DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor); }; QuicHpackDebugVisitor::QuicHpackDebugVisitor() {}
diff --git a/net/third_party/quic/core/quic_spdy_session.h b/net/third_party/quic/core/http/quic_spdy_session.h similarity index 93% rename from net/third_party/quic/core/quic_spdy_session.h rename to net/third_party/quic/core/http/quic_spdy_session.h index 74ed443..9ecf6d0 100644 --- a/net/third_party/quic/core/quic_spdy_session.h +++ b/net/third_party/quic/core/http/quic_spdy_session.h
@@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_SESSION_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_SESSION_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_ #include <cstddef> #include <memory> #include "base/macros.h" -#include "net/third_party/quic/core/quic_header_list.h" -#include "net/third_party/quic/core/quic_headers_stream.h" +#include "net/third_party/quic/core/http/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_headers_stream.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/core/quic_session.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" #include "net/third_party/quic/platform/api/quic_export.h" #include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" @@ -32,6 +32,8 @@ class QUIC_EXPORT_PRIVATE QuicHpackDebugVisitor { public: QuicHpackDebugVisitor(); + QuicHpackDebugVisitor(const QuicHpackDebugVisitor&) = delete; + QuicHpackDebugVisitor& operator=(const QuicHpackDebugVisitor&) = delete; virtual ~QuicHpackDebugVisitor(); @@ -39,9 +41,6 @@ // the time since the corresponding entry was added to the dynamic // table. virtual void OnUseEntry(QuicTime::Delta elapsed) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(QuicHpackDebugVisitor); }; // A QUIC session with a headers stream. @@ -51,6 +50,8 @@ QuicSpdySession(QuicConnection* connection, QuicSession::Visitor* visitor, const QuicConfig& config); + QuicSpdySession(const QuicSpdySession&) = delete; + QuicSpdySession& operator=(const QuicSpdySession&) = delete; ~QuicSpdySession() override; @@ -239,10 +240,8 @@ spdy::SpdyFramer spdy_framer_; http2::Http2DecoderAdapter h2_deframer_; std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_; - - DISALLOW_COPY_AND_ASSIGN(QuicSpdySession); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_SESSION_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
diff --git a/net/third_party/quic/core/quic_spdy_session_test.cc b/net/third_party/quic/core/http/quic_spdy_session_test.cc similarity index 99% rename from net/third_party/quic/core/quic_spdy_session_test.cc rename to net/third_party/quic/core/http/quic_spdy_session_test.cc index 5edfb7e..fc9c5be 100644 --- a/net/third_party/quic/core/quic_spdy_session_test.cc +++ b/net/third_party/quic/core/http/quic_spdy_session_test.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_session.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" #include <cstdint> #include <set> @@ -28,7 +28,6 @@ #include "net/third_party/quic/test_tools/quic_flow_controller_peer.h" #include "net/third_party/quic/test_tools/quic_session_peer.h" #include "net/third_party/quic/test_tools/quic_spdy_session_peer.h" -#include "net/third_party/quic/test_tools/quic_spdy_stream_peer.h" #include "net/third_party/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quic/test_tools/quic_stream_send_buffer_peer.h" #include "net/third_party/quic/test_tools/quic_test_utils.h"
diff --git a/net/third_party/quic/core/quic_spdy_stream.cc b/net/third_party/quic/core/http/quic_spdy_stream.cc similarity index 97% rename from net/third_party/quic/core/quic_spdy_stream.cc rename to net/third_party/quic/core/http/quic_spdy_stream.cc index 3a8febc4..fe2c14f 100644 --- a/net/third_party/quic/core/quic_spdy_stream.cc +++ b/net/third_party/quic/core/http/quic_spdy_stream.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_stream.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include <utility> -#include "net/third_party/quic/core/quic_spdy_session.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_utils.h" #include "net/third_party/quic/core/quic_write_blocked_list.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_string.h"
diff --git a/net/third_party/quic/core/quic_spdy_stream.h b/net/third_party/quic/core/http/quic_spdy_stream.h similarity index 94% rename from net/third_party/quic/core/quic_spdy_stream.h rename to net/third_party/quic/core/http/quic_spdy_stream.h index 0ebe198..a511cbb 100644 --- a/net/third_party/quic/core/quic_spdy_stream.h +++ b/net/third_party/quic/core/http/quic_spdy_stream.h
@@ -6,8 +6,8 @@ // In each direction, the data on such a stream first contains compressed // headers then body data. -#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_STREAM_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_STREAM_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_ #include <sys/types.h> @@ -16,7 +16,7 @@ #include "base/macros.h" #include "net/base/iovec.h" -#include "net/third_party/quic/core/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_header_list.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_stream.h" #include "net/third_party/quic/core/quic_stream_sequencer.h" @@ -29,7 +29,6 @@ namespace quic { namespace test { -class QuicSpdyStreamPeer; class QuicStreamPeer; } // namespace test @@ -42,6 +41,8 @@ class QUIC_EXPORT_PRIVATE Visitor { public: Visitor() {} + Visitor(const Visitor&) = delete; + Visitor& operator=(const Visitor&) = delete; // Called when the stream is closed. virtual void OnClose(QuicSpdyStream* stream) = 0; @@ -52,12 +53,11 @@ protected: virtual ~Visitor() {} - - private: - DISALLOW_COPY_AND_ASSIGN(Visitor); }; QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session); + QuicSpdyStream(const QuicSpdyStream&) = delete; + QuicSpdyStream& operator=(const QuicSpdyStream&) = delete; ~QuicSpdyStream() override; // QuicStream implementation @@ -181,7 +181,6 @@ void set_headers_decompressed(bool val) { headers_decompressed_ = val; } private: - friend class test::QuicSpdyStreamPeer; friend class test::QuicStreamPeer; friend class QuicStreamUtils; @@ -200,10 +199,8 @@ bool trailers_consumed_; // The parsed trailers received from the peer. spdy::SpdyHeaderBlock received_trailers_; - - DISALLOW_COPY_AND_ASSIGN(QuicSpdyStream); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_STREAM_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
diff --git a/net/third_party/quic/core/quic_spdy_stream_test.cc b/net/third_party/quic/core/http/quic_spdy_stream_test.cc similarity index 99% rename from net/third_party/quic/core/quic_spdy_stream_test.cc rename to net/third_party/quic/core/http/quic_spdy_stream_test.cc index f2a9963..394a180 100644 --- a/net/third_party/quic/core/quic_spdy_stream_test.cc +++ b/net/third_party/quic/core/http/quic_spdy_stream_test.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/quic_spdy_stream.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include <memory> #include <utility> +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_utils.h" #include "net/third_party/quic/core/quic_write_blocked_list.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_arraysize.h" #include "net/third_party/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quic/platform/api/quic_map_util.h"
diff --git a/net/third_party/quic/core/spdy_utils.cc b/net/third_party/quic/core/http/spdy_utils.cc similarity index 98% rename from net/third_party/quic/core/spdy_utils.cc rename to net/third_party/quic/core/http/spdy_utils.cc index 90ac60c..31e2d09 100644 --- a/net/third_party/quic/core/spdy_utils.cc +++ b/net/third_party/quic/core/http/spdy_utils.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include <memory> #include <vector>
diff --git a/net/third_party/quic/core/spdy_utils.h b/net/third_party/quic/core/http/spdy_utils.h similarity index 89% rename from net/third_party/quic/core/spdy_utils.h rename to net/third_party/quic/core/http/spdy_utils.h index b12966d8..ec1bf11 100644 --- a/net/third_party/quic/core/spdy_utils.h +++ b/net/third_party/quic/core/http/spdy_utils.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 NET_THIRD_PARTY_QUIC_CORE_SPDY_UTILS_H_ -#define NET_THIRD_PARTY_QUIC_CORE_SPDY_UTILS_H_ +#ifndef NET_THIRD_PARTY_QUIC_CORE_HTTP_SPDY_UTILS_H_ +#define NET_THIRD_PARTY_QUIC_CORE_HTTP_SPDY_UTILS_H_ #include <cstddef> #include <cstdint> #include "base/macros.h" -#include "net/third_party/quic/core/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_header_list.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/platform/api/quic_export.h" #include "net/third_party/quic/platform/api/quic_string.h" @@ -19,6 +19,8 @@ class QUIC_EXPORT_PRIVATE SpdyUtils { public: + SpdyUtils() = delete; + // Populate |content length| with the value of the content-length header. // Returns true on success, false if parsing fails or content-length header is // missing. @@ -54,11 +56,8 @@ // which must be fully-qualified. static bool PopulateHeaderBlockFromUrl(const QuicString url, spdy::SpdyHeaderBlock* headers); - - private: - DISALLOW_COPY_AND_ASSIGN(SpdyUtils); }; } // namespace quic -#endif // NET_THIRD_PARTY_QUIC_CORE_SPDY_UTILS_H_ +#endif // NET_THIRD_PARTY_QUIC_CORE_HTTP_SPDY_UTILS_H_
diff --git a/net/third_party/quic/core/spdy_utils_test.cc b/net/third_party/quic/core/http/spdy_utils_test.cc similarity index 99% rename from net/third_party/quic/core/spdy_utils_test.cc rename to net/third_party/quic/core/http/spdy_utils_test.cc index 4910e72..3c6b618 100644 --- a/net/third_party/quic/core/spdy_utils_test.cc +++ b/net/third_party/quic/core/http/spdy_utils_test.cc
@@ -5,7 +5,7 @@ #include <memory> #include "base/macros.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/quic/platform/api/quic_test.h"
diff --git a/net/third_party/quic/core/quic_alarm.h b/net/third_party/quic/core/quic_alarm.h index 966bd7c6..e45464108 100644 --- a/net/third_party/quic/core/quic_alarm.h +++ b/net/third_party/quic/core/quic_alarm.h
@@ -28,6 +28,8 @@ }; explicit QuicAlarm(QuicArenaScopedPtr<Delegate> delegate); + QuicAlarm(const QuicAlarm&) = delete; + QuicAlarm& operator=(const QuicAlarm&) = delete; virtual ~QuicAlarm(); // Sets the alarm to fire at |deadline|. Must not be called while @@ -78,8 +80,6 @@ private: QuicArenaScopedPtr<Delegate> delegate_; QuicTime deadline_; - - DISALLOW_COPY_AND_ASSIGN(QuicAlarm); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_arena_scoped_ptr.h b/net/third_party/quic/core/quic_arena_scoped_ptr.h index 4ff6030c..7a524f85 100644 --- a/net/third_party/quic/core/quic_arena_scoped_ptr.h +++ b/net/third_party/quic/core/quic_arena_scoped_ptr.h
@@ -73,6 +73,8 @@ // Constructs a QuicArenaScopedPtr with the given representation. QuicArenaScopedPtr(void* value, ConstructFrom from); + QuicArenaScopedPtr(const QuicArenaScopedPtr&) = delete; + QuicArenaScopedPtr& operator=(const QuicArenaScopedPtr&) = delete; // Low-order bits of value_ that determine if the pointer came from an arena. static const uintptr_t kFromArenaMask = 0x1; @@ -80,8 +82,6 @@ // Every platform we care about has at least 4B aligned integers, so store the // is_from_arena bit in the least significant bit. void* value_; - - DISALLOW_COPY_AND_ASSIGN(QuicArenaScopedPtr); }; template <typename T>
diff --git a/net/third_party/quic/core/quic_connection.cc b/net/third_party/quic/core/quic_connection.cc index d5460ad..b94f16f 100644 --- a/net/third_party/quic/core/quic_connection.cc +++ b/net/third_party/quic/core/quic_connection.cc
@@ -85,6 +85,8 @@ public: explicit AckAlarmDelegate(QuicConnection* connection) : connection_(connection) {} + AckAlarmDelegate(const AckAlarmDelegate&) = delete; + AckAlarmDelegate& operator=(const AckAlarmDelegate&) = delete; void OnAlarm() override { DCHECK(connection_->ack_frame_updated()); @@ -94,8 +96,6 @@ private: QuicConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(AckAlarmDelegate); }; // This alarm will be scheduled any time a data-bearing packet is sent out. @@ -105,13 +105,14 @@ public: explicit RetransmissionAlarmDelegate(QuicConnection* connection) : connection_(connection) {} + RetransmissionAlarmDelegate(const RetransmissionAlarmDelegate&) = delete; + RetransmissionAlarmDelegate& operator=(const RetransmissionAlarmDelegate&) = + delete; void OnAlarm() override { connection_->OnRetransmissionTimeout(); } private: QuicConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(RetransmissionAlarmDelegate); }; // An alarm that is scheduled when the SentPacketManager requires a delay @@ -120,78 +121,82 @@ public: explicit SendAlarmDelegate(QuicConnection* connection) : connection_(connection) {} + SendAlarmDelegate(const SendAlarmDelegate&) = delete; + SendAlarmDelegate& operator=(const SendAlarmDelegate&) = delete; void OnAlarm() override { connection_->WriteAndBundleAcksIfNotBlocked(); } private: QuicConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(SendAlarmDelegate); }; class PathDegradingAlarmDelegate : public QuicAlarm::Delegate { public: explicit PathDegradingAlarmDelegate(QuicConnection* connection) : connection_(connection) {} + PathDegradingAlarmDelegate(const PathDegradingAlarmDelegate&) = delete; + PathDegradingAlarmDelegate& operator=(const PathDegradingAlarmDelegate&) = + delete; void OnAlarm() override { connection_->OnPathDegradingTimeout(); } private: QuicConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(PathDegradingAlarmDelegate); }; class TimeoutAlarmDelegate : public QuicAlarm::Delegate { public: explicit TimeoutAlarmDelegate(QuicConnection* connection) : connection_(connection) {} + TimeoutAlarmDelegate(const TimeoutAlarmDelegate&) = delete; + TimeoutAlarmDelegate& operator=(const TimeoutAlarmDelegate&) = delete; void OnAlarm() override { connection_->CheckForTimeout(); } private: QuicConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(TimeoutAlarmDelegate); }; class PingAlarmDelegate : public QuicAlarm::Delegate { public: explicit PingAlarmDelegate(QuicConnection* connection) : connection_(connection) {} + PingAlarmDelegate(const PingAlarmDelegate&) = delete; + PingAlarmDelegate& operator=(const PingAlarmDelegate&) = delete; void OnAlarm() override { connection_->OnPingTimeout(); } private: QuicConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(PingAlarmDelegate); }; class MtuDiscoveryAlarmDelegate : public QuicAlarm::Delegate { public: explicit MtuDiscoveryAlarmDelegate(QuicConnection* connection) : connection_(connection) {} + MtuDiscoveryAlarmDelegate(const MtuDiscoveryAlarmDelegate&) = delete; + MtuDiscoveryAlarmDelegate& operator=(const MtuDiscoveryAlarmDelegate&) = + delete; void OnAlarm() override { connection_->DiscoverMtu(); } private: QuicConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(MtuDiscoveryAlarmDelegate); }; class RetransmittableOnWireAlarmDelegate : public QuicAlarm::Delegate { public: explicit RetransmittableOnWireAlarmDelegate(QuicConnection* connection) : connection_(connection) {} + RetransmittableOnWireAlarmDelegate( + const RetransmittableOnWireAlarmDelegate&) = delete; + RetransmittableOnWireAlarmDelegate& operator=( + const RetransmittableOnWireAlarmDelegate&) = delete; void OnAlarm() override { connection_->OnPingTimeout(); } private: QuicConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(RetransmittableOnWireAlarmDelegate); }; } // namespace
diff --git a/net/third_party/quic/core/quic_connection.h b/net/third_party/quic/core/quic_connection.h index a3ab651c..a0d370b 100644 --- a/net/third_party/quic/core/quic_connection.h +++ b/net/third_party/quic/core/quic_connection.h
@@ -337,6 +337,8 @@ bool owns_writer, Perspective perspective, const ParsedQuicVersionVector& supported_versions); + QuicConnection(const QuicConnection&) = delete; + QuicConnection& operator=(const QuicConnection&) = delete; ~QuicConnection() override; // Sets connection parameters from the supplied |config|. @@ -1295,8 +1297,6 @@ // Latched value of quic_reloadable_flag_quic_retransmissions_app_limited. const bool retransmissions_app_limited_; - - DISALLOW_COPY_AND_ASSIGN(QuicConnection); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_connection_test.cc b/net/third_party/quic/core/quic_connection_test.cc index 714f521a..08b3417 100644 --- a/net/third_party/quic/core/quic_connection_test.cc +++ b/net/third_party/quic/core/quic_connection_test.cc
@@ -91,6 +91,8 @@ class TaggingEncrypter : public QuicEncrypter { public: explicit TaggingEncrypter(uint8_t tag) : tag_(tag) {} + TaggingEncrypter(const TaggingEncrypter&) = delete; + TaggingEncrypter& operator=(const TaggingEncrypter&) = delete; ~TaggingEncrypter() override {} @@ -142,8 +144,6 @@ }; const uint8_t tag_; - - DISALLOW_COPY_AND_ASSIGN(TaggingEncrypter); }; // TaggingDecrypter ensures that the final kTagSize bytes of the message all @@ -237,6 +237,8 @@ : clock_(clock), random_generator_(random_generator) { clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); } + TestConnectionHelper(const TestConnectionHelper&) = delete; + TestConnectionHelper& operator=(const TestConnectionHelper&) = delete; // QuicConnectionHelperInterface const QuicClock* GetClock() const override { return clock_; } @@ -251,8 +253,6 @@ MockClock* clock_; MockRandom* random_generator_; SimpleBufferAllocator buffer_allocator_; - - DISALLOW_COPY_AND_ASSIGN(TestConnectionHelper); }; class TestAlarmFactory : public QuicAlarmFactory { @@ -268,6 +268,8 @@ }; TestAlarmFactory() {} + TestAlarmFactory(const TestAlarmFactory&) = delete; + TestAlarmFactory& operator=(const TestAlarmFactory&) = delete; QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override { return new TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)); @@ -278,9 +280,6 @@ QuicConnectionArena* arena) override { return arena->New<TestAlarm>(std::move(delegate)); } - - private: - DISALLOW_COPY_AND_ASSIGN(TestAlarmFactory); }; class TestPacketWriter : public QuicPacketWriter { @@ -302,6 +301,8 @@ clock_(clock), write_pause_time_delta_(QuicTime::Delta::Zero()), max_packet_size_(kMaxPacketSize) {} + TestPacketWriter(const TestPacketWriter&) = delete; + TestPacketWriter& operator=(const TestPacketWriter&) = delete; // QuicPacketWriter interface WriteResult WritePacket(const char* buffer, @@ -492,8 +493,6 @@ // time. QuicTime::Delta write_pause_time_delta_; QuicByteCount max_packet_size_; - - DISALLOW_COPY_AND_ASSIGN(TestPacketWriter); }; class TestConnection : public QuicConnection { @@ -519,6 +518,8 @@ QuicMakeUnique<NullEncrypter>(perspective)); SetDataProducer(&producer_); } + TestConnection(const TestConnection&) = delete; + TestConnection& operator=(const TestConnection&) = delete; void SendAck() { QuicConnectionPeer::SendAck(this); } @@ -713,8 +714,6 @@ SimpleSessionNotifier* notifier_; std::unique_ptr<QuicSocketAddress> next_effective_peer_addr_; - - DISALLOW_COPY_AND_ASSIGN(TestConnection); }; enum class AckResponse { kDefer, kImmediate }; @@ -851,6 +850,9 @@ .Times(AnyNumber()); } + QuicConnectionTest(const QuicConnectionTest&) = delete; + QuicConnectionTest& operator=(const QuicConnectionTest&) = delete; + ParsedQuicVersion version() { return GetParam().version; } QuicAckFrame* outgoing_ack() { @@ -1245,9 +1247,6 @@ QuicConnectionIdLength connection_id_length_; SimpleSessionNotifier notifier_; - - private: - DISALLOW_COPY_AND_ASSIGN(QuicConnectionTest); }; // Run all end to end tests with all supported versions.
diff --git a/net/third_party/quic/core/quic_crypto_client_handshaker.h b/net/third_party/quic/core/quic_crypto_client_handshaker.h index c2859860c..a7cbb61 100644 --- a/net/third_party/quic/core/quic_crypto_client_handshaker.h +++ b/net/third_party/quic/core/quic_crypto_client_handshaker.h
@@ -32,6 +32,9 @@ std::unique_ptr<ProofVerifyContext> verify_context, QuicCryptoClientConfig* crypto_config, QuicCryptoClientStream::ProofHandler* proof_handler); + QuicCryptoClientHandshaker(const QuicCryptoClientHandshaker&) = delete; + QuicCryptoClientHandshaker& operator=(const QuicCryptoClientHandshaker&) = + delete; ~QuicCryptoClientHandshaker() override; @@ -233,8 +236,6 @@ bool handshake_confirmed_; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> crypto_negotiated_params_; - - DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientHandshaker); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_crypto_client_stream.h b/net/third_party/quic/core/quic_crypto_client_stream.h index 5bb85ce..b04047de8 100644 --- a/net/third_party/quic/core/quic_crypto_client_stream.h +++ b/net/third_party/quic/core/quic_crypto_client_stream.h
@@ -134,6 +134,8 @@ std::unique_ptr<ProofVerifyContext> verify_context, QuicCryptoClientConfig* crypto_config, ProofHandler* proof_handler); + QuicCryptoClientStream(const QuicCryptoClientStream&) = delete; + QuicCryptoClientStream& operator=(const QuicCryptoClientStream&) = delete; ~QuicCryptoClientStream() override; @@ -162,8 +164,6 @@ private: std::unique_ptr<HandshakerDelegate> handshaker_; - - DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientStream); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_crypto_handshaker.h b/net/third_party/quic/core/quic_crypto_handshaker.h index a88235fc..e5d139c 100644 --- a/net/third_party/quic/core/quic_crypto_handshaker.h +++ b/net/third_party/quic/core/quic_crypto_handshaker.h
@@ -14,6 +14,8 @@ : public CryptoFramerVisitorInterface { public: QuicCryptoHandshaker(QuicCryptoStream* stream, QuicSession* session); + QuicCryptoHandshaker(const QuicCryptoHandshaker&) = delete; + QuicCryptoHandshaker& operator=(const QuicCryptoHandshaker&) = delete; ~QuicCryptoHandshaker() override; @@ -41,8 +43,6 @@ // Records last sent crypto handshake message tag. QuicTag last_sent_handshake_message_tag_; - - DISALLOW_COPY_AND_ASSIGN(QuicCryptoHandshaker); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_crypto_server_handshaker.h b/net/third_party/quic/core/quic_crypto_server_handshaker.h index 3562a92..17a3be6d 100644 --- a/net/third_party/quic/core/quic_crypto_server_handshaker.h +++ b/net/third_party/quic/core/quic_crypto_server_handshaker.h
@@ -31,6 +31,9 @@ QuicCompressedCertsCache* compressed_certs_cache, QuicSession* session, QuicCryptoServerStream::Helper* helper); + QuicCryptoServerHandshaker(const QuicCryptoServerHandshaker&) = delete; + QuicCryptoServerHandshaker& operator=(const QuicCryptoServerHandshaker&) = + delete; ~QuicCryptoServerHandshaker() override; @@ -79,6 +82,8 @@ class ValidateCallback : public ValidateClientHelloResultCallback { public: explicit ValidateCallback(QuicCryptoServerHandshaker* parent); + ValidateCallback(const ValidateCallback&) = delete; + ValidateCallback& operator=(const ValidateCallback&) = delete; // To allow the parent to detach itself from the callback before deletion. void Cancel(); @@ -88,8 +93,6 @@ private: QuicCryptoServerHandshaker* parent_; - - DISALLOW_COPY_AND_ASSIGN(ValidateCallback); }; class SendServerConfigUpdateCallback @@ -221,8 +224,6 @@ bool handshake_confirmed_; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> crypto_negotiated_params_; - - DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerHandshaker); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_crypto_server_stream.h b/net/third_party/quic/core/quic_crypto_server_stream.h index 5626f25..1e49e48 100644 --- a/net/third_party/quic/core/quic_crypto_server_stream.h +++ b/net/third_party/quic/core/quic_crypto_server_stream.h
@@ -161,6 +161,8 @@ bool use_stateless_rejects_if_peer_supported, QuicSession* session, Helper* helper); + QuicCryptoServerStream(const QuicCryptoServerStream&) = delete; + QuicCryptoServerStream& operator=(const QuicCryptoServerStream&) = delete; ~QuicCryptoServerStream() override; @@ -220,8 +222,6 @@ const QuicCryptoServerConfig* crypto_config_; QuicCompressedCertsCache* compressed_certs_cache_; Helper* helper_; - - DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerStream); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_crypto_stream.h b/net/third_party/quic/core/quic_crypto_stream.h index 850502b..1d6a023f 100644 --- a/net/third_party/quic/core/quic_crypto_stream.h +++ b/net/third_party/quic/core/quic_crypto_stream.h
@@ -34,6 +34,8 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream { public: explicit QuicCryptoStream(QuicSession* session); + QuicCryptoStream(const QuicCryptoStream&) = delete; + QuicCryptoStream& operator=(const QuicCryptoStream&) = delete; ~QuicCryptoStream() override; @@ -108,8 +110,6 @@ // TODO(fayang): This is not needed once switching from QUIC crypto to // TLS 1.3, which never encrypts crypto data. QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS]; - - DISALLOW_COPY_AND_ASSIGN(QuicCryptoStream); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_crypto_stream_test.cc b/net/third_party/quic/core/quic_crypto_stream_test.cc index aa13037..a070950 100644 --- a/net/third_party/quic/core/quic_crypto_stream_test.cc +++ b/net/third_party/quic/core/quic_crypto_stream_test.cc
@@ -34,6 +34,8 @@ : QuicCryptoStream(session), QuicCryptoHandshaker(this, session), params_(new QuicCryptoNegotiatedParameters) {} + MockQuicCryptoStream(const MockQuicCryptoStream&) = delete; + MockQuicCryptoStream& operator=(const MockQuicCryptoStream&) = delete; void OnHandshakeMessage(const CryptoHandshakeMessage& message) override { messages_.push_back(message); @@ -60,8 +62,6 @@ private: QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_; std::vector<CryptoHandshakeMessage> messages_; - - DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoStream); }; class QuicCryptoStreamTest : public QuicTest { @@ -79,6 +79,8 @@ message_.SetStringPiece(2, "def"); ConstructHandshakeMessage(Perspective::IS_SERVER); } + QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete; + QuicCryptoStreamTest& operator=(const QuicCryptoStreamTest&) = delete; void ConstructHandshakeMessage(Perspective perspective) { CryptoFramer framer; @@ -94,9 +96,6 @@ MockQuicCryptoStream* stream_; CryptoHandshakeMessage message_; std::unique_ptr<QuicData> message_data_; - - private: - DISALLOW_COPY_AND_ASSIGN(QuicCryptoStreamTest); }; TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
diff --git a/net/third_party/quic/core/quic_data_reader.h b/net/third_party/quic/core/quic_data_reader.h index 256ed1b..81eaba1 100644 --- a/net/third_party/quic/core/quic_data_reader.h +++ b/net/third_party/quic/core/quic_data_reader.h
@@ -34,6 +34,8 @@ public: // Caller must provide an underlying buffer to work on. QuicDataReader(const char* data, const size_t len, Endianness endianness); + QuicDataReader(const QuicDataReader&) = delete; + QuicDataReader& operator=(const QuicDataReader&) = delete; // Empty destructor. ~QuicDataReader() {} @@ -159,8 +161,6 @@ // The endianness to read integers and floating numbers. Endianness endianness_; - - DISALLOW_COPY_AND_ASSIGN(QuicDataReader); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_data_writer.h b/net/third_party/quic/core/quic_data_writer.h index 98dbc68..7d7faaa1 100644 --- a/net/third_party/quic/core/quic_data_writer.h +++ b/net/third_party/quic/core/quic_data_writer.h
@@ -38,6 +38,8 @@ public: // Creates a QuicDataWriter where |buffer| is not owned. QuicDataWriter(size_t size, char* buffer, Endianness endianness); + QuicDataWriter(const QuicDataWriter&) = delete; + QuicDataWriter& operator=(const QuicDataWriter&) = delete; ~QuicDataWriter(); @@ -127,8 +129,6 @@ // The endianness to write integers and floating numbers. Endianness endianness_; - - DISALLOW_COPY_AND_ASSIGN(QuicDataWriter); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_default_packet_writer.h b/net/third_party/quic/core/quic_default_packet_writer.h index b72daa1..3500f91 100644 --- a/net/third_party/quic/core/quic_default_packet_writer.h +++ b/net/third_party/quic/core/quic_default_packet_writer.h
@@ -20,6 +20,8 @@ class QUIC_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter { public: explicit QuicDefaultPacketWriter(int fd); + QuicDefaultPacketWriter(const QuicDefaultPacketWriter&) = delete; + QuicDefaultPacketWriter& operator=(const QuicDefaultPacketWriter&) = delete; ~QuicDefaultPacketWriter() override; // QuicPacketWriter @@ -47,8 +49,6 @@ private: int fd_; bool write_blocked_; - - DISALLOW_COPY_AND_ASSIGN(QuicDefaultPacketWriter); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_dispatcher.cc b/net/third_party/quic/core/quic_dispatcher.cc index b863b78..79430b88 100644 --- a/net/third_party/quic/core/quic_dispatcher.cc +++ b/net/third_party/quic/core/quic_dispatcher.cc
@@ -35,14 +35,14 @@ public: explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher) : dispatcher_(dispatcher) {} + DeleteSessionsAlarm(const DeleteSessionsAlarm&) = delete; + DeleteSessionsAlarm& operator=(const DeleteSessionsAlarm&) = delete; void OnAlarm() override { dispatcher_->DeleteSessions(); } private: // Not owned. QuicDispatcher* dispatcher_; - - DISALLOW_COPY_AND_ASSIGN(DeleteSessionsAlarm); }; // Collects packets serialized by a QuicPacketCreator in order
diff --git a/net/third_party/quic/core/quic_dispatcher.h b/net/third_party/quic/core/quic_dispatcher.h index 2b5402a..61c6392 100644 --- a/net/third_party/quic/core/quic_dispatcher.h +++ b/net/third_party/quic/core/quic_dispatcher.h
@@ -50,6 +50,8 @@ std::unique_ptr<QuicConnectionHelperInterface> helper, std::unique_ptr<QuicCryptoServerStream::Helper> session_helper, std::unique_ptr<QuicAlarmFactory> alarm_factory); + QuicDispatcher(const QuicDispatcher&) = delete; + QuicDispatcher& operator=(const QuicDispatcher&) = delete; ~QuicDispatcher() override; @@ -446,8 +448,6 @@ // True if this dispatcher is not draining. bool accept_new_connections_; - - DISALLOW_COPY_AND_ASSIGN(QuicDispatcher); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_dispatcher_test.cc b/net/third_party/quic/core/quic_dispatcher_test.cc index 2f9e3d1..2bbdf16 100644 --- a/net/third_party/quic/core/quic_dispatcher_test.cc +++ b/net/third_party/quic/core/quic_dispatcher_test.cc
@@ -65,6 +65,9 @@ crypto_config, compressed_certs_cache), crypto_stream_(QuicServerSessionBase::GetMutableCryptoStream()) {} + TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete; + TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) = + delete; ~TestQuicSpdyServerSession() override { delete connection(); }; @@ -102,8 +105,6 @@ private: QuicCryptoServerStreamBase* crypto_stream_; - - DISALLOW_COPY_AND_ASSIGN(TestQuicSpdyServerSession); }; class TestDispatcher : public QuicDispatcher { @@ -805,6 +806,9 @@ session, helper), handshake_confirmed_(false) {} + MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete; + MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) = + delete; void set_handshake_confirmed_for_testing(bool handshake_confirmed) { handshake_confirmed_ = handshake_confirmed; @@ -814,7 +818,6 @@ private: bool handshake_confirmed_; - DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); }; struct StatelessRejectTestParams {
diff --git a/net/third_party/quic/core/quic_epoll_alarm_factory.h b/net/third_party/quic/core/quic_epoll_alarm_factory.h index 87e8ccda..9fe432d 100644 --- a/net/third_party/quic/core/quic_epoll_alarm_factory.h +++ b/net/third_party/quic/core/quic_epoll_alarm_factory.h
@@ -18,6 +18,8 @@ class QuicEpollAlarmFactory : public QuicAlarmFactory { public: explicit QuicEpollAlarmFactory(net::EpollServer* epoll_server); + QuicEpollAlarmFactory(const QuicEpollAlarmFactory&) = delete; + QuicEpollAlarmFactory& operator=(const QuicEpollAlarmFactory&) = delete; ~QuicEpollAlarmFactory() override; // QuicAlarmFactory interface. @@ -28,8 +30,6 @@ private: net::EpollServer* epoll_server_; // Not owned. - - DISALLOW_COPY_AND_ASSIGN(QuicEpollAlarmFactory); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_epoll_connection_helper.h b/net/third_party/quic/core/quic_epoll_connection_helper.h index f55be65..d996e08 100644 --- a/net/third_party/quic/core/quic_epoll_connection_helper.h +++ b/net/third_party/quic/core/quic_epoll_connection_helper.h
@@ -34,6 +34,9 @@ class QuicEpollConnectionHelper : public QuicConnectionHelperInterface { public: QuicEpollConnectionHelper(net::EpollServer* eps, QuicAllocator allocator); + QuicEpollConnectionHelper(const QuicEpollConnectionHelper&) = delete; + QuicEpollConnectionHelper& operator=(const QuicEpollConnectionHelper&) = + delete; ~QuicEpollConnectionHelper() override; // QuicEpollConnectionHelperInterface @@ -51,8 +54,6 @@ QuicStreamBufferAllocator stream_buffer_allocator_; SimpleBufferAllocator simple_buffer_allocator_; QuicAllocator allocator_type_; - - DISALLOW_COPY_AND_ASSIGN(QuicEpollConnectionHelper); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_flow_controller.h b/net/third_party/quic/core/quic_flow_controller.h index 6092f42..fc5deab 100644 --- a/net/third_party/quic/core/quic_flow_controller.h +++ b/net/third_party/quic/core/quic_flow_controller.h
@@ -48,6 +48,8 @@ QuicStreamOffset receive_window_offset, bool should_auto_tune_receive_window, QuicFlowControllerInterface* session_flow_controller); + QuicFlowController(const QuicFlowController&) = delete; + QuicFlowController& operator=(const QuicFlowController&) = delete; ~QuicFlowController() override {} @@ -195,8 +197,6 @@ // Keep time of the last time a window update was sent. We use this // as part of the receive window auto tuning. QuicTime prev_window_update_time_; - - DISALLOW_COPY_AND_ASSIGN(QuicFlowController); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_flow_controller_test.cc b/net/third_party/quic/core/quic_flow_controller_test.cc index b4a201b9..b59fac99 100644 --- a/net/third_party/quic/core/quic_flow_controller_test.cc +++ b/net/third_party/quic/core/quic_flow_controller_test.cc
@@ -26,12 +26,11 @@ class MockFlowController : public QuicFlowControllerInterface { public: MockFlowController() {} + MockFlowController(const MockFlowController&) = delete; + MockFlowController& operator=(const MockFlowController&) = delete; ~MockFlowController() override {} MOCK_METHOD1(EnsureWindowAtLeast, void(QuicByteCount)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockFlowController); }; class QuicFlowControllerTest : public QuicTest {
diff --git a/net/third_party/quic/core/quic_framer.h b/net/third_party/quic/core/quic_framer.h index 95420ef9..74dca318 100644 --- a/net/third_party/quic/core/quic_framer.h +++ b/net/third_party/quic/core/quic_framer.h
@@ -195,6 +195,8 @@ QuicFramer(const ParsedQuicVersionVector& supported_versions, QuicTime creation_time, Perspective perspective); + QuicFramer(const QuicFramer&) = delete; + QuicFramer& operator=(const QuicFramer&) = delete; virtual ~QuicFramer(); @@ -763,8 +765,6 @@ // If not null, framer asks data_producer_ to write stream frame data. Not // owned. TODO(fayang): Consider add data producer to framer's constructor. QuicStreamFrameDataProducer* data_producer_; - - DISALLOW_COPY_AND_ASSIGN(QuicFramer); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_one_block_arena.h b/net/third_party/quic/core/quic_one_block_arena.h index 494331ee..c07c2cc 100644 --- a/net/third_party/quic/core/quic_one_block_arena.h +++ b/net/third_party/quic/core/quic_one_block_arena.h
@@ -26,6 +26,8 @@ public: QuicOneBlockArena(); + QuicOneBlockArena(const QuicOneBlockArena&) = delete; + QuicOneBlockArena& operator=(const QuicOneBlockArena&) = delete; // Instantiates an object of type |T| with |args|. |args| are perfectly // forwarded to |T|'s constructor. The returned pointer's lifetime is @@ -46,8 +48,6 @@ QUIC_ALIGNED(8) char storage_[ArenaSize]; // Current offset into the storage. uint32_t offset_; - - DISALLOW_COPY_AND_ASSIGN(QuicOneBlockArena); }; template <uint32_t ArenaSize>
diff --git a/net/third_party/quic/core/quic_packet_creator.h b/net/third_party/quic/core/quic_packet_creator.h index 22859e9..2e670a07 100644 --- a/net/third_party/quic/core/quic_packet_creator.h +++ b/net/third_party/quic/core/quic_packet_creator.h
@@ -55,6 +55,8 @@ QuicPacketCreator(QuicConnectionId connection_id, QuicFramer* framer, DelegateInterface* delegate); + QuicPacketCreator(const QuicPacketCreator&) = delete; + QuicPacketCreator& operator=(const QuicPacketCreator&) = delete; ~QuicPacketCreator(); @@ -328,8 +330,6 @@ // If true, packet_'s transmission type is only set by // SetPacketTransmissionType and does not get cleared in ClearPacket. bool can_set_transmission_type_; - - DISALLOW_COPY_AND_ASSIGN(QuicPacketCreator); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_packet_generator.h b/net/third_party/quic/core/quic_packet_generator.h index 50a4077..44fb7eba 100644 --- a/net/third_party/quic/core/quic_packet_generator.h +++ b/net/third_party/quic/core/quic_packet_generator.h
@@ -75,6 +75,8 @@ QuicFramer* framer, QuicRandom* random_generator, DelegateInterface* delegate); + QuicPacketGenerator(const QuicPacketGenerator&) = delete; + QuicPacketGenerator& operator=(const QuicPacketGenerator&) = delete; ~QuicPacketGenerator(); @@ -237,8 +239,6 @@ QuicStopWaitingFrame pending_stop_waiting_frame_; QuicRandom* random_generator_; - - DISALLOW_COPY_AND_ASSIGN(QuicPacketGenerator); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_packet_generator_test.cc b/net/third_party/quic/core/quic_packet_generator_test.cc index 4b11b4c..721039d3 100644 --- a/net/third_party/quic/core/quic_packet_generator_test.cc +++ b/net/third_party/quic/core/quic_packet_generator_test.cc
@@ -40,6 +40,8 @@ class MockDelegate : public QuicPacketGenerator::DelegateInterface { public: MockDelegate() {} + MockDelegate(const MockDelegate&) = delete; + MockDelegate& operator=(const MockDelegate&) = delete; ~MockDelegate() override {} MOCK_METHOD2(ShouldGeneratePacket, @@ -72,9 +74,6 @@ EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _)) .WillRepeatedly(Return(true)); } - - private: - DISALLOW_COPY_AND_ASSIGN(MockDelegate); }; // Simple struct for describing the contents of a packet.
diff --git a/net/third_party/quic/core/quic_packet_reader.h b/net/third_party/quic/core/quic_packet_reader.h index 5fb7abb..f1353379 100644 --- a/net/third_party/quic/core/quic_packet_reader.h +++ b/net/third_party/quic/core/quic_packet_reader.h
@@ -31,6 +31,8 @@ class QuicPacketReader { public: QuicPacketReader(); + QuicPacketReader(const QuicPacketReader&) = delete; + QuicPacketReader& operator=(const QuicPacketReader&) = delete; virtual ~QuicPacketReader(); @@ -84,8 +86,6 @@ PacketData packets_[kNumPacketsPerReadMmsgCall]; mmsghdr mmsg_hdr_[kNumPacketsPerReadMmsgCall]; #endif - - DISALLOW_COPY_AND_ASSIGN(QuicPacketReader); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_packet_writer.h b/net/third_party/quic/core/quic_packet_writer.h index 46e0860..0399a8b9a 100644 --- a/net/third_party/quic/core/quic_packet_writer.h +++ b/net/third_party/quic/core/quic_packet_writer.h
@@ -28,9 +28,9 @@ private: PerPacketOptions(PerPacketOptions&& other) = delete; + PerPacketOptions(const PerPacketOptions&) = delete; + PerPacketOptions& operator=(const PerPacketOptions&) = delete; PerPacketOptions& operator=(PerPacketOptions&& other) = delete; - - DISALLOW_COPY_AND_ASSIGN(PerPacketOptions); }; // An interface between writers and the entity managing the
diff --git a/net/third_party/quic/core/quic_packet_writer_wrapper.h b/net/third_party/quic/core/quic_packet_writer_wrapper.h index 10820f5d..17a5b7b4 100644 --- a/net/third_party/quic/core/quic_packet_writer_wrapper.h +++ b/net/third_party/quic/core/quic_packet_writer_wrapper.h
@@ -19,6 +19,8 @@ class QuicPacketWriterWrapper : public QuicPacketWriter { public: QuicPacketWriterWrapper(); + QuicPacketWriterWrapper(const QuicPacketWriterWrapper&) = delete; + QuicPacketWriterWrapper& operator=(const QuicPacketWriterWrapper&) = delete; ~QuicPacketWriterWrapper() override; // Default implementation of the QuicPacketWriter interface. Passes everything @@ -53,8 +55,6 @@ QuicPacketWriter* writer_ = nullptr; bool owns_writer_ = false; - - DISALLOW_COPY_AND_ASSIGN(QuicPacketWriterWrapper); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_packets.h b/net/third_party/quic/core/quic_packets.h index 7b23cb0..e558340 100644 --- a/net/third_party/quic/core/quic_packets.h +++ b/net/third_party/quic/core/quic_packets.h
@@ -127,6 +127,8 @@ public: QuicData(const char* buffer, size_t length); QuicData(const char* buffer, size_t length, bool owns_buffer); + QuicData(const QuicData&) = delete; + QuicData& operator=(const QuicData&) = delete; virtual ~QuicData(); QuicStringPiece AsStringPiece() const { @@ -140,8 +142,6 @@ const char* buffer_; size_t length_; bool owns_buffer_; - - DISALLOW_COPY_AND_ASSIGN(QuicData); }; class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData { @@ -157,6 +157,8 @@ bool includes_version, bool includes_diversification_nonce, QuicPacketNumberLength packet_number_length); + QuicPacket(const QuicPacket&) = delete; + QuicPacket& operator=(const QuicPacket&) = delete; QuicStringPiece AssociatedData(QuicTransportVersion version) const; QuicStringPiece Plaintext(QuicTransportVersion version) const; @@ -170,14 +172,14 @@ const bool includes_version_; const bool includes_diversification_nonce_; const QuicPacketNumberLength packet_number_length_; - - DISALLOW_COPY_AND_ASSIGN(QuicPacket); }; class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData { public: QuicEncryptedPacket(const char* buffer, size_t length); QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer); + QuicEncryptedPacket(const QuicEncryptedPacket&) = delete; + QuicEncryptedPacket& operator=(const QuicEncryptedPacket&) = delete; // Clones the packet into a new packet which owns the buffer. std::unique_ptr<QuicEncryptedPacket> Clone() const; @@ -189,9 +191,6 @@ QUIC_EXPORT_PRIVATE friend std::ostream& operator<<( std::ostream& os, const QuicEncryptedPacket& s); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicEncryptedPacket); }; // A received encrypted QUIC packet, with a recorded time of receipt. @@ -208,6 +207,8 @@ bool owns_buffer, int ttl, bool ttl_valid); + QuicReceivedPacket(const QuicReceivedPacket&) = delete; + QuicReceivedPacket& operator=(const QuicReceivedPacket&) = delete; // Clones the packet into a new packet which owns the buffer. std::unique_ptr<QuicReceivedPacket> Clone() const; @@ -229,8 +230,6 @@ private: const QuicTime receipt_time_; int ttl_; - - DISALLOW_COPY_AND_ASSIGN(QuicReceivedPacket); }; struct QUIC_EXPORT_PRIVATE SerializedPacket {
diff --git a/net/third_party/quic/core/quic_received_packet_manager.h b/net/third_party/quic/core/quic_received_packet_manager.h index 7c615004..4438194 100644 --- a/net/third_party/quic/core/quic_received_packet_manager.h +++ b/net/third_party/quic/core/quic_received_packet_manager.h
@@ -23,6 +23,9 @@ class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager { public: explicit QuicReceivedPacketManager(QuicConnectionStats* stats); + QuicReceivedPacketManager(const QuicReceivedPacketManager&) = delete; + QuicReceivedPacketManager& operator=(const QuicReceivedPacketManager&) = + delete; virtual ~QuicReceivedPacketManager(); // Updates the internal state concerning which packets have been received. @@ -92,8 +95,6 @@ QuicTime time_largest_observed_; QuicConnectionStats* stats_; - - DISALLOW_COPY_AND_ASSIGN(QuicReceivedPacketManager); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_sent_packet_manager.h b/net/third_party/quic/core/quic_sent_packet_manager.h index ef8e796..85e7b48 100644 --- a/net/third_party/quic/core/quic_sent_packet_manager.h +++ b/net/third_party/quic/core/quic_sent_packet_manager.h
@@ -89,6 +89,8 @@ QuicConnectionStats* stats, CongestionControlType congestion_control_type, LossDetectionType loss_type); + QuicSentPacketManager(const QuicSentPacketManager&) = delete; + QuicSentPacketManager& operator=(const QuicSentPacketManager&) = delete; virtual ~QuicSentPacketManager(); virtual void SetFromConfig(const QuicConfig& config); @@ -551,8 +553,6 @@ // A reverse iterator of last_ack_frame_.packets. This is reset in // OnAckRangeStart, and gradually moves in OnAckRange.. PacketNumberQueue::const_reverse_iterator acked_packets_iter_; - - DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManager); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_session.h b/net/third_party/quic/core/quic_session.h index ce9f92db..b5093e6e 100644 --- a/net/third_party/quic/core/quic_session.h +++ b/net/third_party/quic/core/quic_session.h
@@ -82,6 +82,8 @@ QuicSession(QuicConnection* connection, Visitor* owner, const QuicConfig& config); + QuicSession(const QuicSession&) = delete; + QuicSession& operator=(const QuicSession&) = delete; ~QuicSession() override; @@ -551,8 +553,6 @@ // is not used here. // List of streams with pending retransmissions. QuicLinkedHashMap<QuicStreamId, bool> streams_with_pending_retransmission_; - - DISALLOW_COPY_AND_ASSIGN(QuicSession); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_socket_address_coder.h b/net/third_party/quic/core/quic_socket_address_coder.h index 6894079d..dbb84ad 100644 --- a/net/third_party/quic/core/quic_socket_address_coder.h +++ b/net/third_party/quic/core/quic_socket_address_coder.h
@@ -21,6 +21,8 @@ public: QuicSocketAddressCoder(); explicit QuicSocketAddressCoder(const QuicSocketAddress& address); + QuicSocketAddressCoder(const QuicSocketAddressCoder&) = delete; + QuicSocketAddressCoder& operator=(const QuicSocketAddressCoder&) = delete; ~QuicSocketAddressCoder(); QuicString Encode() const; @@ -33,8 +35,6 @@ private: QuicSocketAddress address_; - - DISALLOW_COPY_AND_ASSIGN(QuicSocketAddressCoder); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_spdy_server_stream_base.h b/net/third_party/quic/core/quic_spdy_server_stream_base.h deleted file mode 100644 index 74c7fa4..0000000 --- a/net/third_party/quic/core/quic_spdy_server_stream_base.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright (c) 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 NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_SERVER_STREAM_BASE_H_ -#define NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_SERVER_STREAM_BASE_H_ - -#include "net/third_party/quic/core/quic_spdy_stream.h" - -namespace quic { - -class QuicSpdyServerStreamBase : public QuicSpdyStream { - public: - QuicSpdyServerStreamBase(QuicStreamId id, QuicSpdySession* session); - - // Override the base class to send QUIC_STREAM_NO_ERROR to the peer - // when the stream has not received all the data. - void CloseWriteSide() override; - void StopReading() override; - - private: - DISALLOW_COPY_AND_ASSIGN(QuicSpdyServerStreamBase); -}; - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_SERVER_STREAM_BASE_H_
diff --git a/net/third_party/quic/core/quic_stream.h b/net/third_party/quic/core/quic_stream.h index 75e0d17..daa5ff49 100644 --- a/net/third_party/quic/core/quic_stream.h +++ b/net/third_party/quic/core/quic_stream.h
@@ -59,6 +59,8 @@ // |is_static| is true, then the stream will be given precedence // over other streams when determing what streams should write next. QuicStream(QuicStreamId id, QuicSession* session, bool is_static); + QuicStream(const QuicStream&) = delete; + QuicStream& operator=(const QuicStream&) = delete; virtual ~QuicStream(); @@ -433,8 +435,6 @@ // If true, then this stream has precedence over other streams for write // scheduling. const bool is_static_; - - DISALLOW_COPY_AND_ASSIGN(QuicStream); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_stream_sequencer.h b/net/third_party/quic/core/quic_stream_sequencer.h index e93d11b..f536f45a 100644 --- a/net/third_party/quic/core/quic_stream_sequencer.h +++ b/net/third_party/quic/core/quic_stream_sequencer.h
@@ -27,6 +27,8 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencer { public: explicit QuicStreamSequencer(QuicStream* quic_stream); + QuicStreamSequencer(const QuicStreamSequencer&) = delete; + QuicStreamSequencer& operator=(const QuicStreamSequencer&) = delete; virtual ~QuicStreamSequencer(); // If the frame is the next one we need in order to process in-order data, @@ -152,8 +154,6 @@ // If false, only call OnDataAvailable() when it becomes newly unblocked. // Otherwise, call OnDataAvailable() when number of readable bytes changes. bool level_triggered_; - - DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencer); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_stream_sequencer_buffer.h b/net/third_party/quic/core/quic_stream_sequencer_buffer.h index e76be81..45368dd 100644 --- a/net/third_party/quic/core/quic_stream_sequencer_buffer.h +++ b/net/third_party/quic/core/quic_stream_sequencer_buffer.h
@@ -88,6 +88,9 @@ }; explicit QuicStreamSequencerBuffer(size_t max_capacity_bytes); + QuicStreamSequencerBuffer(const QuicStreamSequencerBuffer&) = delete; + QuicStreamSequencerBuffer& operator=(const QuicStreamSequencerBuffer&) = + delete; ~QuicStreamSequencerBuffer(); // Free the space used to buffer data. @@ -225,8 +228,6 @@ // Currently received data. QuicIntervalSet<QuicStreamOffset> bytes_received_; - - DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencerBuffer); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_sustained_bandwidth_recorder.h b/net/third_party/quic/core/quic_sustained_bandwidth_recorder.h index 73baa1d0..123d193 100644 --- a/net/third_party/quic/core/quic_sustained_bandwidth_recorder.h +++ b/net/third_party/quic/core/quic_sustained_bandwidth_recorder.h
@@ -26,6 +26,10 @@ class QUIC_EXPORT_PRIVATE QuicSustainedBandwidthRecorder { public: QuicSustainedBandwidthRecorder(); + QuicSustainedBandwidthRecorder(const QuicSustainedBandwidthRecorder&) = + delete; + QuicSustainedBandwidthRecorder& operator=( + const QuicSustainedBandwidthRecorder&) = delete; // As long as |in_recovery| is consistently false, multiple calls to this // method over a 3 * srtt period results in storage of a valid sustained @@ -85,8 +89,6 @@ // Timestamp marking the beginning of the latest recording period. QuicTime start_time_; - - DISALLOW_COPY_AND_ASSIGN(QuicSustainedBandwidthRecorder); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_time_wait_list_manager.cc b/net/third_party/quic/core/quic_time_wait_list_manager.cc index 95bbecf..00aa6d5 100644 --- a/net/third_party/quic/core/quic_time_wait_list_manager.cc +++ b/net/third_party/quic/core/quic_time_wait_list_manager.cc
@@ -32,6 +32,8 @@ explicit ConnectionIdCleanUpAlarm( QuicTimeWaitListManager* time_wait_list_manager) : time_wait_list_manager_(time_wait_list_manager) {} + ConnectionIdCleanUpAlarm(const ConnectionIdCleanUpAlarm&) = delete; + ConnectionIdCleanUpAlarm& operator=(const ConnectionIdCleanUpAlarm&) = delete; void OnAlarm() override { time_wait_list_manager_->CleanUpOldConnectionIds(); @@ -40,8 +42,6 @@ private: // Not owned. QuicTimeWaitListManager* time_wait_list_manager_; - - DISALLOW_COPY_AND_ASSIGN(ConnectionIdCleanUpAlarm); }; // This class stores pending public reset packets to be sent to clients. @@ -59,6 +59,8 @@ : server_address_(server_address), client_address_(client_address), packet_(std::move(packet)) {} + QueuedPacket(const QueuedPacket&) = delete; + QueuedPacket& operator=(const QueuedPacket&) = delete; const QuicSocketAddress& server_address() const { return server_address_; } const QuicSocketAddress& client_address() const { return client_address_; } @@ -68,8 +70,6 @@ const QuicSocketAddress server_address_; const QuicSocketAddress client_address_; std::unique_ptr<QuicEncryptedPacket> packet_; - - DISALLOW_COPY_AND_ASSIGN(QueuedPacket); }; QuicTimeWaitListManager::QuicTimeWaitListManager(
diff --git a/net/third_party/quic/core/quic_time_wait_list_manager.h b/net/third_party/quic/core/quic_time_wait_list_manager.h index bae6a2c..45f559f 100644 --- a/net/third_party/quic/core/quic_time_wait_list_manager.h +++ b/net/third_party/quic/core/quic_time_wait_list_manager.h
@@ -66,6 +66,8 @@ Visitor* visitor, const QuicClock* clock, QuicAlarmFactory* alarm_factory); + QuicTimeWaitListManager(const QuicTimeWaitListManager&) = delete; + QuicTimeWaitListManager& operator=(const QuicTimeWaitListManager&) = delete; ~QuicTimeWaitListManager() override; // Adds the given connection_id to time wait state for time_wait_period_. @@ -215,8 +217,6 @@ // Interface that manages blocked writers. Visitor* visitor_; - - DISALLOW_COPY_AND_ASSIGN(QuicTimeWaitListManager); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_unacked_packet_map.h b/net/third_party/quic/core/quic_unacked_packet_map.h index ef14e46..656fbca 100644 --- a/net/third_party/quic/core/quic_unacked_packet_map.h +++ b/net/third_party/quic/core/quic_unacked_packet_map.h
@@ -23,6 +23,8 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap { public: QuicUnackedPacketMap(); + QuicUnackedPacketMap(const QuicUnackedPacketMap&) = delete; + QuicUnackedPacketMap& operator=(const QuicUnackedPacketMap&) = delete; ~QuicUnackedPacketMap(); // Adds |serialized_packet| to the map and marks it as sent at |sent_time|. @@ -231,8 +233,6 @@ // If true, let session decides what to write. bool session_decides_what_to_write_; - - DISALLOW_COPY_AND_ASSIGN(QuicUnackedPacketMap); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_utils.h b/net/third_party/quic/core/quic_utils.h index 5038faf..ba539a8 100644 --- a/net/third_party/quic/core/quic_utils.h +++ b/net/third_party/quic/core/quic_utils.h
@@ -22,6 +22,8 @@ class QUIC_EXPORT_PRIVATE QuicUtils { public: + QuicUtils() = delete; + // Returns the 64 bit FNV1a hash of the data. See // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param static uint64_t FNV1a_64_Hash(QuicStringPiece data); @@ -87,9 +89,6 @@ // Returns true if header with |first_byte| is considered as an IETF QUIC // packet header. static bool IsIetfPacketHeader(uint8_t first_byte); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicUtils); }; } // namespace quic
diff --git a/net/third_party/quic/core/quic_write_blocked_list.h b/net/third_party/quic/core/quic_write_blocked_list.h index 793f8a1..d592123b 100644 --- a/net/third_party/quic/core/quic_write_blocked_list.h +++ b/net/third_party/quic/core/quic_write_blocked_list.h
@@ -25,6 +25,8 @@ public: explicit QuicWriteBlockedList(); + QuicWriteBlockedList(const QuicWriteBlockedList&) = delete; + QuicWriteBlockedList& operator=(const QuicWriteBlockedList&) = delete; ~QuicWriteBlockedList(); bool HasWriteBlockedDataStreams() const { @@ -340,8 +342,6 @@ // Latched value of quic_use_static_stream_collection_in_write_blocked_list. const bool use_static_stream_collection_; - - DISALLOW_COPY_AND_ASSIGN(QuicWriteBlockedList); }; } // namespace quic
diff --git a/net/third_party/quic/core/stateless_rejector.h b/net/third_party/quic/core/stateless_rejector.h index 925d63f..6904bb8 100644 --- a/net/third_party/quic/core/stateless_rejector.h +++ b/net/third_party/quic/core/stateless_rejector.h
@@ -33,6 +33,8 @@ QuicByteCount chlo_packet_size, const QuicSocketAddress& client_address, const QuicSocketAddress& server_address); + StatelessRejector(const StatelessRejector&) = delete; + StatelessRejector& operator=(const StatelessRejector&) = delete; ~StatelessRejector(); @@ -110,8 +112,6 @@ CryptoFramer crypto_framer_; QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_; - - DISALLOW_COPY_AND_ASSIGN(StatelessRejector); }; } // namespace quic
diff --git a/net/third_party/quic/core/tls_client_handshaker.h b/net/third_party/quic/core/tls_client_handshaker.h index c950b59..9a51d432 100644 --- a/net/third_party/quic/core/tls_client_handshaker.h +++ b/net/third_party/quic/core/tls_client_handshaker.h
@@ -29,6 +29,8 @@ SSL_CTX* ssl_ctx, std::unique_ptr<ProofVerifyContext> verify_context, const QuicString& user_agent_id); + TlsClientHandshaker(const TlsClientHandshaker&) = delete; + TlsClientHandshaker& operator=(const TlsClientHandshaker&) = delete; ~TlsClientHandshaker() override; @@ -119,8 +121,6 @@ bool handshake_confirmed_ = false; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> crypto_negotiated_params_; - - DISALLOW_COPY_AND_ASSIGN(TlsClientHandshaker); }; } // namespace quic
diff --git a/net/third_party/quic/core/tls_handshaker.cc b/net/third_party/quic/core/tls_handshaker.cc index 08f105e..ad4f1838 100644 --- a/net/third_party/quic/core/tls_handshaker.cc +++ b/net/third_party/quic/core/tls_handshaker.cc
@@ -38,11 +38,12 @@ CHECK_LE(0, ssl_ex_data_index_handshaker_); } + SslIndexSingleton(const SslIndexSingleton&) = delete; + SslIndexSingleton& operator=(const SslIndexSingleton&) = delete; + friend QuicSingletonFriend<SslIndexSingleton>; int ssl_ex_data_index_handshaker_; - - DISALLOW_COPY_AND_ASSIGN(SslIndexSingleton); }; } // namespace
diff --git a/net/third_party/quic/core/tls_handshaker.h b/net/third_party/quic/core/tls_handshaker.h index d6fdea4..4975a11 100644 --- a/net/third_party/quic/core/tls_handshaker.h +++ b/net/third_party/quic/core/tls_handshaker.h
@@ -28,6 +28,8 @@ TlsHandshaker(QuicCryptoStream* stream, QuicSession* session, SSL_CTX* ssl_ctx); + TlsHandshaker(const TlsHandshaker&) = delete; + TlsHandshaker& operator=(const TlsHandshaker&) = delete; ~TlsHandshaker() override; @@ -81,8 +83,6 @@ QuicSession* session_; QuicTlsAdapter bio_adapter_; bssl::UniquePtr<SSL> ssl_; - - DISALLOW_COPY_AND_ASSIGN(TlsHandshaker); }; } // namespace quic
diff --git a/net/third_party/quic/core/tls_server_handshaker.h b/net/third_party/quic/core/tls_server_handshaker.h index 13fbdbb..b0a57a5 100644 --- a/net/third_party/quic/core/tls_server_handshaker.h +++ b/net/third_party/quic/core/tls_server_handshaker.h
@@ -27,6 +27,8 @@ QuicSession* session, SSL_CTX* ssl_ctx, ProofSource* proof_source); + TlsServerHandshaker(const TlsServerHandshaker&) = delete; + TlsServerHandshaker& operator=(const TlsServerHandshaker&) = delete; ~TlsServerHandshaker() override; @@ -159,8 +161,6 @@ bool handshake_confirmed_ = false; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> crypto_negotiated_params_; - - DISALLOW_COPY_AND_ASSIGN(TlsServerHandshaker); }; } // namespace quic
diff --git a/net/third_party/quic/platform/api/quic_hostname_utils.h b/net/third_party/quic/platform/api/quic_hostname_utils.h index 3fa4ffea..5f8d53fa 100644 --- a/net/third_party/quic/platform/api/quic_hostname_utils.h +++ b/net/third_party/quic/platform/api/quic_hostname_utils.h
@@ -14,6 +14,8 @@ class QUIC_EXPORT_PRIVATE QuicHostnameUtils { public: + QuicHostnameUtils() = delete; + // Returns true if the sni is valid, false otherwise. // (1) disallow IP addresses; // (2) check that the hostname contains valid characters only; and @@ -23,9 +25,6 @@ // Convert hostname to lowercase and remove the trailing '.'. // WARNING: mutates |hostname| in place and returns |hostname|. static char* NormalizeHostname(char* hostname); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicHostnameUtils); }; } // namespace quic
diff --git a/net/third_party/quic/platform/api/quic_lru_cache.h b/net/third_party/quic/platform/api/quic_lru_cache.h index facedb2..771a2cff 100644 --- a/net/third_party/quic/platform/api/quic_lru_cache.h +++ b/net/third_party/quic/platform/api/quic_lru_cache.h
@@ -19,6 +19,8 @@ class QuicLRUCache { public: explicit QuicLRUCache(int64_t total_units) : impl_(total_units) {} + QuicLRUCache(const QuicLRUCache&) = delete; + QuicLRUCache& operator=(const QuicLRUCache&) = delete; // Inserts one unit of |key|, |value| pair to the cache. Cache takes ownership // of inserted |value|. @@ -43,8 +45,6 @@ private: QuicLRUCacheImpl<K, V> impl_; - - DISALLOW_COPY_AND_ASSIGN(QuicLRUCache); }; } // namespace quic
diff --git a/net/third_party/quic/platform/api/quic_mutex.h b/net/third_party/quic/platform/api/quic_mutex.h index 280bed2..3637ce59 100644 --- a/net/third_party/quic/platform/api/quic_mutex.h +++ b/net/third_party/quic/platform/api/quic_mutex.h
@@ -14,6 +14,8 @@ class QUIC_EXPORT_PRIVATE LOCKABLE QuicMutex { public: QuicMutex() = default; + QuicMutex(const QuicMutex&) = delete; + QuicMutex& operator=(const QuicMutex&) = delete; // Block until this Mutex is free, then acquire it exclusively. void WriterLock() EXCLUSIVE_LOCK_FUNCTION(); @@ -34,8 +36,6 @@ private: QuicLockImpl impl_; - - DISALLOW_COPY_AND_ASSIGN(QuicMutex); }; // A helper class that acquires the given QuicMutex shared lock while the @@ -43,13 +43,13 @@ class QUIC_EXPORT_PRIVATE SCOPED_LOCKABLE QuicReaderMutexLock { public: explicit QuicReaderMutexLock(QuicMutex* lock) SHARED_LOCK_FUNCTION(lock); + QuicReaderMutexLock(const QuicReaderMutexLock&) = delete; + QuicReaderMutexLock& operator=(const QuicReaderMutexLock&) = delete; ~QuicReaderMutexLock() UNLOCK_FUNCTION(); private: QuicMutex* const lock_; - - DISALLOW_COPY_AND_ASSIGN(QuicReaderMutexLock); }; // A helper class that acquires the given QuicMutex exclusive lock while the @@ -57,13 +57,13 @@ class QUIC_EXPORT_PRIVATE SCOPED_LOCKABLE QuicWriterMutexLock { public: explicit QuicWriterMutexLock(QuicMutex* lock) EXCLUSIVE_LOCK_FUNCTION(lock); + QuicWriterMutexLock(const QuicWriterMutexLock&) = delete; + QuicWriterMutexLock& operator=(const QuicWriterMutexLock&) = delete; ~QuicWriterMutexLock() UNLOCK_FUNCTION(); private: QuicMutex* const lock_; - - DISALLOW_COPY_AND_ASSIGN(QuicWriterMutexLock); }; } // namespace quic
diff --git a/net/third_party/quic/platform/api/quic_url_utils.h b/net/third_party/quic/platform/api/quic_url_utils.h index 5580c39..65a1467 100644 --- a/net/third_party/quic/platform/api/quic_url_utils.h +++ b/net/third_party/quic/platform/api/quic_url_utils.h
@@ -15,6 +15,8 @@ class QUIC_EXPORT_PRIVATE QuicUrlUtils { public: + QuicUrlUtils() = delete; + // Returns hostname, or empty std::string if missing. static QuicString HostName(QuicStringPiece url); @@ -29,9 +31,6 @@ static QuicString GetPushPromiseUrl(QuicStringPiece scheme, QuicStringPiece authority, QuicStringPiece path); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicUrlUtils); }; } // namespace quic
diff --git a/net/third_party/quic/test_tools/limited_mtu_test_writer.h b/net/third_party/quic/test_tools/limited_mtu_test_writer.h index 105252b..4b9734d 100644 --- a/net/third_party/quic/test_tools/limited_mtu_test_writer.h +++ b/net/third_party/quic/test_tools/limited_mtu_test_writer.h
@@ -17,6 +17,8 @@ class LimitedMtuTestWriter : public QuicPacketWriterWrapper { public: explicit LimitedMtuTestWriter(QuicByteCount mtu); + LimitedMtuTestWriter(const LimitedMtuTestWriter&) = delete; + LimitedMtuTestWriter& operator=(const LimitedMtuTestWriter&) = delete; ~LimitedMtuTestWriter() override; // Inherited from QuicPacketWriterWrapper. @@ -28,8 +30,6 @@ private: QuicByteCount mtu_; - - DISALLOW_COPY_AND_ASSIGN(LimitedMtuTestWriter); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/mock_clock.h b/net/third_party/quic/test_tools/mock_clock.h index 3eba3c8..8c94e9a 100644 --- a/net/third_party/quic/test_tools/mock_clock.h +++ b/net/third_party/quic/test_tools/mock_clock.h
@@ -16,6 +16,8 @@ class MockClock : public QuicClock { public: MockClock(); + MockClock(const MockClock&) = delete; + MockClock& operator=(const MockClock&) = delete; ~MockClock() override; // QuicClock implementation: @@ -31,8 +33,6 @@ private: QuicTime now_; - - DISALLOW_COPY_AND_ASSIGN(MockClock); }; } // namespace quic
diff --git a/net/third_party/quic/test_tools/mock_crypto_client_stream.cc b/net/third_party/quic/test_tools/mock_crypto_client_stream.cc index 61b0209..ce761ec3 100644 --- a/net/third_party/quic/test_tools/mock_crypto_client_stream.cc +++ b/net/third_party/quic/test_tools/mock_crypto_client_stream.cc
@@ -8,7 +8,7 @@ #include "net/third_party/quic/core/crypto/null_encrypter.h" #include "net/third_party/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quic/core/crypto/quic_encrypter.h" -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quic/test_tools/mock_decrypter.h" #include "net/third_party/quic/test_tools/mock_encrypter.h"
diff --git a/net/third_party/quic/test_tools/mock_crypto_client_stream.h b/net/third_party/quic/test_tools/mock_crypto_client_stream.h index e258be1..61cbd42 100644 --- a/net/third_party/quic/test_tools/mock_crypto_client_stream.h +++ b/net/third_party/quic/test_tools/mock_crypto_client_stream.h
@@ -11,10 +11,10 @@ #include "net/quic/chromium/crypto/proof_verifier_chromium.h" #include "net/third_party/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quic/core/crypto/crypto_protocol.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h" #include "net/third_party/quic/core/quic_crypto_client_stream.h" #include "net/third_party/quic/core/quic_server_id.h" #include "net/third_party/quic/core/quic_session.h" -#include "net/third_party/quic/core/quic_spdy_client_session_base.h" namespace quic {
diff --git a/net/third_party/quic/test_tools/mock_quic_client_promised_info.h b/net/third_party/quic/test_tools/mock_quic_client_promised_info.h index e52acd06..20cfbac 100644 --- a/net/third_party/quic/test_tools/mock_quic_client_promised_info.h +++ b/net/third_party/quic/test_tools/mock_quic_client_promised_info.h
@@ -8,7 +8,7 @@ #include <string> #include "base/macros.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" #include "net/third_party/quic/core/quic_packets.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/net/third_party/quic/test_tools/mock_quic_dispatcher.h b/net/third_party/quic/test_tools/mock_quic_dispatcher.h index d6637f9..03096371 100644 --- a/net/third_party/quic/test_tools/mock_quic_dispatcher.h +++ b/net/third_party/quic/test_tools/mock_quic_dispatcher.h
@@ -26,6 +26,8 @@ std::unique_ptr<QuicCryptoServerStream::Helper> session_helper, std::unique_ptr<QuicAlarmFactory> alarm_factory, QuicSimpleServerBackend* quic_simple_server_backend); + MockQuicDispatcher(const MockQuicDispatcher&) = delete; + MockQuicDispatcher& operator=(const MockQuicDispatcher&) = delete; ~MockQuicDispatcher() override; @@ -33,9 +35,6 @@ void(const QuicSocketAddress& server_address, const QuicSocketAddress& client_address, const QuicReceivedPacket& packet)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockQuicDispatcher); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/mock_quic_session_visitor.h b/net/third_party/quic/test_tools/mock_quic_session_visitor.h index 3ac911b3..b207375c 100644 --- a/net/third_party/quic/test_tools/mock_quic_session_visitor.h +++ b/net/third_party/quic/test_tools/mock_quic_session_visitor.h
@@ -16,6 +16,8 @@ class MockQuicSessionVisitor : public QuicTimeWaitListManager::Visitor { public: MockQuicSessionVisitor(); + MockQuicSessionVisitor(const MockQuicSessionVisitor&) = delete; + MockQuicSessionVisitor& operator=(const MockQuicSessionVisitor&) = delete; ~MockQuicSessionVisitor() override; MOCK_METHOD3(OnConnectionClosed, void(QuicConnectionId connection_id, @@ -26,14 +28,15 @@ MOCK_METHOD1(OnRstStreamReceived, void(const QuicRstStreamFrame& frame)); MOCK_METHOD1(OnConnectionAddedToTimeWaitList, void(QuicConnectionId connection_id)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockQuicSessionVisitor); }; class MockQuicCryptoServerStreamHelper : public QuicCryptoServerStream::Helper { public: MockQuicCryptoServerStreamHelper(); + MockQuicCryptoServerStreamHelper(const MockQuicCryptoServerStreamHelper&) = + delete; + MockQuicCryptoServerStreamHelper& operator=( + const MockQuicCryptoServerStreamHelper&) = delete; ~MockQuicCryptoServerStreamHelper() override; MOCK_CONST_METHOD1(GenerateConnectionIdForReject, QuicConnectionId(QuicConnectionId connection_id)); @@ -43,9 +46,6 @@ const QuicSocketAddress& peer_address, const QuicSocketAddress& self_address, QuicString* error_details)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStreamHelper); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/mock_quic_spdy_client_stream.h b/net/third_party/quic/test_tools/mock_quic_spdy_client_stream.h index e1c8531..6a0a4d89 100644 --- a/net/third_party/quic/test_tools/mock_quic_spdy_client_stream.h +++ b/net/third_party/quic/test_tools/mock_quic_spdy_client_stream.h
@@ -6,9 +6,9 @@ #define NET_THIRD_PARTY_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_ #include "base/macros.h" -#include "net/third_party/quic/core/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" #include "net/third_party/quic/core/quic_packets.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" #include "testing/gmock/include/gmock/gmock.h" namespace quic {
diff --git a/net/third_party/quic/test_tools/mock_random.h b/net/third_party/quic/test_tools/mock_random.h index 090bab6a..727c8240 100644 --- a/net/third_party/quic/test_tools/mock_random.h +++ b/net/third_party/quic/test_tools/mock_random.h
@@ -17,6 +17,8 @@ // Initializes base_ to 0xDEADBEEF. MockRandom(); explicit MockRandom(uint32_t base); + MockRandom(const MockRandom&) = delete; + MockRandom& operator=(const MockRandom&) = delete; // QuicRandom: // Fills the |data| buffer with a repeating byte, initially 'r'. @@ -31,8 +33,6 @@ private: uint32_t base_; uint8_t increment_; - - DISALLOW_COPY_AND_ASSIGN(MockRandom); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/packet_dropping_test_writer.h b/net/third_party/quic/test_tools/packet_dropping_test_writer.h index a9c29c3..e4c47ed 100644 --- a/net/third_party/quic/test_tools/packet_dropping_test_writer.h +++ b/net/third_party/quic/test_tools/packet_dropping_test_writer.h
@@ -37,6 +37,8 @@ }; PacketDroppingTestWriter(); + PacketDroppingTestWriter(const PacketDroppingTestWriter&) = delete; + PacketDroppingTestWriter& operator=(const PacketDroppingTestWriter&) = delete; ~PacketDroppingTestWriter() override; @@ -138,6 +140,8 @@ const QuicSocketAddress& peer_address, std::unique_ptr<PerPacketOptions> options, QuicTime send_time); + DelayedWrite(const DelayedWrite&) = delete; + DelayedWrite& operator=(const DelayedWrite&) = delete; // TODO(rtenneti): on windows RValue reference gives errors. DelayedWrite(DelayedWrite&& other); // TODO(rtenneti): on windows RValue reference gives errors. @@ -149,9 +153,6 @@ const QuicSocketAddress peer_address; std::unique_ptr<PerPacketOptions> options; QuicTime send_time; - - private: - DISALLOW_COPY_AND_ASSIGN(DelayedWrite); }; typedef std::list<DelayedWrite> DelayedPacketList; @@ -175,8 +176,6 @@ QuicBandwidth fake_bandwidth_ GUARDED_BY(config_mutex_); QuicByteCount buffer_size_ GUARDED_BY(config_mutex_); int32_t num_consecutive_packet_lost_ GUARDED_BY(config_mutex_); - - DISALLOW_COPY_AND_ASSIGN(PacketDroppingTestWriter); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_buffered_packet_store_peer.h b/net/third_party/quic/test_tools/quic_buffered_packet_store_peer.h index f2ee116..5450b48 100644 --- a/net/third_party/quic/test_tools/quic_buffered_packet_store_peer.h +++ b/net/third_party/quic/test_tools/quic_buffered_packet_store_peer.h
@@ -18,12 +18,11 @@ class QuicBufferedPacketStorePeer { public: + QuicBufferedPacketStorePeer() = delete; + static QuicAlarm* expiration_alarm(QuicBufferedPacketStore* store); static void set_clock(QuicBufferedPacketStore* store, const QuicClock* clock); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicBufferedPacketStorePeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_client_peer.h b/net/third_party/quic/test_tools/quic_client_peer.h index c0061062..59d2d6e 100644 --- a/net/third_party/quic/test_tools/quic_client_peer.h +++ b/net/third_party/quic/test_tools/quic_client_peer.h
@@ -16,13 +16,12 @@ class QuicClientPeer { public: + QuicClientPeer() = delete; + static bool CreateUDPSocketAndBind(QuicClient* client); static void CleanUpUDPSocket(QuicClient* client, int fd); static void SetClientPort(QuicClient* client, int port); static void SetWriter(QuicClient* client, QuicPacketWriter* writer); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicClientPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_client_promised_info_peer.h b/net/third_party/quic/test_tools/quic_client_promised_info_peer.h index d169531..693904e 100644 --- a/net/third_party/quic/test_tools/quic_client_promised_info_peer.h +++ b/net/third_party/quic/test_tools/quic_client_promised_info_peer.h
@@ -6,17 +6,16 @@ #define NET_THIRD_PARTY_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_ #include "base/macros.h" -#include "net/third_party/quic/core/quic_client_promised_info.h" +#include "net/third_party/quic/core/http/quic_client_promised_info.h" namespace quic { namespace test { class QuicClientPromisedInfoPeer { public: - static QuicAlarm* GetAlarm(QuicClientPromisedInfo* promised_stream); + QuicClientPromisedInfoPeer() = delete; - private: - DISALLOW_COPY_AND_ASSIGN(QuicClientPromisedInfoPeer); + static QuicAlarm* GetAlarm(QuicClientPromisedInfo* promised_stream); }; } // namespace test } // namespace quic
diff --git a/net/third_party/quic/test_tools/quic_config_peer.h b/net/third_party/quic/test_tools/quic_config_peer.h index 33a802d..2164fd30 100644 --- a/net/third_party/quic/test_tools/quic_config_peer.h +++ b/net/third_party/quic/test_tools/quic_config_peer.h
@@ -18,6 +18,8 @@ class QuicConfigPeer { public: + QuicConfigPeer() = delete; + static void SetReceivedInitialStreamFlowControlWindow(QuicConfig* config, uint32_t window_bytes); @@ -40,9 +42,6 @@ static void SetReceivedStatelessResetToken(QuicConfig* config, QuicUint128 token); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicConfigPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_connection_peer.h b/net/third_party/quic/test_tools/quic_connection_peer.h index fe43104..b5ad7ae 100644 --- a/net/third_party/quic/test_tools/quic_connection_peer.h +++ b/net/third_party/quic/test_tools/quic_connection_peer.h
@@ -31,6 +31,8 @@ // Peer to make public a number of otherwise private QuicConnection methods. class QuicConnectionPeer { public: + QuicConnectionPeer() = delete; + static void SendAck(QuicConnection* connection); static void SetSendAlgorithm(QuicConnection* connection, @@ -128,9 +130,6 @@ QuicPacketCount max_tracked_packets); static void SetSessionDecidesWhatToWrite(QuicConnection* connection); static void SetNegotiatedVersion(QuicConnection* connection); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicConnectionPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_dispatcher_peer.h b/net/third_party/quic/test_tools/quic_dispatcher_peer.h index b97aa8f2..7494d32 100644 --- a/net/third_party/quic/test_tools/quic_dispatcher_peer.h +++ b/net/third_party/quic/test_tools/quic_dispatcher_peer.h
@@ -16,6 +16,8 @@ class QuicDispatcherPeer { public: + QuicDispatcherPeer() = delete; + static void SetTimeWaitListManager( QuicDispatcher* dispatcher, QuicTimeWaitListManager* time_wait_list_manager); @@ -60,9 +62,6 @@ static void RestorePerPacketContext( QuicDispatcher* dispatcher, std::unique_ptr<QuicDispatcher::PerPacketContext>); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicDispatcherPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_flow_controller_peer.h b/net/third_party/quic/test_tools/quic_flow_controller_peer.h index f423f36..2f99b28 100644 --- a/net/third_party/quic/test_tools/quic_flow_controller_peer.h +++ b/net/third_party/quic/test_tools/quic_flow_controller_peer.h
@@ -16,6 +16,8 @@ class QuicFlowControllerPeer { public: + QuicFlowControllerPeer() = delete; + static void SetSendWindowOffset(QuicFlowController* flow_controller, QuicStreamOffset offset); @@ -36,9 +38,6 @@ static QuicByteCount WindowUpdateThreshold( QuicFlowController* flow_controller); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicFlowControllerPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_framer_peer.h b/net/third_party/quic/test_tools/quic_framer_peer.h index 71255db..d7903bb 100644 --- a/net/third_party/quic/test_tools/quic_framer_peer.h +++ b/net/third_party/quic/test_tools/quic_framer_peer.h
@@ -16,6 +16,8 @@ class QuicFramerPeer { public: + QuicFramerPeer() = delete; + static QuicPacketNumber CalculatePacketNumberFromWire( QuicFramer* framer, QuicPacketNumberLength packet_number_length, @@ -147,9 +149,6 @@ const QuicFrame& frame, bool last_frame_in_packet, QuicPacketNumberLength packet_number_length); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicFramerPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_packet_creator_peer.h b/net/third_party/quic/test_tools/quic_packet_creator_peer.h index a94cf8d0..35a4f869 100644 --- a/net/third_party/quic/test_tools/quic_packet_creator_peer.h +++ b/net/third_party/quic/test_tools/quic_packet_creator_peer.h
@@ -16,6 +16,8 @@ class QuicPacketCreatorPeer { public: + QuicPacketCreatorPeer() = delete; + static bool SendVersionInPacket(QuicPacketCreator* creator); static void SetSendVersionInPacket(QuicPacketCreator* creator, @@ -43,9 +45,6 @@ QuicPacketCreator* creator); static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator); static QuicFramer* framer(QuicPacketCreator* creator); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicPacketCreatorPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_packet_generator_peer.h b/net/third_party/quic/test_tools/quic_packet_generator_peer.h index fbf853b1..d9f22a5 100644 --- a/net/third_party/quic/test_tools/quic_packet_generator_peer.h +++ b/net/third_party/quic/test_tools/quic_packet_generator_peer.h
@@ -17,10 +17,9 @@ class QuicPacketGeneratorPeer { public: - static QuicPacketCreator* GetPacketCreator(QuicPacketGenerator* generator); + QuicPacketGeneratorPeer() = delete; - private: - DISALLOW_COPY_AND_ASSIGN(QuicPacketGeneratorPeer); + static QuicPacketCreator* GetPacketCreator(QuicPacketGenerator* generator); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h b/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h index b75b195a..4aa02b8 100644 --- a/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h +++ b/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -17,6 +17,8 @@ class QuicSentPacketManagerPeer { public: + QuicSentPacketManagerPeer() = delete; + static size_t GetMaxTailLossProbes( QuicSentPacketManager* sent_packet_manager); @@ -104,9 +106,6 @@ static void SetNextPacedPacketTime(QuicSentPacketManager* sent_packet_manager, QuicTime time); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManagerPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_server_peer.h b/net/third_party/quic/test_tools/quic_server_peer.h index 5759a3b..bf4bff5 100644 --- a/net/third_party/quic/test_tools/quic_server_peer.h +++ b/net/third_party/quic/test_tools/quic_server_peer.h
@@ -17,12 +17,11 @@ class QuicServerPeer { public: + QuicServerPeer() = delete; + static bool SetSmallSocket(QuicServer* server); static QuicDispatcher* GetDispatcher(QuicServer* server); static void SetReader(QuicServer* server, QuicPacketReader* reader); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicServerPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_session_peer.h b/net/third_party/quic/test_tools/quic_session_peer.h index a3a57310..e0e510c 100644 --- a/net/third_party/quic/test_tools/quic_session_peer.h +++ b/net/third_party/quic/test_tools/quic_session_peer.h
@@ -25,6 +25,8 @@ class QuicSessionPeer { public: + QuicSessionPeer() = delete; + static QuicStreamId GetNextOutgoingStreamId(QuicSession* session); static void SetNextOutgoingStreamId(QuicSession* session, QuicStreamId id); static void SetMaxOpenIncomingStreams(QuicSession* session, @@ -55,9 +57,6 @@ static QuicStream* GetStream(QuicSession* session, QuicStreamId id); static bool IsStreamWriteBlocked(QuicSession* session, QuicStreamId id); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicSessionPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_spdy_session_peer.cc b/net/third_party/quic/test_tools/quic_spdy_session_peer.cc index ae763a14..60b0359 100644 --- a/net/third_party/quic/test_tools/quic_spdy_session_peer.cc +++ b/net/third_party/quic/test_tools/quic_spdy_session_peer.cc
@@ -4,7 +4,7 @@ #include "net/third_party/quic/test_tools/quic_spdy_session_peer.h" -#include "net/third_party/quic/core/quic_spdy_session.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" namespace quic { namespace test {
diff --git a/net/third_party/quic/test_tools/quic_spdy_session_peer.h b/net/third_party/quic/test_tools/quic_spdy_session_peer.h index c98986b8..488300d 100644 --- a/net/third_party/quic/test_tools/quic_spdy_session_peer.h +++ b/net/third_party/quic/test_tools/quic_spdy_session_peer.h
@@ -20,6 +20,8 @@ class QuicSpdySessionPeer { public: + QuicSpdySessionPeer() = delete; + static QuicHeadersStream* GetHeadersStream(QuicSpdySession* session); static void SetHeadersStream(QuicSpdySession* session, QuicHeadersStream* headers_stream); @@ -54,9 +56,6 @@ static QuicStreamId GetNthServerInitiatedStreamId( const QuicSpdySession& session, int n); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicSpdySessionPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_spdy_stream_peer.cc b/net/third_party/quic/test_tools/quic_spdy_stream_peer.cc deleted file mode 100644 index a491cf5..0000000 --- a/net/third_party/quic/test_tools/quic_spdy_stream_peer.cc +++ /dev/null
@@ -1,7 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/third_party/quic/test_tools/quic_spdy_stream_peer.h" - -#include "net/third_party/quic/core/quic_spdy_stream.h"
diff --git a/net/third_party/quic/test_tools/quic_spdy_stream_peer.h b/net/third_party/quic/test_tools/quic_spdy_stream_peer.h deleted file mode 100644 index 88cb151e..0000000 --- a/net/third_party/quic/test_tools/quic_spdy_stream_peer.h +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_THIRD_PARTY_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_ -#define NET_THIRD_PARTY_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_ - -#include "base/macros.h" - -namespace quic { - -namespace test { - -class QuicSpdyStreamPeer { - public: - private: - DISALLOW_COPY_AND_ASSIGN(QuicSpdyStreamPeer); -}; - -} // namespace test - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
diff --git a/net/third_party/quic/test_tools/quic_stream_peer.h b/net/third_party/quic/test_tools/quic_stream_peer.h index fad55440..407aeb7 100644 --- a/net/third_party/quic/test_tools/quic_stream_peer.h +++ b/net/third_party/quic/test_tools/quic_stream_peer.h
@@ -22,6 +22,8 @@ class QuicStreamPeer { public: + QuicStreamPeer() = delete; + static void SetWriteSideClosed(bool value, QuicStream* stream); static void SetStreamBytesWritten(QuicStreamOffset stream_bytes_written, QuicStream* stream); @@ -49,9 +51,6 @@ static void set_ack_listener( QuicStream* stream, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicStreamPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_stream_sequencer_buffer_peer.h b/net/third_party/quic/test_tools/quic_stream_sequencer_buffer_peer.h index 7937766..7e4def1 100644 --- a/net/third_party/quic/test_tools/quic_stream_sequencer_buffer_peer.h +++ b/net/third_party/quic/test_tools/quic_stream_sequencer_buffer_peer.h
@@ -14,6 +14,9 @@ class QuicStreamSequencerBufferPeer { public: explicit QuicStreamSequencerBufferPeer(QuicStreamSequencerBuffer* buffer); + QuicStreamSequencerBufferPeer(const QuicStreamSequencerBufferPeer&) = delete; + QuicStreamSequencerBufferPeer& operator=( + const QuicStreamSequencerBufferPeer&) = delete; // Read from this buffer_ into the given destination buffer_ up to the // size of the destination. Returns the number of bytes read. Reading from @@ -52,7 +55,6 @@ private: QuicStreamSequencerBuffer* buffer_; - DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencerBufferPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_stream_sequencer_peer.h b/net/third_party/quic/test_tools/quic_stream_sequencer_peer.h index aa97588d..67ef054 100644 --- a/net/third_party/quic/test_tools/quic_stream_sequencer_peer.h +++ b/net/third_party/quic/test_tools/quic_stream_sequencer_peer.h
@@ -16,6 +16,8 @@ class QuicStreamSequencerPeer { public: + QuicStreamSequencerPeer() = delete; + static size_t GetNumBufferedBytes(QuicStreamSequencer* sequencer); static QuicStreamOffset GetCloseOffset(QuicStreamSequencer* sequencer); @@ -24,9 +26,6 @@ static void SetFrameBufferTotalBytesRead(QuicStreamSequencer* sequencer, QuicStreamOffset total_bytes_read); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencerPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h b/net/third_party/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h index e398b7d..355237a 100644 --- a/net/third_party/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h +++ b/net/third_party/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
@@ -18,6 +18,8 @@ class QuicSustainedBandwidthRecorderPeer { public: + QuicSustainedBandwidthRecorderPeer() = delete; + static void SetBandwidthEstimate( QuicSustainedBandwidthRecorder* bandwidth_recorder, int32_t bandwidth_estimate_kbytes_per_second); @@ -26,9 +28,6 @@ QuicSustainedBandwidthRecorder* bandwidth_recorder, int32_t max_bandwidth_estimate_kbytes_per_second, int32_t max_bandwidth_timestamp); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicSustainedBandwidthRecorderPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_test_client.cc b/net/third_party/quic/test_tools/quic_test_client.cc index 38f3f3c..10bb8ea2 100644 --- a/net/third_party/quic/test_tools/quic_test_client.cc +++ b/net/third_party/quic/test_tools/quic_test_client.cc
@@ -9,12 +9,12 @@ #include <vector> #include "net/third_party/quic/core/crypto/proof_verifier.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_epoll_connection_helper.h" #include "net/third_party/quic/core/quic_packet_writer_wrapper.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" #include "net/third_party/quic/core/quic_utils.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h"
diff --git a/net/third_party/quic/test_tools/quic_test_client.h b/net/third_party/quic/test_tools/quic_test_client.h index 4c09e07..903c7e7 100644 --- a/net/third_party/quic/test_tools/quic_test_client.h +++ b/net/third_party/quic/test_tools/quic_test_client.h
@@ -49,6 +49,8 @@ const ParsedQuicVersionVector& supported_versions, net::EpollServer* epoll_server, std::unique_ptr<ProofVerifier> proof_verifier); + MockableQuicClient(const MockableQuicClient&) = delete; + MockableQuicClient& operator=(const MockableQuicClient&) = delete; ~MockableQuicClient() override; @@ -69,8 +71,6 @@ private: QuicConnectionId override_connection_id_; // ConnectionId to use, if nonzero CachedNetworkParameters cached_network_paramaters_; - - DISALLOW_COPY_AND_ASSIGN(MockableQuicClient); }; // A toy QUIC client used for testing. @@ -318,6 +318,8 @@ protected: QuicTestClient(); + QuicTestClient(const QuicTestClient&) = delete; + QuicTestClient& operator=(const QuicTestClient&) = delete; private: class TestClientDataToResend : public QuicClient::QuicDataToResend { @@ -395,8 +397,6 @@ // logic which extracts the SNI from the request URL. bool override_sni_set_ = false; QuicString override_sni_; - - DISALLOW_COPY_AND_ASSIGN(QuicTestClient); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/quic_test_utils.h b/net/third_party/quic/test_tools/quic_test_utils.h index ef0d0fb..231d60ba 100644 --- a/net/third_party/quic/test_tools/quic_test_utils.h +++ b/net/third_party/quic/test_tools/quic_test_utils.h
@@ -18,12 +18,12 @@ #include "net/test/gtest_util.h" #include "net/third_party/quic/core/congestion_control/loss_detection_interface.h" #include "net/third_party/quic/core/congestion_control/send_algorithm_interface.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_server_session_base.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_connection_close_delegate_interface.h" #include "net/third_party/quic/core/quic_framer.h" #include "net/third_party/quic/core/quic_sent_packet_manager.h" -#include "net/third_party/quic/core/quic_server_session_base.h" #include "net/third_party/quic/core/quic_simple_buffer_allocator.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" @@ -218,6 +218,8 @@ class SimpleRandom : public QuicRandom { public: SimpleRandom() : seed_(0) {} + SimpleRandom(const SimpleRandom&) = delete; + SimpleRandom& operator=(const SimpleRandom&) = delete; ~SimpleRandom() override {} // Returns a random number in the range [0, kuint64max]. @@ -229,13 +231,13 @@ private: uint64_t seed_; - - DISALLOW_COPY_AND_ASSIGN(SimpleRandom); }; class MockFramerVisitor : public QuicFramerVisitorInterface { public: MockFramerVisitor(); + MockFramerVisitor(const MockFramerVisitor&) = delete; + MockFramerVisitor& operator=(const MockFramerVisitor&) = delete; ~MockFramerVisitor() override; MOCK_METHOD1(OnError, void(QuicFramer* framer)); @@ -278,14 +280,13 @@ MOCK_CONST_METHOD1(IsValidStatelessResetToken, bool(QuicUint128)); MOCK_METHOD1(OnAuthenticatedIetfStatelessResetPacket, void(const QuicIetfStatelessResetPacket&)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockFramerVisitor); }; class NoOpFramerVisitor : public QuicFramerVisitorInterface { public: NoOpFramerVisitor() {} + NoOpFramerVisitor(const NoOpFramerVisitor&) = delete; + NoOpFramerVisitor& operator=(const NoOpFramerVisitor&) = delete; void OnError(QuicFramer* framer) override {} void OnPacket() override {} @@ -322,14 +323,14 @@ bool IsValidStatelessResetToken(QuicUint128 token) const override; void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& packet) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(NoOpFramerVisitor); }; class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface { public: MockQuicConnectionVisitor(); + MockQuicConnectionVisitor(const MockQuicConnectionVisitor&) = delete; + MockQuicConnectionVisitor& operator=(const MockQuicConnectionVisitor&) = + delete; ~MockQuicConnectionVisitor() override; MOCK_METHOD1(OnStreamFrame, void(const QuicStreamFrame& frame)); @@ -360,14 +361,13 @@ MOCK_METHOD0(SendPing, void()); MOCK_CONST_METHOD0(AllowSelfAddressChange, bool()); MOCK_METHOD0(OnForwardProgressConfirmed, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockQuicConnectionVisitor); }; class MockQuicConnectionHelper : public QuicConnectionHelperInterface { public: MockQuicConnectionHelper(); + MockQuicConnectionHelper(const MockQuicConnectionHelper&) = delete; + MockQuicConnectionHelper& operator=(const MockQuicConnectionHelper&) = delete; ~MockQuicConnectionHelper() override; const QuicClock* GetClock() const override; QuicRandom* GetRandomGenerator() override; @@ -378,8 +378,6 @@ MockClock clock_; MockRandom random_generator_; SimpleBufferAllocator buffer_allocator_; - - DISALLOW_COPY_AND_ASSIGN(MockQuicConnectionHelper); }; class MockAlarmFactory : public QuicAlarmFactory { @@ -437,6 +435,8 @@ MockAlarmFactory* alarm_factory, Perspective perspective, const ParsedQuicVersionVector& supported_versions); + MockQuicConnection(const MockQuicConnection&) = delete; + MockQuicConnection& operator=(const MockQuicConnection&) = delete; ~MockQuicConnection() override; @@ -505,9 +505,6 @@ return QuicConnection::SendConnectivityProbingPacket(probing_writer, peer_address); } - - private: - DISALLOW_COPY_AND_ASSIGN(MockQuicConnection); }; class PacketSavingConnection : public MockQuicConnection { @@ -520,15 +517,14 @@ MockAlarmFactory* alarm_factory, Perspective perspective, const ParsedQuicVersionVector& supported_versions); + PacketSavingConnection(const PacketSavingConnection&) = delete; + PacketSavingConnection& operator=(const PacketSavingConnection&) = delete; ~PacketSavingConnection() override; void SendOrQueuePacket(SerializedPacket* packet) override; std::vector<std::unique_ptr<QuicEncryptedPacket>> encrypted_packets_; - - private: - DISALLOW_COPY_AND_ASSIGN(PacketSavingConnection); }; class MockQuicSession : public QuicSession { @@ -538,6 +534,8 @@ // Takes ownership of |connection|. explicit MockQuicSession(QuicConnection* connection); + MockQuicSession(const MockQuicSession&) = delete; + MockQuicSession& operator=(const MockQuicSession&) = delete; ~MockQuicSession() override; QuicCryptoStream* GetMutableCryptoStream() override; @@ -584,8 +582,6 @@ private: std::unique_ptr<QuicCryptoStream> crypto_stream_; - - DISALLOW_COPY_AND_ASSIGN(MockQuicSession); }; class MockQuicCryptoStream : public QuicCryptoStream { @@ -613,6 +609,8 @@ // Takes ownership of |connection|. MockQuicSpdySession(QuicConnection* connection, bool create_mock_crypto_stream); + MockQuicSpdySession(const MockQuicSpdySession&) = delete; + MockQuicSpdySession& operator=(const MockQuicSpdySession&) = delete; ~MockQuicSpdySession() override; QuicCryptoStream* GetMutableCryptoStream() override; @@ -693,8 +691,6 @@ private: std::unique_ptr<QuicCryptoStream> crypto_stream_; spdy::SpdyHeaderBlock write_headers_; - - DISALLOW_COPY_AND_ASSIGN(MockQuicSpdySession); }; class TestQuicSpdyServerSession : public QuicServerSessionBase { @@ -704,6 +700,9 @@ const QuicConfig& config, const QuicCryptoServerConfig* crypto_config, QuicCompressedCertsCache* compressed_certs_cache); + TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete; + TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) = + delete; ~TestQuicSpdyServerSession() override; MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id)); @@ -724,8 +723,6 @@ private: MockQuicSessionVisitor visitor_; MockQuicCryptoServerStreamHelper helper_; - - DISALLOW_COPY_AND_ASSIGN(TestQuicSpdyServerSession); }; // A test implementation of QuicClientPushPromiseIndex::Delegate. @@ -756,6 +753,9 @@ const QuicConfig& config, const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config); + TestQuicSpdyClientSession(const TestQuicSpdyClientSession&) = delete; + TestQuicSpdyClientSession& operator=(const TestQuicSpdyClientSession&) = + delete; ~TestQuicSpdyClientSession() override; bool IsAuthorized(const QuicString& authority) override; @@ -780,13 +780,13 @@ private: std::unique_ptr<QuicCryptoClientStream> crypto_stream_; QuicClientPushPromiseIndex push_promise_index_; - - DISALLOW_COPY_AND_ASSIGN(TestQuicSpdyClientSession); }; class MockPacketWriter : public QuicPacketWriter { public: MockPacketWriter(); + MockPacketWriter(const MockPacketWriter&) = delete; + MockPacketWriter& operator=(const MockPacketWriter&) = delete; ~MockPacketWriter() override; MOCK_METHOD5(WritePacket, @@ -804,14 +804,13 @@ MOCK_CONST_METHOD0(IsBatchMode, bool()); MOCK_CONST_METHOD0(GetNextWriteLocation, char*()); MOCK_METHOD0(Flush, WriteResult()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockPacketWriter); }; class MockSendAlgorithm : public SendAlgorithmInterface { public: MockSendAlgorithm(); + MockSendAlgorithm(const MockSendAlgorithm&) = delete; + MockSendAlgorithm& operator=(const MockSendAlgorithm&) = delete; ~MockSendAlgorithm() override; MOCK_METHOD2(SetFromConfig, @@ -850,14 +849,13 @@ MOCK_CONST_METHOD0(GetCongestionControlType, CongestionControlType()); MOCK_METHOD2(AdjustNetworkParameters, void(QuicBandwidth, QuicTime::Delta)); MOCK_METHOD1(OnApplicationLimited, void(QuicByteCount)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockSendAlgorithm); }; class MockLossAlgorithm : public LossDetectionInterface { public: MockLossAlgorithm(); + MockLossAlgorithm(const MockLossAlgorithm&) = delete; + MockLossAlgorithm& operator=(const MockLossAlgorithm&) = delete; ~MockLossAlgorithm() override; MOCK_CONST_METHOD0(GetLossDetectionType, LossDetectionType()); @@ -873,14 +871,13 @@ QuicTime, const RttStats&, QuicPacketNumber)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockLossAlgorithm); }; class MockAckListener : public QuicAckListenerInterface { public: MockAckListener(); + MockAckListener(const MockAckListener&) = delete; + MockAckListener& operator=(const MockAckListener&) = delete; MOCK_METHOD2(OnPacketAcked, void(int acked_bytes, QuicTime::Delta ack_delay_time)); @@ -890,22 +887,18 @@ protected: // Object is ref counted. ~MockAckListener() override; - - private: - DISALLOW_COPY_AND_ASSIGN(MockAckListener); }; class MockNetworkChangeVisitor : public QuicSentPacketManager::NetworkChangeVisitor { public: MockNetworkChangeVisitor(); + MockNetworkChangeVisitor(const MockNetworkChangeVisitor&) = delete; + MockNetworkChangeVisitor& operator=(const MockNetworkChangeVisitor&) = delete; ~MockNetworkChangeVisitor() override; MOCK_METHOD0(OnCongestionChange, void()); MOCK_METHOD1(OnPathMtuIncreased, void(QuicPacketLength)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockNetworkChangeVisitor); }; class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor { @@ -990,6 +983,9 @@ class MockPacketCreatorDelegate : public QuicPacketCreator::DelegateInterface { public: MockPacketCreatorDelegate(); + MockPacketCreatorDelegate(const MockPacketCreatorDelegate&) = delete; + MockPacketCreatorDelegate& operator=(const MockPacketCreatorDelegate&) = + delete; ~MockPacketCreatorDelegate() override; MOCK_METHOD0(GetPacketBuffer, char*()); @@ -998,9 +994,6 @@ void(QuicErrorCode, const QuicString&, ConnectionCloseSource source)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockPacketCreatorDelegate); }; class MockSessionNotifier : public SessionNotifierInterface {
diff --git a/net/third_party/quic/test_tools/rtt_stats_peer.h b/net/third_party/quic/test_tools/rtt_stats_peer.h index b508c84..aba2f23 100644 --- a/net/third_party/quic/test_tools/rtt_stats_peer.h +++ b/net/third_party/quic/test_tools/rtt_stats_peer.h
@@ -14,12 +14,11 @@ class RttStatsPeer { public: + RttStatsPeer() = delete; + static void SetSmoothedRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms); static void SetMinRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms); - - private: - DISALLOW_COPY_AND_ASSIGN(RttStatsPeer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/server_thread.h b/net/third_party/quic/test_tools/server_thread.h index e75e64b..4046e8ac 100644 --- a/net/third_party/quic/test_tools/server_thread.h +++ b/net/third_party/quic/test_tools/server_thread.h
@@ -23,6 +23,8 @@ class ServerThread : public base::SimpleThread { public: ServerThread(QuicServer* server, const QuicSocketAddress& address); + ServerThread(const ServerThread&) = delete; + ServerThread& operator=(const ServerThread&) = delete; ~ServerThread() override; @@ -80,8 +82,6 @@ QuicMutex scheduled_actions_lock_; QuicDeque<std::function<void()>> scheduled_actions_ GUARDED_BY(scheduled_actions_lock_); - - DISALLOW_COPY_AND_ASSIGN(ServerThread); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/simple_quic_framer.cc b/net/third_party/quic/test_tools/simple_quic_framer.cc index 7d33411..c84585d 100644 --- a/net/third_party/quic/test_tools/simple_quic_framer.cc +++ b/net/third_party/quic/test_tools/simple_quic_framer.cc
@@ -18,6 +18,8 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { public: SimpleFramerVisitor() : error_(QUIC_NO_ERROR) {} + SimpleFramerVisitor(const SimpleFramerVisitor&) = delete; + SimpleFramerVisitor& operator=(const SimpleFramerVisitor&) = delete; ~SimpleFramerVisitor() override {} @@ -230,8 +232,6 @@ std::vector<QuicBlockedFrame> blocked_frames_; std::vector<QuicNewConnectionIdFrame> new_connection_id_frames_; std::vector<std::unique_ptr<QuicString>> stream_data_; - - DISALLOW_COPY_AND_ASSIGN(SimpleFramerVisitor); }; SimpleQuicFramer::SimpleQuicFramer()
diff --git a/net/third_party/quic/test_tools/simple_quic_framer.h b/net/third_party/quic/test_tools/simple_quic_framer.h index 886facd9..37d20f1 100644 --- a/net/third_party/quic/test_tools/simple_quic_framer.h +++ b/net/third_party/quic/test_tools/simple_quic_framer.h
@@ -27,6 +27,8 @@ explicit SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions); SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions, Perspective perspective); + SimpleQuicFramer(const SimpleQuicFramer&) = delete; + SimpleQuicFramer& operator=(const SimpleQuicFramer&) = delete; ~SimpleQuicFramer(); bool ProcessPacket(const QuicEncryptedPacket& packet); @@ -54,7 +56,6 @@ private: QuicFramer framer_; std::unique_ptr<SimpleFramerVisitor> visitor_; - DISALLOW_COPY_AND_ASSIGN(SimpleQuicFramer); }; } // namespace test
diff --git a/net/third_party/quic/test_tools/simulator/actor.h b/net/third_party/quic/test_tools/simulator/actor.h index d2698f7d..514e8f0 100644 --- a/net/third_party/quic/test_tools/simulator/actor.h +++ b/net/third_party/quic/test_tools/simulator/actor.h
@@ -55,9 +55,9 @@ // Since the Actor object registers itself with a simulator using a pointer to // itself, do not allow it to be moved. Actor(Actor&&) = delete; + Actor(const Actor&) = delete; + Actor& operator=(const Actor&) = delete; Actor& operator=(Actor&&) = delete; - - DISALLOW_COPY_AND_ASSIGN(Actor); }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/alarm_factory.h b/net/third_party/quic/test_tools/simulator/alarm_factory.h index d10cd47..33d7e099 100644 --- a/net/third_party/quic/test_tools/simulator/alarm_factory.h +++ b/net/third_party/quic/test_tools/simulator/alarm_factory.h
@@ -15,6 +15,8 @@ class AlarmFactory : public QuicAlarmFactory { public: AlarmFactory(Simulator* simulator, std::string name); + AlarmFactory(const AlarmFactory&) = delete; + AlarmFactory& operator=(const AlarmFactory&) = delete; ~AlarmFactory() override; QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override; @@ -29,8 +31,6 @@ Simulator* simulator_; std::string name_; int counter_; - - DISALLOW_COPY_AND_ASSIGN(AlarmFactory); }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/link.h b/net/third_party/quic/test_tools/simulator/link.h index 8636ee5..64dfabdc 100644 --- a/net/third_party/quic/test_tools/simulator/link.h +++ b/net/third_party/quic/test_tools/simulator/link.h
@@ -24,6 +24,8 @@ UnconstrainedPortInterface* sink, QuicBandwidth bandwidth, QuicTime::Delta propagation_delay); + OneWayLink(const OneWayLink&) = delete; + OneWayLink& operator=(const OneWayLink&) = delete; ~OneWayLink() override; void AcceptPacket(std::unique_ptr<Packet> packet) override; @@ -57,8 +59,6 @@ const QuicTime::Delta propagation_delay_; QuicTime next_write_at_; - - DISALLOW_COPY_AND_ASSIGN(OneWayLink); }; // A full-duplex link between two endpoints, functionally equivalent to two @@ -75,14 +75,14 @@ Endpoint* endpoint_b, QuicBandwidth bandwidth, QuicTime::Delta propagation_delay); + SymmetricLink(const SymmetricLink&) = delete; + SymmetricLink& operator=(const SymmetricLink&) = delete; inline QuicBandwidth bandwidth() { return a_to_b_link_.bandwidth(); } private: OneWayLink a_to_b_link_; OneWayLink b_to_a_link_; - - DISALLOW_COPY_AND_ASSIGN(SymmetricLink); }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/packet_filter.h b/net/third_party/quic/test_tools/simulator/packet_filter.h index 4c4878e3..e769db1 100644 --- a/net/third_party/quic/test_tools/simulator/packet_filter.h +++ b/net/third_party/quic/test_tools/simulator/packet_filter.h
@@ -40,6 +40,8 @@ // Initialize the filter by wrapping around |input|. Does not take the // ownership of |input|. PacketFilter(Simulator* simulator, std::string name, Endpoint* input); + PacketFilter(const PacketFilter&) = delete; + PacketFilter& operator=(const PacketFilter&) = delete; ~PacketFilter() override; // Implementation of ConstrainedPortInterface. @@ -66,8 +68,6 @@ // The original network endpoint wrapped by the class. Endpoint* input_; - - DISALLOW_COPY_AND_ASSIGN(PacketFilter); }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/queue.h b/net/third_party/quic/test_tools/simulator/queue.h index 2d57fee..e9641d30 100644 --- a/net/third_party/quic/test_tools/simulator/queue.h +++ b/net/third_party/quic/test_tools/simulator/queue.h
@@ -24,6 +24,8 @@ }; Queue(Simulator* simulator, std::string name, QuicByteCount capacity); + Queue(const Queue&) = delete; + Queue& operator=(const Queue&) = delete; ~Queue() override; void set_tx_port(ConstrainedPortInterface* port); @@ -110,8 +112,6 @@ QuicQueue<EnqueuedPacket> queue_; ListenerInterface* listener_; - - DISALLOW_COPY_AND_ASSIGN(Queue); }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/simulator.h b/net/third_party/quic/test_tools/simulator/simulator.h index ebb882c..a086eb2 100644 --- a/net/third_party/quic/test_tools/simulator/simulator.h +++ b/net/third_party/quic/test_tools/simulator/simulator.h
@@ -22,6 +22,8 @@ class Simulator : public QuicConnectionHelperInterface { public: Simulator(); + Simulator(const Simulator&) = delete; + Simulator& operator=(const Simulator&) = delete; ~Simulator() override; // Register an actor with the simulator. Returns a handle which the actor can @@ -125,8 +127,6 @@ // unscheduled actors is QuicTime::Infinite(). QuicUnorderedMap<Actor*, QuicTime> scheduled_times_; QuicUnorderedSet<std::string> actor_names_; - - DISALLOW_COPY_AND_ASSIGN(Simulator); }; template <class TerminationPredicate>
diff --git a/net/third_party/quic/test_tools/simulator/switch.h b/net/third_party/quic/test_tools/simulator/switch.h index f344a425..0b272f3 100644 --- a/net/third_party/quic/test_tools/simulator/switch.h +++ b/net/third_party/quic/test_tools/simulator/switch.h
@@ -23,6 +23,8 @@ std::string name, SwitchPortNumber port_count, QuicByteCount queue_capacity); + Switch(const Switch&) = delete; + Switch& operator=(const Switch&) = delete; ~Switch(); // Returns Endpoint associated with the port under number |port_number|. Just @@ -45,6 +47,8 @@ SwitchPortNumber port_number, QuicByteCount queue_capacity); Port(Port&&) = delete; + Port(const Port&) = delete; + Port& operator=(const Port&) = delete; ~Port() override {} // Accepts packet to be routed into the switch. @@ -66,8 +70,6 @@ bool connected_; Queue queue_; - - DISALLOW_COPY_AND_ASSIGN(Port); }; // Sends the packet to the appropriate port, or to all ports if the @@ -79,8 +81,6 @@ // assumed to be stable. std::deque<Port> ports_; QuicUnorderedMap<std::string, Port*> switching_table_; - - DISALLOW_COPY_AND_ASSIGN(Switch); }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/traffic_policer.h b/net/third_party/quic/test_tools/simulator/traffic_policer.h index 8e389de9..fd38fcf 100644 --- a/net/third_party/quic/test_tools/simulator/traffic_policer.h +++ b/net/third_party/quic/test_tools/simulator/traffic_policer.h
@@ -25,6 +25,8 @@ QuicByteCount max_bucket_size, QuicBandwidth target_bandwidth, Endpoint* input); + TrafficPolicer(const TrafficPolicer&) = delete; + TrafficPolicer& operator=(const TrafficPolicer&) = delete; ~TrafficPolicer() override; protected: @@ -44,8 +46,6 @@ // Maps each destination to the number of tokens it has left. QuicUnorderedMap<std::string, QuicByteCount> token_buckets_; - - DISALLOW_COPY_AND_ASSIGN(TrafficPolicer); }; } // namespace simulator
diff --git a/net/third_party/quic/tools/quic_backend_response.h b/net/third_party/quic/tools/quic_backend_response.h index 3d898f8..81698d0 100644 --- a/net/third_party/quic/tools/quic_backend_response.h +++ b/net/third_party/quic/tools/quic_backend_response.h
@@ -5,7 +5,7 @@ #ifndef NET_THIRD_PARTY_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_ #define NET_THIRD_PARTY_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_ -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_url.h" namespace quic {
diff --git a/net/third_party/quic/tools/quic_client.cc b/net/third_party/quic/tools/quic_client.cc index 97b3feec4..2b00375 100644 --- a/net/third_party/quic/tools/quic_client.cc +++ b/net/third_party/quic/tools/quic_client.cc
@@ -13,13 +13,13 @@ #include "base/run_loop.h" #include "net/third_party/quic/core/crypto/quic_random.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_data_reader.h" #include "net/third_party/quic/core/quic_epoll_alarm_factory.h" #include "net/third_party/quic/core/quic_epoll_connection_helper.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h"
diff --git a/net/third_party/quic/tools/quic_client.h b/net/third_party/quic/tools/quic_client.h index 14747f4..6778176 100644 --- a/net/third_party/quic/tools/quic_client.h +++ b/net/third_party/quic/tools/quic_client.h
@@ -14,12 +14,12 @@ #include "base/command_line.h" #include "base/macros.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/core/quic_config.h" #include "net/third_party/quic/core/quic_packet_reader.h" #include "net/third_party/quic/core/quic_process_packet_interface.h" -#include "net/third_party/quic/core/quic_spdy_client_session.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" #include "net/third_party/quic/platform/api/quic_containers.h" #include "net/third_party/quic/tools/quic_client_base.h" #include "net/third_party/quic/tools/quic_client_epoll_network_helper.h" @@ -56,6 +56,8 @@ net::EpollServer* epoll_server, std::unique_ptr<QuicClientEpollNetworkHelper> network_helper, std::unique_ptr<ProofVerifier> proof_verifier); + QuicClient(const QuicClient&) = delete; + QuicClient& operator=(const QuicClient&) = delete; ~QuicClient() override; @@ -75,8 +77,6 @@ private: friend class test::QuicClientPeer; bool drop_response_body_ = false; - - DISALLOW_COPY_AND_ASSIGN(QuicClient); }; } // namespace quic
diff --git a/net/third_party/quic/tools/quic_client_base.cc b/net/third_party/quic/tools/quic_client_base.cc index 8166c4e..8b7958d 100644 --- a/net/third_party/quic/tools/quic_client_base.cc +++ b/net/third_party/quic/tools/quic_client_base.cc
@@ -5,8 +5,8 @@ #include "net/third_party/quic/tools/quic_client_base.h" #include "net/third_party/quic/core/crypto/quic_random.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_logging.h"
diff --git a/net/third_party/quic/tools/quic_client_base.h b/net/third_party/quic/tools/quic_client_base.h index 4503085..e722180 100644 --- a/net/third_party/quic/tools/quic_client_base.h +++ b/net/third_party/quic/tools/quic_client_base.h
@@ -12,10 +12,10 @@ #include "base/macros.h" #include "net/third_party/quic/core/crypto/crypto_handshake.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" #include "net/third_party/quic/core/quic_config.h" -#include "net/third_party/quic/core/quic_spdy_client_session.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" #include "net/third_party/quic/platform/api/quic_socket_address.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" @@ -65,6 +65,8 @@ QuicAlarmFactory* alarm_factory, std::unique_ptr<NetworkHelper> network_helper, std::unique_ptr<ProofVerifier> proof_verifier); + QuicClientBase(const QuicClientBase&) = delete; + QuicClientBase& operator=(const QuicClientBase&) = delete; virtual ~QuicClientBase(); @@ -355,8 +357,6 @@ // The network helper used to create sockets and manage the event loop. // Not owned by this class. std::unique_ptr<NetworkHelper> network_helper_; - - DISALLOW_COPY_AND_ASSIGN(QuicClientBase); }; } // namespace quic
diff --git a/net/third_party/quic/tools/quic_client_epoll_network_helper.cc b/net/third_party/quic/tools/quic_client_epoll_network_helper.cc index ae144130..784282f 100644 --- a/net/third_party/quic/tools/quic_client_epoll_network_helper.cc +++ b/net/third_party/quic/tools/quic_client_epoll_network_helper.cc
@@ -13,13 +13,13 @@ #include "base/run_loop.h" #include "net/third_party/quic/core/crypto/quic_random.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_data_reader.h" #include "net/third_party/quic/core/quic_epoll_alarm_factory.h" #include "net/third_party/quic/core/quic_epoll_connection_helper.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h"
diff --git a/net/third_party/quic/tools/quic_client_epoll_network_helper.h b/net/third_party/quic/tools/quic_client_epoll_network_helper.h index 1b20afd..2a6d22e3 100644 --- a/net/third_party/quic/tools/quic_client_epoll_network_helper.h +++ b/net/third_party/quic/tools/quic_client_epoll_network_helper.h
@@ -14,12 +14,12 @@ #include "base/command_line.h" #include "base/macros.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/core/quic_config.h" #include "net/third_party/quic/core/quic_packet_reader.h" #include "net/third_party/quic/core/quic_process_packet_interface.h" -#include "net/third_party/quic/core/quic_spdy_client_session.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" #include "net/third_party/quic/platform/api/quic_containers.h" #include "net/third_party/quic/tools/quic_client_base.h" #include "net/third_party/quic/tools/quic_spdy_client_base.h" @@ -41,6 +41,9 @@ // net::EpollServer. QuicClientEpollNetworkHelper(net::EpollServer* epoll_server, QuicClientBase* client); + QuicClientEpollNetworkHelper(const QuicClientEpollNetworkHelper&) = delete; + QuicClientEpollNetworkHelper& operator=(const QuicClientEpollNetworkHelper&) = + delete; ~QuicClientEpollNetworkHelper() override; @@ -130,8 +133,6 @@ QuicClientBase* client_; int max_reads_per_epoll_loop_; - - DISALLOW_COPY_AND_ASSIGN(QuicClientEpollNetworkHelper); }; } // namespace quic
diff --git a/net/third_party/quic/tools/quic_memory_cache_backend.cc b/net/third_party/quic/tools/quic_memory_cache_backend.cc index f6825dd..167fbd93 100644 --- a/net/third_party/quic/tools/quic_memory_cache_backend.cc +++ b/net/third_party/quic/tools/quic_memory_cache_backend.cc
@@ -6,7 +6,7 @@ #include <utility> -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_file_utils.h" #include "net/third_party/quic/platform/api/quic_logging.h"
diff --git a/net/third_party/quic/tools/quic_memory_cache_backend.h b/net/third_party/quic/tools/quic_memory_cache_backend.h index 50d03423..ee605a4 100644 --- a/net/third_party/quic/tools/quic_memory_cache_backend.h +++ b/net/third_party/quic/tools/quic_memory_cache_backend.h
@@ -10,7 +10,7 @@ #include <memory> #include <vector> -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_containers.h" #include "net/third_party/quic/platform/api/quic_mutex.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" @@ -33,6 +33,8 @@ class ResourceFile { public: explicit ResourceFile(const QuicString& file_name); + ResourceFile(const ResourceFile&) = delete; + ResourceFile& operator=(const ResourceFile&) = delete; virtual ~ResourceFile(); void Read(); @@ -68,11 +70,11 @@ QuicStringPiece host_; QuicStringPiece path_; QuicMemoryCacheBackend* cache_; - - DISALLOW_COPY_AND_ASSIGN(ResourceFile); }; QuicMemoryCacheBackend(); + QuicMemoryCacheBackend(const QuicMemoryCacheBackend&) = delete; + QuicMemoryCacheBackend& operator=(const QuicMemoryCacheBackend&) = delete; ~QuicMemoryCacheBackend() override; // Retrieve a response from this cache for a given host and path.. @@ -184,8 +186,6 @@ // server threads accessing those responses. mutable QuicMutex response_mutex_; bool cache_initialized_; - - DISALLOW_COPY_AND_ASSIGN(QuicMemoryCacheBackend); }; } // namespace quic
diff --git a/net/third_party/quic/tools/quic_server.h b/net/third_party/quic/tools/quic_server.h index 1d5ffa1..322c4ab 100644 --- a/net/third_party/quic/tools/quic_server.h +++ b/net/third_party/quic/tools/quic_server.h
@@ -42,6 +42,8 @@ const QuicCryptoServerConfig::ConfigOptions& server_config_options, const ParsedQuicVersionVector& supported_versions, QuicSimpleServerBackend* quic_simple_server_backend); + QuicServer(const QuicServer&) = delete; + QuicServer& operator=(const QuicServer&) = delete; ~QuicServer() override; @@ -148,8 +150,6 @@ QuicSimpleServerBackend* quic_simple_server_backend_; // unowned. base::WeakPtrFactory<QuicServer> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(QuicServer); }; } // namespace quic
diff --git a/net/third_party/quic/tools/quic_simple_client_session.h b/net/third_party/quic/tools/quic_simple_client_session.h index 195b40a..05d9121 100644 --- a/net/third_party/quic/tools/quic_simple_client_session.h +++ b/net/third_party/quic/tools/quic_simple_client_session.h
@@ -5,7 +5,7 @@ #ifndef NET_THIRD_PARTY_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_ #define NET_THIRD_PARTY_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_ -#include "net/third_party/quic/core/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" #include "net/third_party/quic/tools/quic_simple_client_stream.h" namespace quic {
diff --git a/net/third_party/quic/tools/quic_simple_client_stream.h b/net/third_party/quic/tools/quic_simple_client_stream.h index d50c107..dc6abf4c 100644 --- a/net/third_party/quic/tools/quic_simple_client_stream.h +++ b/net/third_party/quic/tools/quic_simple_client_stream.h
@@ -5,7 +5,7 @@ #ifndef NET_THIRD_PARTY_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_ #define NET_THIRD_PARTY_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_ -#include "net/third_party/quic/core/quic_spdy_client_stream.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" namespace quic {
diff --git a/net/third_party/quic/tools/quic_simple_dispatcher.h b/net/third_party/quic/tools/quic_simple_dispatcher.h index fa460723..25414a1 100644 --- a/net/third_party/quic/tools/quic_simple_dispatcher.h +++ b/net/third_party/quic/tools/quic_simple_dispatcher.h
@@ -5,8 +5,8 @@ #ifndef NET_THIRD_PARTY_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_ #define NET_THIRD_PARTY_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_ +#include "net/third_party/quic/core/http/quic_server_session_base.h" #include "net/third_party/quic/core/quic_dispatcher.h" -#include "net/third_party/quic/core/quic_server_session_base.h" #include "net/third_party/quic/tools/quic_simple_server_backend.h" namespace quic {
diff --git a/net/third_party/quic/tools/quic_simple_server_session.h b/net/third_party/quic/tools/quic_simple_server_session.h index 423e433..2551bc43 100644 --- a/net/third_party/quic/tools/quic_simple_server_session.h +++ b/net/third_party/quic/tools/quic_simple_server_session.h
@@ -17,10 +17,10 @@ #include <vector> #include "base/macros.h" +#include "net/third_party/quic/core/http/quic_server_session_base.h" +#include "net/third_party/quic/core/http/quic_spdy_session.h" #include "net/third_party/quic/core/quic_crypto_server_stream.h" #include "net/third_party/quic/core/quic_packets.h" -#include "net/third_party/quic/core/quic_server_session_base.h" -#include "net/third_party/quic/core/quic_spdy_session.h" #include "net/third_party/quic/platform/api/quic_containers.h" #include "net/third_party/quic/tools/quic_backend_response.h" #include "net/third_party/quic/tools/quic_simple_server_backend.h" @@ -60,6 +60,8 @@ const QuicCryptoServerConfig* crypto_config, QuicCompressedCertsCache* compressed_certs_cache, QuicSimpleServerBackend* quic_simple_server_backend); + QuicSimpleServerSession(const QuicSimpleServerSession&) = delete; + QuicSimpleServerSession& operator=(const QuicSimpleServerSession&) = delete; ~QuicSimpleServerSession() override; @@ -149,8 +151,6 @@ QuicDeque<PromisedStreamInfo> promised_streams_; QuicSimpleServerBackend* quic_simple_server_backend_; // Not owned. - - DISALLOW_COPY_AND_ASSIGN(QuicSimpleServerSession); }; } // namespace quic
diff --git a/net/third_party/quic/tools/quic_simple_server_session_test.cc b/net/third_party/quic/tools/quic_simple_server_session_test.cc index 8352e96a..c9c76aa 100644 --- a/net/third_party/quic/tools/quic_simple_server_session_test.cc +++ b/net/third_party/quic/tools/quic_simple_server_session_test.cc
@@ -31,7 +31,6 @@ #include "net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h" #include "net/third_party/quic/test_tools/quic_session_peer.h" #include "net/third_party/quic/test_tools/quic_spdy_session_peer.h" -#include "net/third_party/quic/test_tools/quic_spdy_stream_peer.h" #include "net/third_party/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h" #include "net/third_party/quic/test_tools/quic_test_utils.h" @@ -88,7 +87,10 @@ enable_quic_stateless_reject_support), // NOLINT session, helper) {} - ~MockQuicCryptoServerStream() override = default; + MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete; + MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) = + delete; + ~MockQuicCryptoServerStream() override {} MOCK_METHOD1(SendServerConfigUpdate, void(const CachedNetworkParameters* cached_network_parameters)); @@ -104,8 +106,6 @@ private: bool encryption_established_override_ = false; - - DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); }; class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
diff --git a/net/third_party/quic/tools/quic_simple_server_stream.cc b/net/third_party/quic/tools/quic_simple_server_stream.cc index ee33460..eac3e0c 100644 --- a/net/third_party/quic/tools/quic_simple_server_stream.cc +++ b/net/third_party/quic/tools/quic_simple_server_stream.cc
@@ -7,8 +7,8 @@ #include <list> #include <utility> -#include "net/third_party/quic/core/quic_spdy_stream.h" -#include "net/third_party/quic/core/spdy_utils.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_logging.h"
diff --git a/net/third_party/quic/tools/quic_simple_server_stream.h b/net/third_party/quic/tools/quic_simple_server_stream.h index 8dd096a..226210b 100644 --- a/net/third_party/quic/tools/quic_simple_server_stream.h +++ b/net/third_party/quic/tools/quic_simple_server_stream.h
@@ -7,9 +7,9 @@ #include "base/macros.h" #include "net/http/http_response_headers.h" +#include "net/third_party/quic/core/http/quic_spdy_server_stream_base.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/core/quic_packets.h" -#include "net/third_party/quic/core/quic_spdy_server_stream_base.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/quic/tools/quic_backend_response.h" #include "net/third_party/quic/tools/quic_simple_server_backend.h" @@ -29,6 +29,8 @@ QuicSimpleServerStream(QuicStreamId id, QuicSpdySession* session, QuicSimpleServerBackend* quic_simple_server_backend); + QuicSimpleServerStream(const QuicSimpleServerStream&) = delete; + QuicSimpleServerStream& operator=(const QuicSimpleServerStream&) = delete; ~QuicSimpleServerStream() override; // QuicSpdyStream @@ -97,8 +99,6 @@ QuicString body_; QuicSimpleServerBackend* quic_simple_server_backend_; // Not owned. - - DISALLOW_COPY_AND_ASSIGN(QuicSimpleServerStream); }; } // namespace quic
diff --git a/net/third_party/quic/tools/quic_simple_server_stream_test.cc b/net/third_party/quic/tools/quic_simple_server_stream_test.cc index 771a7c4..8fcd565 100644 --- a/net/third_party/quic/tools/quic_simple_server_stream_test.cc +++ b/net/third_party/quic/tools/quic_simple_server_stream_test.cc
@@ -9,8 +9,8 @@ #include <utility> #include "net/test/gtest_util.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_utils.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/core/tls_server_handshaker.h" #include "net/third_party/quic/platform/api/quic_arraysize.h" #include "net/third_party/quic/platform/api/quic_expect_bug.h" @@ -103,6 +103,9 @@ .WillByDefault(testing::Return(QuicConsumedData(0, false))); } + MockQuicSimpleServerSession(const MockQuicSimpleServerSession&) = delete; + MockQuicSimpleServerSession& operator=(const MockQuicSimpleServerSession&) = + delete; ~MockQuicSimpleServerSession() override = default; MOCK_METHOD3(OnConnectionClosed, @@ -165,9 +168,6 @@ using QuicSession::ActivateStream; spdy::SpdyHeaderBlock original_request_headers_; - - private: - DISALLOW_COPY_AND_ASSIGN(MockQuicSimpleServerSession); }; class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
diff --git a/net/third_party/quic/tools/quic_spdy_client_base.cc b/net/third_party/quic/tools/quic_spdy_client_base.cc index 0d34d46..b88fd79 100644 --- a/net/third_party/quic/tools/quic_spdy_client_base.cc +++ b/net/third_party/quic/tools/quic_spdy_client_base.cc
@@ -5,8 +5,8 @@ #include "net/third_party/quic/tools/quic_spdy_client_base.h" #include "net/third_party/quic/core/crypto/quic_random.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h"
diff --git a/net/third_party/quic/tools/quic_spdy_client_base.h b/net/third_party/quic/tools/quic_spdy_client_base.h index c896447..edb2003 100644 --- a/net/third_party/quic/tools/quic_spdy_client_base.h +++ b/net/third_party/quic/tools/quic_spdy_client_base.h
@@ -12,10 +12,10 @@ #include "base/macros.h" #include "net/third_party/quic/core/crypto/crypto_handshake.h" -#include "net/third_party/quic/core/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_client_push_promise_index.h" +#include "net/third_party/quic/core/http/quic_spdy_client_session.h" +#include "net/third_party/quic/core/http/quic_spdy_client_stream.h" #include "net/third_party/quic/core/quic_config.h" -#include "net/third_party/quic/core/quic_spdy_client_session.h" -#include "net/third_party/quic/core/quic_spdy_client_stream.h" #include "net/third_party/quic/platform/api/quic_socket_address.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/quic/tools/quic_client_base.h" @@ -53,6 +53,8 @@ QuicDataToResend(std::unique_ptr<spdy::SpdyHeaderBlock> headers, QuicStringPiece body, bool fin); + QuicDataToResend(const QuicDataToResend&) = delete; + QuicDataToResend& operator=(const QuicDataToResend&) = delete; virtual ~QuicDataToResend(); @@ -64,9 +66,6 @@ std::unique_ptr<spdy::SpdyHeaderBlock> headers_; QuicStringPiece body_; bool fin_; - - private: - DISALLOW_COPY_AND_ASSIGN(QuicDataToResend); }; QuicSpdyClientBase(const QuicServerId& server_id, @@ -76,6 +75,8 @@ QuicAlarmFactory* alarm_factory, std::unique_ptr<NetworkHelper> network_helper, std::unique_ptr<ProofVerifier> proof_verifier); + QuicSpdyClientBase(const QuicSpdyClientBase&) = delete; + QuicSpdyClientBase& operator=(const QuicSpdyClientBase&) = delete; ~QuicSpdyClientBase() override; @@ -171,14 +172,14 @@ DCHECK(client); } + ClientQuicDataToResend(const ClientQuicDataToResend&) = delete; + ClientQuicDataToResend& operator=(const ClientQuicDataToResend&) = delete; ~ClientQuicDataToResend() override {} void Resend() override; private: QuicSpdyClientBase* client_; - - DISALLOW_COPY_AND_ASSIGN(ClientQuicDataToResend); }; // Index of pending promised streams. Must outlive |session_|. @@ -207,8 +208,6 @@ std::vector<std::unique_ptr<QuicDataToResend>> data_to_resend_on_connect_; std::unique_ptr<ClientQuicDataToResend> push_promise_data_to_resend_; - - DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientBase); }; } // namespace quic
diff --git a/net/tools/quic/quic_client_message_loop_network_helper.cc b/net/tools/quic/quic_client_message_loop_network_helper.cc index c6154de..25a00eb 100644 --- a/net/tools/quic/quic_client_message_loop_network_helper.cc +++ b/net/tools/quic/quic_client_message_loop_network_helper.cc
@@ -21,10 +21,10 @@ #include "net/socket/udp_client_socket.h" #include "net/spdy/spdy_http_utils.h" #include "net/third_party/quic/core/crypto/quic_random.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/spdy/core/spdy_header_block.h"
diff --git a/net/tools/quic/quic_client_message_loop_network_helper.h b/net/tools/quic/quic_client_message_loop_network_helper.h index a41f7fd3..a4e7d42 100644 --- a/net/tools/quic/quic_client_message_loop_network_helper.h +++ b/net/tools/quic/quic_client_message_loop_network_helper.h
@@ -20,8 +20,8 @@ #include "net/http/http_response_headers.h" #include "net/log/net_log.h" #include "net/quic/chromium/quic_chromium_packet_reader.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/core/quic_config.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" #include "net/third_party/quic/platform/impl/quic_chromium_clock.h" #include "net/third_party/quic/tools/quic_spdy_client_base.h"
diff --git a/net/tools/quic/quic_simple_client.cc b/net/tools/quic/quic_simple_client.cc index ac17ee6c..d743f723 100644 --- a/net/tools/quic/quic_simple_client.cc +++ b/net/tools/quic/quic_simple_client.cc
@@ -21,10 +21,10 @@ #include "net/socket/udp_client_socket.h" #include "net/spdy/spdy_http_utils.h" #include "net/third_party/quic/core/crypto/quic_random.h" +#include "net/third_party/quic/core/http/spdy_utils.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_server_id.h" -#include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/spdy/core/spdy_header_block.h"
diff --git a/net/tools/quic/quic_simple_client.h b/net/tools/quic/quic_simple_client.h index d9144b36..4d73cda8 100644 --- a/net/tools/quic/quic_simple_client.h +++ b/net/tools/quic/quic_simple_client.h
@@ -20,8 +20,8 @@ #include "net/http/http_response_headers.h" #include "net/log/net_log.h" #include "net/quic/chromium/quic_chromium_packet_reader.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quic/core/quic_config.h" -#include "net/third_party/quic/core/quic_spdy_stream.h" #include "net/third_party/quic/platform/impl/quic_chromium_clock.h" #include "net/third_party/quic/tools/quic_spdy_client_base.h" #include "net/tools/quic/quic_client_message_loop_network_helper.h"
diff --git a/net/tools/quic/quic_simple_server_session_helper.h b/net/tools/quic/quic_simple_server_session_helper.h index b176e26..46f3b65 100644 --- a/net/tools/quic/quic_simple_server_session_helper.h +++ b/net/tools/quic/quic_simple_server_session_helper.h
@@ -6,7 +6,7 @@ #define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_HELPER_H_ #include "net/third_party/quic/core/crypto/quic_random.h" -#include "net/third_party/quic/core/quic_server_session_base.h" +#include "net/third_party/quic/core/http/quic_server_session_base.h" namespace net {
diff --git a/ppapi/generators/idl_ast.py b/ppapi/generators/idl_ast.py index 515dbb0..e95e94e 100644 --- a/ppapi/generators/idl_ast.py +++ b/ppapi/generators/idl_ast.py
@@ -178,5 +178,3 @@ errors = filenode.GetProperty('ERRORS') if errors: self.errors += errors - -
diff --git a/ppapi/generators/idl_c_header.py b/ppapi/generators/idl_c_header.py index b4b98227..9b4513ac 100755 --- a/ppapi/generators/idl_c_header.py +++ b/ppapi/generators/idl_c_header.py
@@ -371,4 +371,3 @@ if __name__ == '__main__': sys.exit(main(sys.argv[1:])) -
diff --git a/ppapi/generators/idl_namespace.py b/ppapi/generators/idl_namespace.py index b81411e..21a643c 100755 --- a/ppapi/generators/idl_namespace.py +++ b/ppapi/generators/idl_namespace.py
@@ -246,4 +246,3 @@ if __name__ == '__main__': sys.exit(Main(sys.argv[1:])) -
diff --git a/ppapi/generators/idl_node.py b/ppapi/generators/idl_node.py index 55b24d1..feeb430 100755 --- a/ppapi/generators/idl_node.py +++ b/ppapi/generators/idl_node.py
@@ -444,4 +444,3 @@ if __name__ == '__main__': sys.exit(Main()) -
diff --git a/ppapi/generators/idl_parser.py b/ppapi/generators/idl_parser.py index 823dcf5a..fdd5e88c 100755 --- a/ppapi/generators/idl_parser.py +++ b/ppapi/generators/idl_parser.py
@@ -1293,4 +1293,3 @@ if __name__ == '__main__': sys.exit(Main(sys.argv[1:])) -
diff --git a/ppapi/generators/idl_propertynode.py b/ppapi/generators/idl_propertynode.py index e15354a..9152ed7 100755 --- a/ppapi/generators/idl_propertynode.py +++ b/ppapi/generators/idl_propertynode.py
@@ -111,4 +111,3 @@ if __name__ == '__main__': sys.exit(Main()) -
diff --git a/ppapi/generators/idl_release.py b/ppapi/generators/idl_release.py index ff4aa01d..44068548 100755 --- a/ppapi/generators/idl_release.py +++ b/ppapi/generators/idl_release.py
@@ -353,4 +353,3 @@ if __name__ == '__main__': sys.exit(Main(sys.argv[1:])) -
diff --git a/ppapi/generators/idl_tests.py b/ppapi/generators/idl_tests.py index bf6d8a1..b41bb0f66 100755 --- a/ppapi/generators/idl_tests.py +++ b/ppapi/generators/idl_tests.py
@@ -42,4 +42,3 @@ if __name__ == '__main__': sys.exit(main(sys.argv[1:])) -
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index dfc727dd..285f46b 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -260,9 +260,9 @@ // TODO(843510): Consider setting this info and notifying observers // asynchronously in response to GoogleSigninSucceeded() once there are no // direct clients of SigninManager. - DCHECK(account_info.account_id == primary_account_info_.account_id); - DCHECK(account_info.gaia == primary_account_info_.gaia); - DCHECK(account_info.email == primary_account_info_.email); + DCHECK_EQ(account_info.account_id, primary_account_info_.account_id); + DCHECK_EQ(account_info.gaia, primary_account_info_.gaia); + DCHECK(gaia::AreEmailsSame(account_info.email, primary_account_info_.email)); primary_account_info_ = AccountInfo(); } #endif
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc index 309f856..f1704081 100644 --- a/services/identity/public/cpp/identity_test_utils.cc +++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -194,7 +194,7 @@ return account_info; } -void ClearPrimaryAccount(SigninManagerForTest* signin_manager, +void ClearPrimaryAccount(SigninManagerBase* signin_manager, IdentityManager* identity_manager) { #if defined(OS_CHROMEOS) // TODO(blundell): If we ever need this functionality on ChromeOS (which seems @@ -209,7 +209,10 @@ identity_manager, run_loop.QuitClosure(), IdentityManagerEvent::PRIMARY_ACCOUNT_CLEARED); - signin_manager->ForceSignOut(); + SigninManager* real_signin_manager = + SigninManager::FromSigninManagerBase(signin_manager); + real_signin_manager->SignOut(signin_metrics::SIGNOUT_TEST, + signin_metrics::SignoutDelete::IGNORE_METRIC); run_loop.Run(); #endif
diff --git a/services/identity/public/cpp/identity_test_utils.h b/services/identity/public/cpp/identity_test_utils.h index ac550f4..e72264fc 100644 --- a/services/identity/public/cpp/identity_test_utils.h +++ b/services/identity/public/cpp/identity_test_utils.h
@@ -79,11 +79,7 @@ // Clears the primary account. On non-ChromeOS, results in the firing of the // IdentityManager and SigninManager callbacks for signout. Blocks until the // primary account is cleared. -// Note that this function requires FakeSigninManager, as it internally invokes -// functionality of the fake. If a use case emerges for invoking this -// functionality with a production SigninManager, contact blundell@chromium.org. -// NOTE: See disclaimer at top of file re: direct usage. -void ClearPrimaryAccount(SigninManagerForTest* signin_manager, +void ClearPrimaryAccount(SigninManagerBase* signin_manager, IdentityManager* identity_manager); // Makes an account available for the given email address, generating a GAIA ID
diff --git a/storage/OWNERS b/storage/OWNERS index 4cc173f..ca4682d 100644 --- a/storage/OWNERS +++ b/storage/OWNERS
@@ -1,5 +1,6 @@ dmurph@chromium.org jsbell@chromium.org +pwnall@chromium.org kinuko@chromium.org # TEAM: storage-dev@chromium.org
diff --git a/testing/libfuzzer/fuzzers/v8_fuzzer.cc b/testing/libfuzzer/fuzzers/v8_fuzzer.cc index 3f95f34..ec2c0b6 100644 --- a/testing/libfuzzer/fuzzers/v8_fuzzer.cc +++ b/testing/libfuzzer/fuzzers/v8_fuzzer.cc
@@ -113,7 +113,11 @@ bool is_running; }; -extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { +// Explicitly specify some attributes to avoid issues with the linker dead- +// stripping the following function on macOS, as it is not called directly +// by fuzz target. LibFuzzer runtime uses dlsym() to resolve that function. +extern "C" __attribute__((used)) __attribute__((visibility("default"))) int +LLVMFuzzerInitialize(int* argc, char*** argv) { v8::V8::InitializeICUDefaultLocation((*argv)[0]); v8::V8::InitializeExternalStartupData((*argv)[0]); v8::V8::SetFlagsFromCommandLine(argc, *argv, true);
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 3fb4f9e..1afbf9fd 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -488,7 +488,6 @@ crbug.com/591099 fast/block/positioning/positioned-child-inside-relative-positioned-anonymous-block.html [ Failure ] crbug.com/591099 fast/borders/bidi-002.html [ Failure ] crbug.com/859497 fast/borders/bidi-009a.html [ Failure ] -crbug.com/591099 fast/borders/border-image-border-radius.html [ Failure ] crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ] crbug.com/591099 fast/box-shadow/box-shadow.html [ Failure ] crbug.com/591099 fast/box-sizing/replaced.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 4c29df8..34dea75 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2657,6 +2657,15 @@ crbug.com/849859 external/wpt/web-animations/timing-model/animations/pausing-an-animation.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/svg/render/reftests/blending-002.svg [ Failure ] +crbug.com/626703 external/wpt/svg/render/reftests/blending-001.svg [ Failure ] +crbug.com/626703 [ Win7 ] external/wpt/css/css-lists/content-property/marker-text-matches-armenian.html [ Failure ] +crbug.com/626703 [ Mac ] external/wpt/css/css-lists/content-property/marker-text-matches-upper-latin.html [ Failure ] +crbug.com/626703 external/wpt/css/css-lists/content-property/marker-text-matches-disc.html [ Failure ] +crbug.com/626703 [ Win ] external/wpt/css/css-lists/content-property/marker-text-matches-georgian.html [ Failure ] +crbug.com/626703 external/wpt/css/css-lists/content-property/marker-text-matches-square.html [ Failure ] +crbug.com/626703 external/wpt/svg/linking/reftests/use-descendant-combinator-003.html [ Failure ] +crbug.com/626703 external/wpt/css/css-lists/content-property/marker-text-matches-circle.html [ Failure ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-safe-overflow-position-001.html [ Failure ] crbug.com/626703 external/wpt/content-security-policy/securitypolicyviolation/inside-service-worker.https.html [ Timeout ] crbug.com/626703 external/wpt/content-security-policy/securitypolicyviolation/inside-shared-worker.html [ Timeout ] @@ -3745,7 +3754,8 @@ crbug.com/689781 external/wpt/media-source/mediasource-duration.html [ Failure Pass ] -# When WebAssembly is exposed in V8 (soon), this test has the wrong number of expected Object.getOwnPropertyNames() for global object. +crbug.com/860637 http/tests/wasm_streaming/regression860637.html [ Skip ] +crbug.com/860637 virtual/enable_wasm_streaming/http/tests/wasm_streaming/regression860637.html [ Skip ] crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Failure Pass ] crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom200.html [ Failure Pass ] @@ -4612,14 +4622,6 @@ crbug.com/856601 [ Linux ] external/wpt/touch-events/idlharness.window.html [ Timeout Pass ] crbug.com/856601 [ Linux ] http/tests/event-timing/event-timing-retrievability.html [ Timeout Pass ] -### fast/canvas/color-space/ + virtual/gpu/..., color management and transparency. -crbug.com/859102 fast/canvas/color-space/canvas-drawImage-linear-rgb.html [ Pass Failure ] -crbug.com/859102 fast/canvas/color-space/canvas-drawImage-p3.html [ Pass Failure ] -crbug.com/859102 fast/canvas/color-space/canvas-drawImage-rec2020.html [ Pass Failure ] -crbug.com/859102 virtual/gpu/fast/canvas/color-space/canvas-drawImage-linear-rgb.html [ Pass Failure ] -crbug.com/859102 virtual/gpu/fast/canvas/color-space/canvas-drawImage-p3.html [ Pass Failure ] -crbug.com/859102 virtual/gpu/fast/canvas/color-space/canvas-drawImage-rec2020.html [ Pass Failure ] - # Sheriff 2018-07-11 # Test timeouts following wpt-import@89ccb892... crbug.com/862588 [ Linux ] external/wpt/cookie-store/idlharness.tentative.https.html [ Timeout Pass ] @@ -4627,7 +4629,6 @@ crbug.com/862588 [ Linux ] external/wpt/push-api/idlharness.https.any.worker.html [ Timeout Pass ] crbug.com/862588 [ Linux ] external/wpt/resource-timing/idlharness.any.html [ Timeout Pass ] crbug.com/862588 [ Linux ] external/wpt/resource-timing/idlharness.any.worker.html [ Timeout Pass ] -crbug.com/862588 [ Linux ] external/wpt/selection/interfaces.html [ Timeout Pass ] crbug.com/862588 [ Linux ] external/wpt/service-workers/service-worker/interfaces-sw.https.html [ Timeout Pass ] crbug.com/862588 [ Linux ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/idlharness.https.window.html [ Timeout Pass ] @@ -4658,3 +4659,21 @@ crbug.com/866785 [ Mac ] svg/as-border-image/svg-as-border-image-2.html [ Failure Pass ] crbug.com/866785 [ Mac ] svg/as-border-image/svg-as-border-image.html [ Failure Pass ] crbug.com/866785 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/text-track-menu-pointer-selection.html [ Failure Pass ] + +### fast/canvas/color-space/ + virtual/gpu/..., color management and transparency. +crbug.com/859102 fast/canvas/color-space/canvas-drawImage-linear-rgb.html [ Pass Failure ] +crbug.com/859102 fast/canvas/color-space/canvas-drawImage-p3.html [ Pass Failure ] +crbug.com/859102 fast/canvas/color-space/canvas-drawImage-rec2020.html [ Pass Failure ] +crbug.com/859102 virtual/gpu/fast/canvas/color-space/canvas-drawImage-linear-rgb.html [ Pass Failure ] +crbug.com/859102 virtual/gpu/fast/canvas/color-space/canvas-drawImage-p3.html [ Pass Failure ] +crbug.com/859102 virtual/gpu/fast/canvas/color-space/canvas-drawImage-rec2020.html [ Pass Failure ] + +### virtual/gpu/fast/canvas/ blending layout tests timeout +crbug.com/866850 [ Linux Mac ] virtual/gpu/fast/canvas/canvas-blend-image.html [ Pass Timeout ] +crbug.com/866850 [ Linux Mac ] virtual/gpu/fast/canvas/canvas-blending-gradient-over-image.html [ Pass Timeout ] +crbug.com/866850 [ Linux Mac ] virtual/gpu/fast/canvas/canvas-blending-image-over-image.html [ Pass Timeout ] +crbug.com/866850 [ Linux Mac ] virtual/gpu/fast/canvas/canvas-blending-pattern-over-color.html [ Pass Timeout ] +crbug.com/866850 [ Linux Mac ] virtual/gpu/fast/canvas/canvas-blending-pattern-over-gradient.html [ Pass Timeout ] +crbug.com/866850 [ Linux Mac ] virtual/gpu/fast/canvas/canvas-blending-pattern-over-image.html [ Pass Timeout ] +crbug.com/866850 [ Linux Mac ] virtual/gpu/fast/canvas/color-space/canvas-createImageBitmap-p3.html [ Pass Timeout ] +crbug.com/866850 [ Linux Mac ] virtual/gpu/fast/canvas/color-space/canvas-createImageBitmap-rec2020.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/css-parser/unitless-length-quirk.html b/third_party/WebKit/LayoutTests/css-parser/unitless-length-quirk.html index c0afd56b..1bd667db 100644 --- a/third_party/WebKit/LayoutTests/css-parser/unitless-length-quirk.html +++ b/third_party/WebKit/LayoutTests/css-parser/unitless-length-quirk.html
@@ -9,6 +9,6 @@ assert_invalid_value("outlineWidth", "50"); assert_invalid_value("offsetDistance", "60"); -assert_invalid_value("webkitPaddingStart", "12"); -assert_invalid_value("webkitMarginBefore", "24"); +assert_invalid_value("paddingInlineStart", "12"); +assert_invalid_value("marginBlockStart", "24"); </script>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-2.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-2.html index 4117697d..f6a040e 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-2.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-2.html
@@ -66,57 +66,57 @@ <div class="flexbox"> <div class="first" data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; margin: 0 auto;"></div> - <div class="second" data-expected-width="350" data-offset-x="75" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-x="275"></div></div> - <div class="third" data-expected-width="75" data-offset-x="425" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div class="second" data-expected-width="350" data-offset-x="75" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-x="275"></div></div> + <div class="third" data-expected-width="75" data-offset-x="425" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> <div class="flexbox rtl"> <div class="first" data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; margin: 0 auto;"></div> - <div class="second" data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-x="175"></div></div> - <div class="third" data-expected-width="75" data-offset-x="100" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div class="second" data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-x="175"></div></div> + <div class="third" data-expected-width="75" data-offset-x="100" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> <div class="flexbox row-reverse"> <div class="first" data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; margin: 0 auto;"></div> - <div class="second" data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-x="375"></div></div> - <div class="third" data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div class="second" data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-x="375"></div></div> + <div class="third" data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> <div class="flexbox rtl row-reverse"> <div class="first" data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; margin: 0 auto;"></div> - <div class="second" data-expected-width="350" data-offset-x="75" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-x="75"></div></div> - <div class="third" data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div class="second" data-expected-width="350" data-offset-x="75" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-x="75"></div></div> + <div class="third" data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> <div style="position: relative;"> <div class="flexbox column"> <div class="first" data-expected-height="150" data-offset-y="0" style="flex: 1 0 0; margin: auto 200px auto 150px;"></div> - <div class="second" data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-y="150" data-offset-x="200"></div></div> - <div class="third" data-expected-height="150" data-offset-y="450" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div class="second" data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-y="150" data-offset-x="200"></div></div> + <div class="third" data-expected-height="150" data-offset-y="450" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> </div> <div style="position: relative;"> <div class="flexbox column-reverse"> <div class="first" data-expected-height="150" data-offset-y="450" style="flex: 1 0 0; margin: auto 200px auto 150px;"></div> - <div class="second" data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-y="150" data-offset-x="200"></div></div> - <div class="third" data-expected-height="150" data-offset-y="0" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div class="second" data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-y="150" data-offset-x="200"></div></div> + <div class="third" data-expected-height="150" data-offset-y="0" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> </div> <div style="position: relative;"> <div class="flexbox column rtl"> <div class="first" data-expected-height="150" data-offset-y="0" data-offset-x="480" style="flex: 1 0 0; margin: auto 100px auto 50px;"></div> - <div class="second" data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-y="150" data-offset-x="380"></div></div> - <div class="third" data-expected-height="150" data-offset-y="450" data-offset-x="580" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div class="second" data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-y="150" data-offset-x="380"></div></div> + <div class="third" data-expected-height="150" data-offset-y="450" data-offset-x="580" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> </div> <div style="position: relative;"> <div class="flexbox column-reverse rtl"> <div class="first" data-expected-height="150" data-offset-y="450" data-offset-x="480" style="flex: 1 0 0; margin: auto 100px auto 50px;"></div> - <div class="second" data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-y="150" data-offset-x="380"></div></div> - <div class="third" data-expected-height="150" data-offset-y="0" data-offset-x="580" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div class="second" data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-y="150" data-offset-x="380"></div></div> + <div class="third" data-expected-height="150" data-offset-y="0" data-offset-x="580" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-auto-margins.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-auto-margins.html index fcb7c51..3979711 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-auto-margins.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-auto-margins.html
@@ -53,16 +53,16 @@ margin: 13px auto 17px auto; } .logical { - -webkit-margin-before: 10px; - -webkit-margin-after: 30px; - -webkit-margin-start: 40px; - -webkit-margin-end: 20px; + margin-block-start: 10px; + margin-block-end: 30px; + margin-inline-start: 40px; + margin-inline-end: 20px; } .logical > div { - -webkit-margin-before: auto; - -webkit-margin-after: 17px; - -webkit-margin-start: auto; - -webkit-margin-end: 2px; + margin-block-start: auto; + margin-block-end: 17px; + margin-inline-start: auto; + margin-inline-end: 2px; } .flexbox > :nth-child(1) { background-color: blue;
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-border.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-border.html index eba0bb4..cc86577 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-border.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-border.html
@@ -55,16 +55,16 @@ border-width: 13px 2px 17px 8px; } .logical { - -webkit-border-before-width: 10px; - -webkit-border-after-width: 30px; - -webkit-border-start-width: 40px; - -webkit-border-end-width: 20px; + border-block-start-width: 10px; + border-block-end-width: 30px; + border-inline-start-width: 40px; + border-inline-end-width: 20px; } .logical > div { - -webkit-border-before-width: 13px; - -webkit-border-after-width: 17px; - -webkit-border-start-width: 8px; - -webkit-border-end-width: 2px; + border-block-start-width: 13px; + border-block-end-width: 17px; + border-inline-start-width: 8px; + border-inline-end-width: 2px; } .flexbox > :nth-child(1) { background-color: blue;
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-margins.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-margins.html index cb3f930f..2bc8a06 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-margins.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-margins.html
@@ -50,16 +50,16 @@ margin: 13px 2px 17px 8px; } .logical { - -webkit-margin-before: 10px; - -webkit-margin-after: 30px; - -webkit-margin-start: 40px; - -webkit-margin-end: 20px; + margin-block-start: 10px; + margin-block-end: 30px; + margin-inline-start: 40px; + margin-inline-end: 20px; } .logical > div { - -webkit-margin-before: 13px; - -webkit-margin-after: 17px; - -webkit-margin-start: 8px; - -webkit-margin-end: 2px; + margin-block-start: 13px; + margin-block-end: 17px; + margin-inline-start: 8px; + margin-inline-end: 2px; } .flexbox > :nth-child(1) { background-color: blue;
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-padding.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-padding.html index bf0119c..f9cd465 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-padding.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-padding.html
@@ -50,16 +50,16 @@ padding: 13px 2px 17px 8px; } .logical { - -webkit-padding-before: 10px; - -webkit-padding-after: 30px; - -webkit-padding-start: 40px; - -webkit-padding-end: 20px; + padding-block-start: 10px; + padding-block-end: 30px; + padding-inline-start: 40px; + padding-inline-end: 20px; } .logical > div { - -webkit-padding-before: 13px; - -webkit-padding-after: 17px; - -webkit-padding-start: 8px; - -webkit-padding-end: 2px; + padding-block-start: 13px; + padding-block-end: 17px; + padding-inline-start: 8px; + padding-inline-end: 2px; } .flexbox > :nth-child(1) { background-color: blue;
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow.html index b61463a..32938a28 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow.html
@@ -66,57 +66,57 @@ <div class="flexbox"> <div data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; margin: 0 auto;"></div> - <div data-expected-width="350" data-offset-x="75" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-x="275"></div></div> - <div data-expected-width="75" data-offset-x="425" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div data-expected-width="350" data-offset-x="75" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-x="275"></div></div> + <div data-expected-width="75" data-offset-x="425" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> <div class="flexbox rtl"> <div data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; margin: 0 auto;"></div> - <div data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-x="175"></div></div> - <div data-expected-width="75" data-offset-x="100" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-x="175"></div></div> + <div data-expected-width="75" data-offset-x="100" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> <div class="flexbox row-reverse"> <div data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; margin: 0 auto;"></div> - <div data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-x="375"></div></div> - <div data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-x="375"></div></div> + <div data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> <div class="flexbox rtl row-reverse"> <div data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; margin: 0 auto;"></div> - <div data-expected-width="350" data-offset-x="75" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-x="75"></div></div> - <div data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div data-expected-width="350" data-offset-x="75" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-x="75"></div></div> + <div data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> <div style="position: relative;"> <div class="flexbox column"> <div data-expected-height="150" data-offset-y="0" style="flex: 1 0 0; margin: auto 200px auto 150px;"></div> - <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-y="150" data-offset-x="200"></div></div> - <div data-expected-height="150" data-offset-y="450" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-y="150" data-offset-x="200"></div></div> + <div data-expected-height="150" data-offset-y="450" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> </div> <div style="position: relative;"> <div class="flexbox column-reverse"> <div data-expected-height="150" data-offset-y="450" style="flex: 1 0 0; margin: auto 200px auto 150px;"></div> - <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-y="150" data-offset-x="200"></div></div> - <div data-expected-height="150" data-offset-y="0" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-y="150" data-offset-x="200"></div></div> + <div data-expected-height="150" data-offset-y="0" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> </div> <div style="position: relative;"> <div class="flexbox column rtl"> <div data-expected-height="150" data-offset-y="0" data-offset-x="480" style="flex: 1 0 0; margin: auto 100px auto 50px;"></div> - <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-y="150" data-offset-x="380"></div></div> - <div data-expected-height="150" data-offset-y="450" data-offset-x="580" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-y="150" data-offset-x="380"></div></div> + <div data-expected-height="150" data-offset-y="450" data-offset-x="580" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> </div> <div style="position: relative;"> <div class="flexbox column-reverse rtl"> <div data-expected-height="150" data-offset-y="450" data-offset-x="480" style="flex: 1 0 0; margin: auto 100px auto 50px;"></div> - <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; -webkit-padding-start: 200px"><div data-offset-y="150" data-offset-x="380"></div></div> - <div data-expected-height="150" data-offset-y="0" data-offset-x="580" style="flex: 1 0 0; -webkit-margin-end: 100px;"></div> + <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0; padding-inline-start: 200px"><div data-offset-y="150" data-offset-x="380"></div></div> + <div data-expected-height="150" data-offset-y="0" data-offset-x="580" style="flex: 1 0 0; margin-inline-end: 100px;"></div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/multiline-align-self.html b/third_party/WebKit/LayoutTests/css3/flexbox/multiline-align-self.html index 6ccfdd55..09d2054 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/multiline-align-self.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/multiline-align-self.html
@@ -1037,7 +1037,7 @@ flexbox.className = 'flexbox ' + flexboxClassName; flexbox.setAttribute('style', mainAxis + ': 70px'); - var baselineMargin = (flexDirection.indexOf('row') != -1) ? '-webkit-margin-before: 5px;' : '-webkit-margin-start: 5px;'; + var baselineMargin = (flexDirection.indexOf('row') != -1) ? 'margin-block-start: 5px;' : 'margin-inline-start: 5px;'; var testExpectations = expectations[writingMode][flexDirection][direction][wrap]; addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'flex-start', testExpectations['child1']);
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/multiline-justify-content.html b/third_party/WebKit/LayoutTests/css3/flexbox/multiline-justify-content.html index dd91223f..a5e18c1 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/multiline-justify-content.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/multiline-justify-content.html
@@ -1985,7 +1985,7 @@ flexbox.className = 'flexbox ' + flexboxClassName; flexbox.setAttribute('style', mainAxis + ': 80px'); - var baselineMargin = (flexDirection.indexOf('row') != -1) ? '-webkit-margin-before: 5px' : '-webkit-margin-start: 5px'; + var baselineMargin = (flexDirection.indexOf('row') != -1) ? 'margin-block-start: 5px' : 'margin-inline-start: 5px'; var testExpectations = expectations[writingMode][flexDirection][direction][wrap][justifyContent]; addChild(flexbox, mainAxis, crossAxis, 40, '10', testExpectations['child1']);
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/negative-flex-rounding-assert.html b/third_party/WebKit/LayoutTests/css3/flexbox/negative-flex-rounding-assert.html index 1daafb9..12abe30 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/negative-flex-rounding-assert.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/negative-flex-rounding-assert.html
@@ -12,10 +12,10 @@ flex-direction: column; } .mfrac > :first-child { - -webkit-margin-after: 0.2em; + margin-block-end: 0.2em; } .mfrac > :last-child { - -webkit-margin-before: 0.2em; + margin-block-start: 0.2em; } .x { line-height: 9px;
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/writing-modes.html b/third_party/WebKit/LayoutTests/css3/flexbox/writing-modes.html index edfc353c..a819051 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/writing-modes.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/writing-modes.html
@@ -63,13 +63,13 @@ <div class="flexbox rtl"> <div data-expected-width="75" data-offset-x="525" style="flex: 1 0 0; margin: 0 auto;"></div> <div data-expected-width="350" data-offset-x="175" style="flex: 2 0 0; padding: 0 100px;"></div> - <div data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; -webkit-margin-start: 100px;"></div> + <div data-expected-width="75" data-offset-x="0" style="flex: 1 0 0; margin-inline-start: 100px;"></div> </div> -<div class="flexbox rtl" style="-webkit-margin-start: 20px;-webkit-margin-end: 50px;"> +<div class="flexbox rtl" style="margin-inline-start: 20px;margin-inline-end: 50px;"> <div data-expected-width="75" data-offset-x="575" style="flex: 1 0 0; margin: 0 auto;"></div> <div data-expected-width="350" data-offset-x="225" style="flex: 2 0 0; padding: 0 100px;"></div> - <div data-expected-width="75" data-offset-x="50" style="flex: 1 0 0; -webkit-margin-start: 100px;"></div> + <div data-expected-width="75" data-offset-x="50" style="flex: 1 0 0; margin-inline-start: 100px;"></div> </div> <div style="position:relative"> @@ -98,7 +98,7 @@ <div style="position:relative"> <div class="flexbox vertical-lr"> - <div data-expected-height="450" data-offset-y="0" style="flex: 1 0 0;-webkit-padding-start:200px;-webkit-padding-end:200px;-webkit-padding-before:100px;-webkit-padding-after:100px;"></div> + <div data-expected-height="450" data-offset-y="0" style="flex: 1 0 0;padding-inline-start:200px;padding-inline-end:200px;padding-block-start:100px;padding-block-end:100px;"></div> <div data-expected-height="100" data-offset-y="450" style="flex: 2 0 0;"></div> <div data-expected-height="50" data-offset-y="550" style="flex: 1 0 0;"></div> </div> @@ -106,7 +106,7 @@ <div style="position:relative"> <div class="flexbox vertical-lr"> - <div data-expected-height="300" data-offset-y="0" class="horizontal-tb" style="flex: 1 0 0;-webkit-padding-start:200px;-webkit-padding-end:200px;-webkit-padding-before:100px;-webkit-padding-after:100px;"></div> + <div data-expected-height="300" data-offset-y="0" class="horizontal-tb" style="flex: 1 0 0;padding-inline-start:200px;padding-inline-end:200px;padding-block-start:100px;padding-block-end:100px;"></div> <div data-expected-height="200" data-offset-y="300" style="flex: 2 0 0;"></div> <div data-expected-height="100" data-offset-y="500" style="flex: 1 0 0;"></div> </div> @@ -139,7 +139,7 @@ <div style="position:relative"> <div class="flexbox vertical-lr"> - <div data-expected-height="150" data-offset-y="0" style="flex: 1 0 0;-webkit-margin-start:auto;-webkit-margin-end:auto;-webkit-margin-before:0;-webkit-margin-after:0;;"></div> + <div data-expected-height="150" data-offset-y="0" style="flex: 1 0 0;margin-inline-start:auto;margin-inline-end:auto;margin-block-start:0;margin-block-end:0;;"></div> <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0;"></div> <div data-expected-height="150" data-offset-y="450" style="flex: 1 0 0;"></div> </div> @@ -147,7 +147,7 @@ <div style="position:relative"> <div class="flexbox vertical-lr"> - <div data-expected-height="150" data-offset-y="0" class="horizontal-tb" style="flex: 1 0 0;-webkit-margin-start:auto;-webkit-margin-end:auto;-webkit-margin-before:0;-webkit-margin-after:0;;"></div> + <div data-expected-height="150" data-offset-y="0" class="horizontal-tb" style="flex: 1 0 0;margin-inline-start:auto;margin-inline-end:auto;margin-block-start:0;margin-block-end:0;;"></div> <div data-expected-height="300" data-offset-y="150" style="flex: 2 0 0;"></div> <div data-expected-height="150" data-offset-y="450" style="flex: 1 0 0;"></div> </div> @@ -157,7 +157,7 @@ <div class="flexbox vertical-lr rtl"> <div data-expected-height="75" data-offset-y="525" style="flex: 1 0 0; margin: auto 0;"></div> <div data-expected-height="350" data-offset-y="175" class="horizontal-tb" style="flex: 2 0 0; padding: 100px 0;"></div> - <div data-expected-height="75" data-offset-y="0" style="flex: 1 0 0; -webkit-margin-start: 100px;"></div> + <div data-expected-height="75" data-offset-y="0" style="flex: 1 0 0; margin-inline-start: 100px;"></div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/delete-blockquote-large-offsets.html b/third_party/WebKit/LayoutTests/editing/deleting/delete-blockquote-large-offsets.html index 7ea982e..991b5cd 100644 --- a/third_party/WebKit/LayoutTests/editing/deleting/delete-blockquote-large-offsets.html +++ b/third_party/WebKit/LayoutTests/editing/deleting/delete-blockquote-large-offsets.html
@@ -3,7 +3,7 @@ <body> This tests setting caret inside a blockquote with a large offset and running execCommand('Delete'). WebKit should not crash and you should see PASS below: <div id="test" contentEditable="true"> -<blockquote type="cite" id="blockquote" style="font-size: 0px; -webkit-min-logical-height: 4px;"><br></blockquote> +<blockquote type="cite" id="blockquote" style="font-size: 0px; min-block-size: 4px;"><br></blockquote> </div> <script> if (window.testRunner)
diff --git a/third_party/WebKit/LayoutTests/editing/selection/modify_move/move-by-word-visually-crash-test-5.html b/third_party/WebKit/LayoutTests/editing/selection/modify_move/move-by-word-visually-crash-test-5.html index 5606a3d..e7a6276f 100644 --- a/third_party/WebKit/LayoutTests/editing/selection/modify_move/move-by-word-visually-crash-test-5.html +++ b/third_party/WebKit/LayoutTests/editing/selection/modify_move/move-by-word-visually-crash-test-5.html
@@ -12,4 +12,4 @@ <div dir=ltr title="test_for_crash" class="test_move_by_word" ><plaintext>class="test_move_by_word" -style="-wap-marquee-style:mix; marker:sliderthumb-vertical; position:-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001; border-top-style:rl-tb; -webkit-padding-after:absolute; position:destination-atop; border:ethiopic-halehame-ti-et; clip-rule:absolute; position:menulist-text; color-profile:-webkit-activelink; position:reset-size; margin-right:message-box; filter:absolute; position:no-punctuation; -webkit-border-end:no-punctuation; border-bottom-style:absolute; position:line-through; text-underline-mode:repeat-y; clip-rule:absolute; position:amharic-abegede; -webkit-text-fill-color:nowrap; -webkit-text-decorations-in-effect:absolute; position:sliderthumb-horizontal; border-top-right-radius:wave; border-top:absolute; position:up; border-right:not-allowed; enable-background:absolute; position:caption; max-height:ne-resize; +style="-wap-marquee-style:mix; marker:sliderthumb-vertical; position:-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001; border-top-style:rl-tb; padding-block-end:absolute; position:destination-atop; border:ethiopic-halehame-ti-et; clip-rule:absolute; position:menulist-text; color-profile:-webkit-activelink; position:reset-size; margin-right:message-box; filter:absolute; position:no-punctuation; border-inline-end:no-punctuation; border-bottom-style:absolute; position:line-through; text-underline-mode:repeat-y; clip-rule:absolute; position:amharic-abegede; -webkit-text-fill-color:nowrap; -webkit-text-decorations-in-effect:absolute; position:sliderthumb-horizontal; border-top-right-radius:wave; border-top:absolute; position:up; border-right:not-allowed; enable-background:absolute; position:caption; max-height:ne-resize;
diff --git a/third_party/WebKit/LayoutTests/editing/text-iterator/first_letter_find_string_crash.html b/third_party/WebKit/LayoutTests/editing/text-iterator/first_letter_find_string_crash.html index 9e84c9270..17155e1 100644 --- a/third_party/WebKit/LayoutTests/editing/text-iterator/first_letter_find_string_crash.html +++ b/third_party/WebKit/LayoutTests/editing/text-iterator/first_letter_find_string_crash.html
@@ -12,7 +12,7 @@ * { -webkit-rtl-ordering: visual; - -webkit-margin-end: -1px + margin-inline-end: -1px } </style> <font dir="rtl">iC <q></q></font>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 5a010e31..3325142 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -6375,6 +6375,18 @@ {} ] ], + "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self.html": [ + [ + "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self.html", + [ + [ + "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html", + "==" + ] + ], + {} + ] + ], "2dcontext/line-styles/canvas_linestyles_linecap_001.htm": [ [ "/2dcontext/line-styles/canvas_linestyles_linecap_001.htm", @@ -47107,6 +47119,150 @@ {} ] ], + "css/css-lists/content-property/marker-text-matches-armenian.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-armenian.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-armenian-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-circle.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-circle.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-circle-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-decimal-leading-zero.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-decimal-leading-zero.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-decimal-leading-zero-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-decimal.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-decimal.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-decimal-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-disc.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-disc.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-disc-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-georgian.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-georgian.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-georgian-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-lower-greek.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-lower-greek.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-lower-greek-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-lower-latin.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-lower-latin.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-lower-latin-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-lower-roman.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-lower-roman.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-lower-roman-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-square.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-square.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-square-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-upper-latin.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-upper-latin.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-upper-latin-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-upper-roman.html": [ + [ + "/css/css-lists/content-property/marker-text-matches-upper-roman.html", + [ + [ + "/css/css-lists/content-property/marker-text-matches-upper-roman-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-lists/counter-increment-inside-display-contents.html": [ [ "/css/css-lists/counter-increment-inside-display-contents.html", @@ -52279,6 +52435,18 @@ {} ] ], + "css/css-pseudo/marker-inherit-line-height.html": [ + [ + "/css/css-pseudo/marker-inherit-line-height.html", + [ + [ + "/css/css-pseudo/marker-inherit-line-height-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-pseudo/marker-inherit-values.html": [ [ "/css/css-pseudo/marker-inherit-values.html", @@ -57595,18 +57763,6 @@ {} ] ], - "css/css-text/overflow-wrap/overflow-wrap-break-word-004.html": [ - [ - "/css/css-text/overflow-wrap/overflow-wrap-break-word-004.html", - [ - [ - "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html", - "==" - ] - ], - {} - ] - ], "css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html": [ [ "/css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html", @@ -59587,30 +59743,6 @@ {} ] ], - "css/css-text/word-break/word-break-break-all-010.html": [ - [ - "/css/css-text/word-break/word-break-break-all-010.html", - [ - [ - "/css/css-text/word-break/reference/word-break-break-all-010-ref.html", - "==" - ] - ], - {} - ] - ], - "css/css-text/word-break/word-break-break-all-011.html": [ - [ - "/css/css-text/word-break/word-break-break-all-011.html", - [ - [ - "/css/css-text/word-break/reference/word-break-break-all-010-ref.html", - "==" - ] - ], - {} - ] - ], "css/css-text/word-break/word-break-keep-all-000.html": [ [ "/css/css-text/word-break/word-break-keep-all-000.html", @@ -95871,6 +96003,18 @@ {} ] ], + "svg/linking/reftests/use-descendant-combinator-003.html": [ + [ + "/svg/linking/reftests/use-descendant-combinator-003.html", + [ + [ + "/svg/linking/reftests/use-descendant-combinator-ref.html", + "==" + ] + ], + {} + ] + ], "svg/painting/currentColor-override-pserver-fallback.svg": [ [ "/svg/painting/currentColor-override-pserver-fallback.svg", @@ -96063,6 +96207,30 @@ {} ] ], + "svg/render/reftests/blending-001.svg": [ + [ + "/svg/render/reftests/blending-001.svg", + [ + [ + "/svg/render/reftests/blending-001-ref.svg", + "==" + ] + ], + {} + ] + ], + "svg/render/reftests/blending-002.svg": [ + [ + "/svg/render/reftests/blending-002.svg", + [ + [ + "/svg/render/reftests/blending-002-ref.svg", + "==" + ] + ], + {} + ] + ], "svg/rendering/order/z-index.svg": [ [ "/svg/rendering/order/z-index.svg", @@ -100904,6 +101072,11 @@ {} ] ], + "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html": [ + [ + {} + ] + ], "2dcontext/drawing-model/.gitkeep": [ [ {} @@ -102559,6 +102732,11 @@ {} ] ], + "accelerometer/idlharness.https.window-expected.txt": [ + [ + {} + ] + ], "accname/description_from_content_of_describedby_element-manual-expected.txt": [ [ {} @@ -103454,6 +103632,26 @@ {} ] ], + "background-fetch/idlharness.any-expected.txt": [ + [ + {} + ] + ], + "background-fetch/idlharness.any.sharedworker-expected.txt": [ + [ + {} + ] + ], + "background-fetch/idlharness.any.worker-expected.txt": [ + [ + {} + ] + ], + "background-fetch/idlharness.https.any.serviceworker-expected.txt": [ + [ + {} + ] + ], "background-fetch/interfaces-worker.https-expected.txt": [ [ {} @@ -123129,6 +123327,11 @@ {} ] ], + "css/css-images/idlharness-expected.txt": [ + [ + {} + ] + ], "css/css-images/linear-gradient-ref.html": [ [ {} @@ -123504,6 +123707,66 @@ {} ] ], + "css/css-lists/content-property/marker-text-matches-armenian-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-circle-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-decimal-leading-zero-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-decimal-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-disc-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-georgian-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-lower-greek-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-lower-latin-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-lower-roman-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-square-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-upper-latin-ref.html": [ + [ + {} + ] + ], + "css/css-lists/content-property/marker-text-matches-upper-roman-ref.html": [ + [ + {} + ] + ], "css/css-lists/counter-7-ref.html": [ [ {} @@ -123534,6 +123797,11 @@ {} ] ], + "css/css-logical/animation-003.tentative-expected.txt": [ + [ + {} + ] + ], "css/css-logical/cascading-001-ref.html": [ [ {} @@ -125059,6 +125327,11 @@ {} ] ], + "css/css-pseudo/marker-inherit-line-height-ref.html": [ + [ + {} + ] + ], "css/css-pseudo/marker-inherit-values-ref.html": [ [ {} @@ -128444,11 +128717,6 @@ {} ] ], - "css/css-text/word-break/reference/word-break-break-all-010-ref.html": [ - [ - {} - ] - ], "css/css-text/word-break/reference/word-break-break-all-ref-000.html": [ [ {} @@ -158309,11 +158577,6 @@ {} ] ], - "infrastructure/server/wpt-server-http.sub-expected.txt": [ - [ - {} - ] - ], "infrastructure/testdriver/send_keys-expected.txt": [ [ {} @@ -158509,6 +158772,11 @@ {} ] ], + "interfaces/css-counter-styles.idl": [ + [ + {} + ] + ], "interfaces/css-font-loading.idl": [ [ {} @@ -158519,6 +158787,11 @@ {} ] ], + "interfaces/css-images.idl": [ + [ + {} + ] + ], "interfaces/css-masking.idl": [ [ {} @@ -158529,6 +158802,11 @@ {} ] ], + "interfaces/css-regions.idl": [ + [ + {} + ] + ], "interfaces/css-transitions.idl": [ [ {} @@ -158669,6 +158947,11 @@ {} ] ], + "interfaces/media-source.idl": [ + [ + {} + ] + ], "interfaces/mediacapture-depth.idl": [ [ {} @@ -159209,6 +159492,16 @@ {} ] ], + "media-source/idlharness.any-expected.txt": [ + [ + {} + ] + ], + "media-source/idlharness.any.worker-expected.txt": [ + [ + {} + ] + ], "media-source/import_tests.sh": [ [ {} @@ -161029,11 +161322,6 @@ {} ] ], - "payment-method-basic-card/idlharness.window-expected.txt": [ - [ - {} - ] - ], "payment-method-basic-card/payment-request-canmakepayment-method.https-expected.txt": [ [ {} @@ -164624,6 +164912,11 @@ {} ] ], + "resize-observer/idlharness.window-expected.txt": [ + [ + {} + ] + ], "resize-observer/resources/iframe.html": [ [ {} @@ -165009,6 +165302,11 @@ {} ] ], + "selection/idlharness.window-expected.txt": [ + [ + {} + ] + ], "selection/interfaces-expected.txt": [ [ {} @@ -165899,6 +166197,16 @@ {} ] ], + "server-timing/resources/parsing/84.js": [ + [ + {} + ] + ], + "server-timing/resources/parsing/84.js.sub.headers": [ + [ + {} + ] + ], "server-timing/resources/parsing/9.js": [ [ {} @@ -167134,11 +167442,6 @@ {} ] ], - "service-workers/service-worker/resources/interfaces-idls.js": [ - [ - {} - ] - ], "service-workers/service-worker/resources/interfaces-worker.sub.js": [ [ {} @@ -169019,6 +169322,16 @@ {} ] ], + "svg/render/reftests/blending-001-ref.svg": [ + [ + {} + ] + ], + "svg/render/reftests/blending-002-ref.svg": [ + [ + {} + ] + ], "svg/rendering/order/z-index-ref.svg": [ [ {} @@ -170434,6 +170747,11 @@ {} ] ], + "webaudio/idlharness.https.window-expected.txt": [ + [ + {} + ] + ], "webaudio/js/buffer-loader.js": [ [ {} @@ -171024,7 +171342,7 @@ {} ] ], - "webrtc/RTCPeerConnection-addTransceiver-expected.txt": [ + "webrtc/RTCPeerConnection-addTransceiver.https-expected.txt": [ [ {} ] @@ -183901,9 +184219,9 @@ {} ] ], - "accelerometer/idlharness.https.html": [ + "accelerometer/idlharness.https.window.js": [ [ - "/accelerometer/idlharness.https.html", + "/accelerometer/idlharness.https.window.html", {} ] ], @@ -183979,13 +184297,21 @@ {} ] ], - "background-fetch/interfaces.https.any.js": [ + "background-fetch/idlharness.any.js": [ [ - "/background-fetch/interfaces.https.any.html", + "/background-fetch/idlharness.any.html", {} ], [ - "/background-fetch/interfaces.https.any.worker.html", + "/background-fetch/idlharness.any.sharedworker.html", + {} + ], + [ + "/background-fetch/idlharness.any.worker.html", + {} + ], + [ + "/background-fetch/idlharness.https.any.serviceworker.html", {} ] ], @@ -192021,6 +192347,12 @@ {} ] ], + "css/css-images/idlharness.html": [ + [ + "/css/css-images/idlharness.html", + {} + ] + ], "css/css-images/parsing/gradient-position-invalid.html": [ [ "/css/css-images/parsing/gradient-position-invalid.html", @@ -192135,9 +192467,9 @@ {} ] ], - "css/css-logical/animation-003.tenative.html": [ + "css/css-logical/animation-003.tentative.html": [ [ - "/css/css-logical/animation-003.tenative.html", + "/css/css-logical/animation-003.tentative.html", {} ] ], @@ -216011,15 +216343,15 @@ {} ] ], - "html/rendering/non-replaced-elements/tables/form-in-tables.html": [ + "html/rendering/non-replaced-elements/tables/form-in-tables-xhtml.xhtml": [ [ - "/html/rendering/non-replaced-elements/tables/form-in-tables.html", + "/html/rendering/non-replaced-elements/tables/form-in-tables-xhtml.xhtml", {} ] ], - "html/rendering/non-replaced-elements/tables/form-in-tables.xhtml": [ + "html/rendering/non-replaced-elements/tables/form-in-tables.html": [ [ - "/html/rendering/non-replaced-elements/tables/form-in-tables.xhtml", + "/html/rendering/non-replaced-elements/tables/form-in-tables.html", {} ] ], @@ -218979,6 +219311,14 @@ } ] ], + "html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach.html": [ + [ + "/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach.html", + { + "timeout": "long" + } + ] + ], "html/semantics/embedded-content/the-img-element/decode/image-decode.html": [ [ "/html/semantics/embedded-content/the-img-element/decode/image-decode.html", @@ -220253,18 +220593,42 @@ {} ] ], + "html/semantics/forms/the-textarea-element/textarea-maxlength.html": [ + [ + "/html/semantics/forms/the-textarea-element/textarea-maxlength.html", + {} + ] + ], + "html/semantics/forms/the-textarea-element/textarea-minlength.html": [ + [ + "/html/semantics/forms/the-textarea-element/textarea-minlength.html", + {} + ] + ], "html/semantics/forms/the-textarea-element/textarea-setcustomvalidity.html": [ [ "/html/semantics/forms/the-textarea-element/textarea-setcustomvalidity.html", {} ] ], + "html/semantics/forms/the-textarea-element/textarea-textLength.html": [ + [ + "/html/semantics/forms/the-textarea-element/textarea-textLength.html", + {} + ] + ], "html/semantics/forms/the-textarea-element/textarea-type.html": [ [ "/html/semantics/forms/the-textarea-element/textarea-type.html", {} ] ], + "html/semantics/forms/the-textarea-element/textarea-validity-clone.html": [ + [ + "/html/semantics/forms/the-textarea-element/textarea-validity-clone.html", + {} + ] + ], "html/semantics/forms/the-textarea-element/value-defaultValue-textContent-xhtml.xhtml": [ [ "/html/semantics/forms/the-textarea-element/value-defaultValue-textContent-xhtml.xhtml", @@ -225895,9 +226259,13 @@ {} ] ], - "media-source/interfaces.html": [ + "media-source/idlharness.any.js": [ [ - "/media-source/interfaces.html", + "/media-source/idlharness.any.html", + {} + ], + [ + "/media-source/idlharness.any.worker.html", {} ] ], @@ -247621,9 +247989,9 @@ {} ] ], - "resize-observer/idlharness.html": [ + "resize-observer/idlharness.window.js": [ [ - "/resize-observer/idlharness.html", + "/resize-observer/idlharness.window.html", {} ] ], @@ -248205,9 +248573,9 @@ {} ] ], - "selection/interfaces.html": [ + "selection/idlharness.window.js": [ [ - "/selection/interfaces.html", + "/selection/idlharness.window.html", {} ] ], @@ -253789,9 +254157,9 @@ {} ] ], - "web-share/idlharness.https.html": [ + "web-share/idlharness.https.window.js": [ [ - "/web-share/idlharness.https.html", + "/web-share/idlharness.https.window.html", {} ] ], @@ -253825,9 +254193,9 @@ {} ] ], - "webaudio/idlharness.https.html": [ + "webaudio/idlharness.https.window.js": [ [ - "/webaudio/idlharness.https.html", + "/webaudio/idlharness.https.window.html", { "timeout": "long" } @@ -255701,9 +256069,9 @@ {} ] ], - "webrtc/RTCPeerConnection-addTransceiver.html": [ + "webrtc/RTCPeerConnection-addTransceiver.https.html": [ [ - "/webrtc/RTCPeerConnection-addTransceiver.html", + "/webrtc/RTCPeerConnection-addTransceiver.https.html", {} ] ], @@ -258275,9 +258643,9 @@ } ] ], - "webstorage/idlharness.html": [ + "webstorage/idlharness.window.js": [ [ - "/webstorage/idlharness.html", + "/webstorage/idlharness.window.html", {} ] ], @@ -268664,6 +269032,14 @@ "3b15af010f2ce13316fed6fcab9d85e05484b60d", "testharness" ], + "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self.html": [ + "ec6a6d1111aae9ce051cd1a2503a5b01149ceca6", + "reftest" + ], + "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html": [ + "f09c2922fc630872519fc37de47f232ecc8cc677", + "support" + ], "2dcontext/drawing-images-to-the-canvas/drawimage_html_image.html": [ "ec86f8f5c84628cd5f3b8673de8dde34dc372fd9", "testharness" @@ -274600,8 +274976,12 @@ "fccd52aeb8ce8476e31cd5a881c3284fa5c16556", "support" ], - "accelerometer/idlharness.https.html": [ - "93a78732bf63dcdd30ca1004f7ab850d5e7faaae", + "accelerometer/idlharness.https.window-expected.txt": [ + "b613fec755d4ffdd89b73e672ad6ad85f93a1a07", + "support" + ], + "accelerometer/idlharness.https.window.js": [ + "80f5c68be13e93686b4851871cc115bad160b633", "testharness" ], "accname/description_from_content_of_describedby_element-manual-expected.txt": [ @@ -275380,6 +275760,26 @@ "6177ea08e069fd1aca85fd3d772a53022b07f519", "support" ], + "background-fetch/idlharness.any-expected.txt": [ + "6d0c8ed4939faa52b94fede0968b379edca7daa5", + "support" + ], + "background-fetch/idlharness.any.js": [ + "5c0eebc307b9cdb534003593248b03004352dacd", + "testharness" + ], + "background-fetch/idlharness.any.sharedworker-expected.txt": [ + "d3818aef8b559e61186ed89c5343601e8f8164f3", + "support" + ], + "background-fetch/idlharness.any.worker-expected.txt": [ + "d3818aef8b559e61186ed89c5343601e8f8164f3", + "support" + ], + "background-fetch/idlharness.https.any.serviceworker-expected.txt": [ + "bc0333837b7e504edcc444ef0e41fcf6d97d6baf", + "support" + ], "background-fetch/interfaces-worker.https-expected.txt": [ "88211a0d44012d229af146366440ced5d12b0988", "support" @@ -275392,10 +275792,6 @@ "8a5cf2119205440349c364ccdeaa65ce3cf42791", "support" ], - "background-fetch/interfaces.https.any.js": [ - "34a07e3b0425cb5a1b940c9581573e2b3322724f", - "testharness" - ], "background-fetch/interfaces.https.any.worker-expected.txt": [ "66d01d6b1e71e7381f1a1b87b56372ffe850b27f", "support" @@ -277205,7 +277601,7 @@ "testharness" ], "content-security-policy/embedded-enforcement/idlharness.window.js": [ - "e009d639fbb4ede1085c365038fb79d1e0625143", + "a64a6a47127c3a770d9190df2d0a3ad570e32427", "testharness" ], "content-security-policy/embedded-enforcement/iframe-csp-attribute.html": [ @@ -313964,6 +314360,14 @@ "4b49a6bc4cfef048f3a4ac1d62feeb604e0d28a5", "reftest" ], + "css/css-images/idlharness-expected.txt": [ + "deb34377105c08e4511c5a4c8b90c58972679287", + "support" + ], + "css/css-images/idlharness.html": [ + "43a0b8582221d2cd3838fcf6ba93bc7198cbdbf1", + "testharness" + ], "css/css-images/image-fit-001.xht": [ "868d9469f57e6013a024efa5e04ef2455d97296e", "visual" @@ -314688,6 +315092,102 @@ "3ddf25363a61baa64374747cdfadeb9329e87f81", "support" ], + "css/css-lists/content-property/marker-text-matches-armenian-ref.html": [ + "36a124835188ab9172d59dcf8615d050f3b4b37d", + "support" + ], + "css/css-lists/content-property/marker-text-matches-armenian.html": [ + "08e07d745f07a15806d532ab2b859a528ea58f0b", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-circle-ref.html": [ + "5cf7f2cb8c066d220dfd441bb50aeec2f514bf25", + "support" + ], + "css/css-lists/content-property/marker-text-matches-circle.html": [ + "3191e867c0d1a02840977838fd13e25e12cdb491", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-decimal-leading-zero-ref.html": [ + "428d093039a3e489e0b5765b0dfe1a3587d1bf92", + "support" + ], + "css/css-lists/content-property/marker-text-matches-decimal-leading-zero.html": [ + "648d651fce939501916074632c5704764115fcd5", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-decimal-ref.html": [ + "f7c2fcd3655546e3d8e6d5fdd82523db81c69927", + "support" + ], + "css/css-lists/content-property/marker-text-matches-decimal.html": [ + "c00f56ab58e7fd3ce8a2fc281543ddcde05d26fb", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-disc-ref.html": [ + "6eee62533f2d54b12a5c9b39e93c3224cb2ffafb", + "support" + ], + "css/css-lists/content-property/marker-text-matches-disc.html": [ + "876d93ca33eac5044084c7a5d0e5e445f3770a98", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-georgian-ref.html": [ + "60f3e664d51a2a71df464f470cb644904f21f612", + "support" + ], + "css/css-lists/content-property/marker-text-matches-georgian.html": [ + "192b49e24f250a1b403ab4b4f815c2d916a17abd", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-lower-greek-ref.html": [ + "4f2732719698d51272bb5cccf891e64a016cef8d", + "support" + ], + "css/css-lists/content-property/marker-text-matches-lower-greek.html": [ + "967b17032b21f3a041fd69b00a7b10a78d6743e6", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-lower-latin-ref.html": [ + "0b9981e525a3bcfe86a1b837d32c70af5355f7c0", + "support" + ], + "css/css-lists/content-property/marker-text-matches-lower-latin.html": [ + "258697c2a8b72849da7e99db6fcb1e18bed313b1", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-lower-roman-ref.html": [ + "d0c2e9b1b84254e32956f9f26461f7d8751e17b8", + "support" + ], + "css/css-lists/content-property/marker-text-matches-lower-roman.html": [ + "8507450cf81d498202277ad20f47d9047b82803c", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-square-ref.html": [ + "1b69ce33b9dd6e674407f78937e47b3aa4d012af", + "support" + ], + "css/css-lists/content-property/marker-text-matches-square.html": [ + "198deb47052925b046d8b9f37ddb2b2109d29c25", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-upper-latin-ref.html": [ + "f2b5bb160a67b42add362f0bdd3d492f1992b3ff", + "support" + ], + "css/css-lists/content-property/marker-text-matches-upper-latin.html": [ + "5640698b5296d42d403591796cb35984d4f44e3a", + "reftest" + ], + "css/css-lists/content-property/marker-text-matches-upper-roman-ref.html": [ + "188a77cab595081eac21b18005a911cf2c3c53ec", + "support" + ], + "css/css-lists/content-property/marker-text-matches-upper-roman.html": [ + "5b66ea59ac497741a1501c3c6d91764fb8d99e0d", + "reftest" + ], "css/css-lists/counter-7-ref.html": [ "6391e214ad5262afaab7cd6caaf57e7f2506fb4d", "support" @@ -314748,7 +315248,11 @@ "ff44f2aadd8f274135c40ffc70a94b71df022718", "support" ], - "css/css-logical/animation-003.tenative.html": [ + "css/css-logical/animation-003.tentative-expected.txt": [ + "ff44f2aadd8f274135c40ffc70a94b71df022718", + "support" + ], + "css/css-logical/animation-003.tentative.html": [ "bdb7e952eb7fecf402f64129a00b511d89470195", "testharness" ], @@ -317940,6 +318444,14 @@ "7d4739f2252956461b38d8b8566a84ead3c1d8b1", "reftest" ], + "css/css-pseudo/marker-inherit-line-height-ref.html": [ + "e0b76bc582df84e630c911cd45a77bd714ae3727", + "support" + ], + "css/css-pseudo/marker-inherit-line-height.html": [ + "d6da862bc43db77db9e22a1fd1090a26a497e8cc", + "reftest" + ], "css/css-pseudo/marker-inherit-values-ref.html": [ "92bdc9d8f482c34ad389f27c957d4024a7e05b43", "support" @@ -323280,10 +323792,6 @@ "63bbe4f7fb67f33217876af58c1de4d032c369f4", "reftest" ], - "css/css-text/overflow-wrap/overflow-wrap-break-word-004.html": [ - "ca2b98f9db6ac13da149380dab3311301d741045", - "reftest" - ], "css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html": [ "9f88a667825f8cb725dc348e17081e1a25b3f4de", "reftest" @@ -324820,10 +325328,6 @@ "5ad54c7b9197746f66fa30628b6059a369f5bd36", "support" ], - "css/css-text/word-break/reference/word-break-break-all-010-ref.html": [ - "0b16a0bdb25ddd647ad96dd82e3430274667ee87", - "support" - ], "css/css-text/word-break/reference/word-break-break-all-ref-000.html": [ "765afbeeede3d3dd8ad33b88927d6eb8e5435463", "support" @@ -325000,14 +325504,6 @@ "fd5f0cf9f57152d3c6df7c4b59c0fe70733bf9f4", "manual" ], - "css/css-text/word-break/word-break-break-all-010.html": [ - "f9eedfe8e72bcf6693f8049bfdf2e1efdf3084ef", - "reftest" - ], - "css/css-text/word-break/word-break-break-all-011.html": [ - "047e950374d902e426287900a2d03c63726420a2", - "reftest" - ], "css/css-text/word-break/word-break-keep-all-000.html": [ "219e6b0435541a834ebbee114b0dd40e15956f75", "reftest" @@ -366836,12 +367332,12 @@ "1732dc6dd595354e21c7fb6006c32b844ceedf18", "reftest" ], - "html/rendering/non-replaced-elements/tables/form-in-tables.html": [ - "8319c136723513a019d48f66c663ce3673777bcd", + "html/rendering/non-replaced-elements/tables/form-in-tables-xhtml.xhtml": [ + "610932708cb18b8022ca64b8c9f3f59d8cf1ae56", "testharness" ], - "html/rendering/non-replaced-elements/tables/form-in-tables.xhtml": [ - "610932708cb18b8022ca64b8c9f3f59d8cf1ae56", + "html/rendering/non-replaced-elements/tables/form-in-tables.html": [ + "8319c136723513a019d48f66c663ce3673777bcd", "testharness" ], "html/rendering/non-replaced-elements/tables/hidden-attr-expected.txt": [ @@ -370668,6 +371164,10 @@ "9405efb65176096957438cbdcc59109b488d80e6", "testharness" ], + "html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach.html": [ + "cd7e495a854d848712b46cddec40e3ebffe9d3ba", + "testharness" + ], "html/semantics/embedded-content/the-img-element/decode/image-decode.html": [ "5368b62bf6c950e8d57b16b36148e5695ce16fd8", "testharness" @@ -371992,6 +372492,14 @@ "b61235681689807b5d46b8aaca9ae6c7a18039f7", "testharness" ], + "html/semantics/forms/the-textarea-element/textarea-maxlength.html": [ + "fb2796fe7e542bd9551c18c0176a4f822ee347cd", + "testharness" + ], + "html/semantics/forms/the-textarea-element/textarea-minlength.html": [ + "fcccb00d0db7222af1fb03e7481ccf31e51ec924", + "testharness" + ], "html/semantics/forms/the-textarea-element/textarea-newline-bidi-ref.html": [ "26eb3e615f8b0e15cf02b7ee18d39fd71b04da70", "support" @@ -372012,10 +372520,18 @@ "5f5932aeba8a0a7da66ee006a6e604780210d57b", "testharness" ], + "html/semantics/forms/the-textarea-element/textarea-textLength.html": [ + "0f9b8cdaace12d4f4e7fbd57a90fcba7e826ced5", + "testharness" + ], "html/semantics/forms/the-textarea-element/textarea-type.html": [ "81a270bc3c9304f8b2e7dd526519f4eab7d94f45", "testharness" ], + "html/semantics/forms/the-textarea-element/textarea-validity-clone.html": [ + "d0334cee779937e5d800e478013e5c8ffeaa6a1c", + "testharness" + ], "html/semantics/forms/the-textarea-element/value-defaultValue-textContent-expected.txt": [ "4f2f22b676dea822e14a2073fa9ea727488fdc95", "support" @@ -377936,10 +378452,6 @@ "d1220af2e8cc4fab720497311064666393eea7c8", "testharness" ], - "infrastructure/server/wpt-server-http.sub-expected.txt": [ - "f43e81e2a389b59723ff9787014c6d96a030e13b", - "support" - ], "infrastructure/server/wpt-server-http.sub.html": [ "2a400478de23a6aecf31bdc08b187784c36be629", "testharness" @@ -378089,7 +378601,7 @@ "support" ], "interfaces/background-fetch.idl": [ - "272d5ef66a2df3a6c3fefaf9688802ed93a9ad5f", + "4f744971f4eb6fc90bfb5fa4cc7514230e5e57dd", "support" ], "interfaces/battery-status.idl": [ @@ -378140,6 +378652,10 @@ "0019e54201874e5d2a2b10c887e44b8c42199c32", "support" ], + "interfaces/css-counter-styles.idl": [ + "437dd5859385f5a17f9b9b2509b8f50eeb42a717", + "support" + ], "interfaces/css-font-loading.idl": [ "9f2f252c5b63c159d9680de46a932bfa4335bf11", "support" @@ -378148,6 +378664,10 @@ "ff2d83e9468c743993c9b4a1ecf3fab09684dc16", "support" ], + "interfaces/css-images.idl": [ + "29ff2de2d9dac38494a4e2b7cfc6dfc2947f16c1", + "support" + ], "interfaces/css-masking.idl": [ "5f4ed3d8922e30ab3ddb714d185c6e6f794e5a29", "support" @@ -378156,6 +378676,10 @@ "9939fb7f08cab0f167e6e0762eac6ad94b2dfd9f", "support" ], + "interfaces/css-regions.idl": [ + "23d01fa1c91539c443b2227df6a89e377b65a393", + "support" + ], "interfaces/css-transitions.idl": [ "54dd701233a71187c8b675ebbf7336f852a7cace", "support" @@ -378268,6 +378792,10 @@ "dad6123e39feca39ec620de51307e56823cc5408", "support" ], + "interfaces/media-source.idl": [ + "a3c8e49db54b906ae99e2aa2cc385c0e4d949a80", + "support" + ], "interfaces/mediacapture-depth.idl": [ "2ac0dcf83f5afb227f24c9063d738dd22e941fe9", "support" @@ -378373,7 +378901,7 @@ "support" ], "interfaces/resource-timing.idl": [ - "75fcdf5c6ac811254e1a025cd58d958f27ab5b5b", + "d500e42e860b94614c0efeeb0b46d2ad7e8d79f9", "support" ], "interfaces/screen-orientation.idl": [ @@ -378389,7 +378917,7 @@ "support" ], "interfaces/selection-api.idl": [ - "10e7cdeb0e3c5e3871c81e30e89e72412d3f572f", + "622e064c826b3d25618e0bd6041e4297f9939d78", "support" ], "interfaces/server-timing.idl": [ @@ -378397,7 +378925,7 @@ "support" ], "interfaces/service-workers.idl": [ - "979a3b43c2db10f5a93213f46f1abf90082da22b", + "d219b474e3981be9cdeed598046e8002b4b48ddf", "support" ], "interfaces/shape-detection-api.idl": [ @@ -378409,7 +378937,7 @@ "support" ], "interfaces/touch-events.idl": [ - "00811ff421c7ecafb8070d1a3d17310e1228c725", + "4e456ecce04a5f8fb19a7be5ae0d9e5bd69a1ec1", "support" ], "interfaces/touchevents.idl": [ @@ -378976,6 +379504,18 @@ "fefa39b93290d8d97b18f606c5166d7792193251", "support" ], + "media-source/idlharness.any-expected.txt": [ + "5d955cd235b47e9a85ec1992410b576835e88040", + "support" + ], + "media-source/idlharness.any.js": [ + "d9b97ca6d0883ef11491723a5db5b9e92e32a380", + "testharness" + ], + "media-source/idlharness.any.worker-expected.txt": [ + "8abee7dbcb3581e009040a8b4cab306a0f5e7f4c", + "support" + ], "media-source/import_tests.sh": [ "943d26f264d59f2a7c01db30f5d91e72dafa9935", "support" @@ -378984,10 +379524,6 @@ "f7122a377e6ceb667a42f978dc549457d8c301e1", "support" ], - "media-source/interfaces.html": [ - "f836da38e12662cd56590d5a0534ad555dbf249e", - "testharness" - ], "media-source/manifest.txt": [ "d1e89d132c19294d2c7bb677668c03f3309b475e", "support" @@ -388640,10 +389176,6 @@ "01e6ebc11174b8de17212aaf004890685bd90fae", "manual" ], - "payment-method-basic-card/idlharness.window-expected.txt": [ - "d6c9c468cebdcd639c1d1d17beba93b3808751b1", - "support" - ], "payment-method-basic-card/idlharness.window.js": [ "0219c2651ea2bd20d1c694f4f450646a38b8513f", "testharness" @@ -389101,7 +389633,7 @@ "support" ], "picture-in-picture/disable-picture-in-picture.html": [ - "d97bf03a6e2f991c173248f9e28bd713da19a6f4", + "f80cdccd1c6edcf6a859a1ae2315a9f65188d812", "testharness" ], "picture-in-picture/enter-picture-in-picture.html": [ @@ -389113,11 +389645,11 @@ "testharness" ], "picture-in-picture/idlharness.window-expected.txt": [ - "a048d5c50c8e843efdfb66389f95f16b3e1bca6a", + "a9cf0a080146f82378696b5732b1d56da3b10368", "support" ], "picture-in-picture/idlharness.window.js": [ - "a2a5c08651d42ef14d4ffd1ac0fa0c56a7a2eb37", + "8861876d089790497afb99496c118ac24f43eadd", "testharness" ], "picture-in-picture/leave-picture-in-picture.html": [ @@ -389133,7 +389665,7 @@ "testharness" ], "picture-in-picture/request-picture-in-picture-twice.html": [ - "289c2decddd418722b3d5345b31706b4fad59ed3", + "c45cc223ec4336916d46c3d4db8bc4decbbd3332", "testharness" ], "picture-in-picture/request-picture-in-picture.html": [ @@ -389141,7 +389673,7 @@ "testharness" ], "picture-in-picture/resources/picture-in-picture-helpers.js": [ - "1d4f14127753148c7dfc4a79d2beec34410e416b", + "b41a3c97a777a69ab28eea3b33f464379303da3d", "support" ], "picture-in-picture/shadow-dom.html": [ @@ -389849,7 +390381,7 @@ "testharness" ], "presentation-api/controlling-ua/idlharness.https.html": [ - "75dca68e8398772129feacc28bfe574e9c8d402b", + "b369c2a6001fa89daffbee9dc588388c74c6badc", "testharness" ], "presentation-api/controlling-ua/reconnectToPresentation_notfound_error.https.html": [ @@ -398392,8 +398924,12 @@ "369f73cd032f618992d1746184927d0e78a920e8", "support" ], - "resize-observer/idlharness.html": [ - "2b1960834f7164e351cdbba119694830055dcf17", + "resize-observer/idlharness.window-expected.txt": [ + "50f625b9289202a2da470abb4b42c2e3a119a6a3", + "support" + ], + "resize-observer/idlharness.window.js": [ + "678952851933ad07531c0bebe6b9dc7be52dcdc3", "testharness" ], "resize-observer/notify.html": [ @@ -398433,7 +398969,7 @@ "testharness" ], "resource-timing/idlharness.any.js": [ - "a1bb5ee0f67683b42035fa683e9a984b0cf4d5dc", + "2065b03393c21199e49553ec99902aaddec74ce0", "testharness" ], "resource-timing/iframe-setdomain.sub.html": [ @@ -399056,14 +399592,18 @@ "4b5b638ae5cdaab02fbe9cca255a119134238a7d", "testharness" ], + "selection/idlharness.window-expected.txt": [ + "1bdfe84569e3607508422c62bc7b03ecfc2df38a", + "support" + ], + "selection/idlharness.window.js": [ + "2a89076946fd12a1629ef962c2e459accba952df", + "testharness" + ], "selection/interfaces-expected.txt": [ "8a53b2e46fc24e712365a3e1484acdca85752864", "support" ], - "selection/interfaces.html": [ - "78e92642e2562da8040c791e4c3a7ad1de53e600", - "testharness" - ], "selection/isCollapsed.html": [ "d1984a9359d880dfb81197e7ec31b2456833809d", "testharness" @@ -399820,6 +400360,14 @@ "ba24e1d89104fb25d5100dfa0b38388ca19ee9c1", "support" ], + "server-timing/resources/parsing/84.js": [ + "aa4b60a397c4704689621874403329c705598c9c", + "support" + ], + "server-timing/resources/parsing/84.js.sub.headers": [ + "94fd8cac84f6fdc22d8b46786ac690f788e657f4", + "support" + ], "server-timing/resources/parsing/9.js": [ "5660bb21eb42f322a58f80c6c001d14c6e0fc0c9", "support" @@ -399829,19 +400377,19 @@ "support" ], "server-timing/server_timing_header-parsing-expected.txt": [ - "87ae6268c574b3305a79fc1376d7a62aa7587f2d", + "3fb854f9b672fcac8995d77ba7d23e996c8f3485", "support" ], "server-timing/server_timing_header-parsing.html": [ - "10f756bbf749b7ad8f7c6eb4efe752ee79c44b4a", + "8df39d7b393cb0ae6dac1997b2d8755210a97ea5", "testharness" ], "server-timing/server_timing_header-parsing.https-expected.txt": [ - "ef70b0cf8dbcb0090957b0bba170ee610b11a39d", + "531ef8b2e35dc7b7984fb6ce4a84eead76fb3a12", "support" ], "server-timing/server_timing_header-parsing.https.html": [ - "10f756bbf749b7ad8f7c6eb4efe752ee79c44b4a", + "8df39d7b393cb0ae6dac1997b2d8755210a97ea5", "testharness" ], "server-timing/service_worker_idl.https.html": [ @@ -400685,7 +401233,7 @@ "testharness" ], "service-workers/service-worker/interfaces-window.https.html": [ - "71c0e09861863b9f36571137d2398fa8af516601", + "18b96c6b13d9b561e2fdb1eca32872d6596c76b0", "testharness" ], "service-workers/service-worker/invalid-blobtype.https.html": [ @@ -401580,12 +402128,8 @@ "0f2d441a80fb4641af35ad851e86690b7c02d1f7", "support" ], - "service-workers/service-worker/resources/interfaces-idls.js": [ - "2d3ae3bdd1be17a2871aa3af2009daaacf43d3db", - "support" - ], "service-workers/service-worker/resources/interfaces-worker.sub.js": [ - "694568194185de15fb912b3e4b4655ea3f65420d", + "cd067da4cc6683916037aaf13d71f6309f04460b", "support" ], "service-workers/service-worker/resources/invalid-blobtype-iframe.https.html": [ @@ -404892,6 +405436,10 @@ "3d51ca0fc007d52147e7ea03493cac7ee1bb7903", "reftest" ], + "svg/linking/reftests/use-descendant-combinator-003.html": [ + "d9155d3b92ecf0735f82ed9a0f2a8fd3fc380d55", + "reftest" + ], "svg/linking/reftests/use-descendant-combinator-ref.html": [ "fb8aec792684b97151d2964b85d1e70829e141ad", "support" @@ -405048,6 +405596,22 @@ "03751dba3c2dfc7b4d478879dc94878b0dffcc99", "reftest" ], + "svg/render/reftests/blending-001-ref.svg": [ + "2eab909f1ad53777522f75b968e73879236573f9", + "support" + ], + "svg/render/reftests/blending-001.svg": [ + "5503dc3d96e7fa0c5884f6692469010fe28e4527", + "reftest" + ], + "svg/render/reftests/blending-002-ref.svg": [ + "cf08e0892c32439a738b1eef93683702b6139990", + "support" + ], + "svg/render/reftests/blending-002.svg": [ + "f77800e686cee3007fb7c40574c61b22d65217ef", + "reftest" + ], "svg/rendering/order/z-index-ref.svg": [ "955f465ece3132da0bdd1e3b832e97db84f22b55", "support" @@ -405449,7 +406013,7 @@ "support" ], "touch-events/idlharness.window.js": [ - "c5bcdd44381f6f49f0e653c48d05cc14c93f424a", + "8a4eee7d4002836a205a1cd0aceb3a8008a1a929", "testharness" ], "touch-events/multi-touch-interactions.js": [ @@ -407608,8 +408172,8 @@ "07eb3c26df43537e0735d741c8bdc8c041b91175", "support" ], - "web-share/idlharness.https.html": [ - "17e370aefd324ffac6a6f4b0211fbaecd1781ad4", + "web-share/idlharness.https.window.js": [ + "cd9160bc9790e6e734a73a1f0656f70f8583e246", "testharness" ], "web-share/resources/manual-helper.js": [ @@ -407705,15 +408269,19 @@ "support" ], "webaudio/historical.html": [ - "93068df297042344669093ce899f0230c87ebf54", + "c6e3c7d6751731c708edfb0f4e32df8a6a3b80b0", "testharness" ], "webaudio/idlharness.https-expected.txt": [ "451ba6e7843b5bc4e64983f0ac2aac11467f91e4", "support" ], - "webaudio/idlharness.https.html": [ - "0403de985b3346240ba1d4b465a8e0838f3860bc", + "webaudio/idlharness.https.window-expected.txt": [ + "77fb40fa0aeedc7f4d8e90d1d51f847895128fbf", + "support" + ], + "webaudio/idlharness.https.window.js": [ + "cadc212b4ecb16e95581e34886f49f0357c593bc", "testharness" ], "webaudio/js/buffer-loader.js": [ @@ -409432,11 +410000,11 @@ "74096ec62288029bf7aea81008e63e43a5f40549", "testharness" ], - "webrtc/RTCPeerConnection-addTransceiver-expected.txt": [ + "webrtc/RTCPeerConnection-addTransceiver.https-expected.txt": [ "f081cfd4da18191f04c211a70735b7142907e61f", "support" ], - "webrtc/RTCPeerConnection-addTransceiver.html": [ + "webrtc/RTCPeerConnection-addTransceiver.https.html": [ "3d1531048c244d0f3391d6fe30e7c8bc7e13ef35", "testharness" ], @@ -409537,7 +410105,7 @@ "testharness" ], "webrtc/RTCPeerConnection-helper.js": [ - "e92d33cfb3fdacc6a2f172ecfe3444a1ced5680e", + "4c2699a8df315a475f1037a3ac8dcbb313f2757b", "support" ], "webrtc/RTCPeerConnection-iceConnectionState-expected.txt": [ @@ -409829,11 +410397,11 @@ "testharness" ], "webrtc/RTCRtpSender-replaceTrack.https-expected.txt": [ - "a6b5ff94414685af0bb1f94f914c47270f26f7b5", + "0addd08af3b15ccf95020bdcd609732d37535a50", "support" ], "webrtc/RTCRtpSender-replaceTrack.https.html": [ - "ea6ff719d0939e22fd5af2c72af009a1c9602c93", + "c73569cdd7272bdda237661599f6c1f62b4c1f0c", "testharness" ], "webrtc/RTCRtpSender-setParameters-expected.txt": [ @@ -411152,8 +411720,8 @@ "6ba7d14a894e782495d818e43f4b0901607c207e", "support" ], - "webstorage/idlharness.html": [ - "9bbb03ed7a846411183963fba16241a107652c0f", + "webstorage/idlharness.window.js": [ + "4aeab6abb761637eeb0d03e6f95dcc5c8a9e00c1", "testharness" ], "webstorage/missing_arguments.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self.html b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self.html new file mode 100644 index 0000000..83cf535 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self.html
@@ -0,0 +1,17 @@ +<link rel="match" href="drawimage_canvas_self_ref.html"> +<canvas id="dest" height="100" width="100"></canvas> +<script> +var canvasWidth = canvasHeight = 100; +var destWidth = canvasWidth / 4; +var destHeight = canvasHeight / 4; +var destCanvas = document.getElementById('dest'); +var destCtx = destCanvas.getContext('2d'); + +destCtx.fillStyle = 'red'; +destCtx.fillRect(0, 0, canvasWidth, canvasHeight); +destCtx.fillStyle = 'green'; +destCtx.fillRect(0, 0, canvasWidth / 2, canvasHeight / 2); +destCtx.drawImage(destCanvas, + 0, 0, destWidth, destHeight, + canvasWidth / 2, canvasHeight / 2, destWidth, destHeight); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html new file mode 100644 index 0000000..9f297ca --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html
@@ -0,0 +1,11 @@ +<canvas id="dest" height="100" width="100"></canvas> +<script> +var canvasWidth = canvasHeight = 100; +var destCanvas = document.getElementById('dest'); +var destCtx = destCanvas.getContext('2d'); +destCtx.fillStyle = 'red'; +destCtx.fillRect(0, 0, canvasWidth, canvasHeight); +destCtx.fillStyle = 'green'; +destCtx.fillRect(0, 0, canvasWidth / 2, canvasHeight / 2); +destCtx.fillRect(canvasWidth / 2, canvasHeight / 2, canvasWidth / 4, canvasHeight / 4); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.html deleted file mode 100644 index 1f32be9..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.html +++ /dev/null
@@ -1,39 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>Accelerometer Sensor IDL tests</title> -<link rel="author" title="Intel" href="http://www.intel.com"> -<link rel="help" href="https://w3c.github.io/accelerometer/"> -<link rel="help" href="https://w3c.github.io/sensors/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/WebIDLParser.js"></script> -<script src="/resources/idlharness.js"></script> -<script> -"use strict"; - -function doTest([dom, generic_sensor, accelerometer]) { - const idl_array = new IdlArray(); - idl_array.add_untested_idls(dom); - idl_array.add_untested_idls('interface EventHandler {};'); - idl_array.add_idls(generic_sensor, { only: ['Sensor', 'SensorOptions'] }); - idl_array.add_idls(accelerometer); - idl_array.add_objects({ - Accelerometer: ['new Accelerometer();'], - LinearAccelerationSensor: ['new LinearAccelerationSensor();'], - GravitySensor: ['new GravitySensor();'] - }); - idl_array.test(); -} - -function fetchText(url) { - return fetch(url).then((response) => response.text()); -} - -promise_test(() => { - return Promise.all([ - "/interfaces/dom.idl", - "/interfaces/sensors.idl", - "/interfaces/accelerometer.idl", - ].map(fetchText)).then(doTest); -}, "Test IDL implementation of Accelerometer Sensor"); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.window-expected.txt new file mode 100644 index 0000000..cacfccf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.window-expected.txt
@@ -0,0 +1,43 @@ +This is a testharness.js-based test. +PASS Test IDL implementation of Accelerometer Sensor +PASS Accelerometer interface: existence and properties of interface object +PASS Accelerometer interface object length +PASS Accelerometer interface object name +PASS Accelerometer interface: existence and properties of interface prototype object +PASS Accelerometer interface: existence and properties of interface prototype object's "constructor" property +PASS Accelerometer interface: existence and properties of interface prototype object's @@unscopables property +PASS Accelerometer interface: attribute x +PASS Unscopable handled correctly for x property on Accelerometer +PASS Accelerometer interface: attribute y +PASS Unscopable handled correctly for y property on Accelerometer +PASS Accelerometer interface: attribute z +PASS Unscopable handled correctly for z property on Accelerometer +PASS Accelerometer must be primary interface of new Accelerometer(); +PASS Stringification of new Accelerometer(); +PASS Accelerometer interface: new Accelerometer(); must inherit property "x" with the proper type +PASS Accelerometer interface: new Accelerometer(); must inherit property "y" with the proper type +PASS Accelerometer interface: new Accelerometer(); must inherit property "z" with the proper type +PASS LinearAccelerationSensor interface: existence and properties of interface object +PASS LinearAccelerationSensor interface object length +PASS LinearAccelerationSensor interface object name +PASS LinearAccelerationSensor interface: existence and properties of interface prototype object +PASS LinearAccelerationSensor interface: existence and properties of interface prototype object's "constructor" property +PASS LinearAccelerationSensor interface: existence and properties of interface prototype object's @@unscopables property +PASS LinearAccelerationSensor must be primary interface of new LinearAccelerationSensor(); +PASS Stringification of new LinearAccelerationSensor(); +PASS Accelerometer interface: new LinearAccelerationSensor(); must inherit property "x" with the proper type +PASS Accelerometer interface: new LinearAccelerationSensor(); must inherit property "y" with the proper type +PASS Accelerometer interface: new LinearAccelerationSensor(); must inherit property "z" with the proper type +FAIL GravitySensor interface: existence and properties of interface object assert_own_property: self does not have own property "GravitySensor" expected property "GravitySensor" missing +FAIL GravitySensor interface object length assert_own_property: self does not have own property "GravitySensor" expected property "GravitySensor" missing +FAIL GravitySensor interface object name assert_own_property: self does not have own property "GravitySensor" expected property "GravitySensor" missing +FAIL GravitySensor interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GravitySensor" expected property "GravitySensor" missing +FAIL GravitySensor interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GravitySensor" expected property "GravitySensor" missing +FAIL GravitySensor interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GravitySensor" expected property "GravitySensor" missing +FAIL GravitySensor must be primary interface of new GravitySensor(); assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: GravitySensor is not defined" +FAIL Stringification of new GravitySensor(); assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: GravitySensor is not defined" +FAIL Accelerometer interface: new GravitySensor(); must inherit property "x" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: GravitySensor is not defined" +FAIL Accelerometer interface: new GravitySensor(); must inherit property "y" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: GravitySensor is not defined" +FAIL Accelerometer interface: new GravitySensor(); must inherit property "z" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: GravitySensor is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.window.js b/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.window.js new file mode 100644 index 0000000..f6cbcd96 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/accelerometer/idlharness.https.window.js
@@ -0,0 +1,19 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// https://w3c.github.io/accelerometer/ + +"use strict"; + +idl_test( + ['accelerometer'], + ['generic-sensor', 'dom'], + idl_array => { + idl_array.add_objects({ + Accelerometer: ['new Accelerometer();'], + LinearAccelerationSensor: ['new LinearAccelerationSensor();'], + GravitySensor: ['new GravitySensor();'] + }); + }, + 'Test IDL implementation of Accelerometer Sensor' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any-expected.txt new file mode 100644 index 0000000..6faed0f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any-expected.txt
@@ -0,0 +1,80 @@ +This is a testharness.js-based test. +Found 76 tests; 58 PASS, 18 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS background-fetch interfaces +PASS Partial interface ServiceWorkerGlobalScope: original interface defined +PASS Partial interface ServiceWorkerRegistration: original interface defined +PASS BackgroundFetchManager interface: existence and properties of interface object +PASS BackgroundFetchManager interface object length +PASS BackgroundFetchManager interface object name +PASS BackgroundFetchManager interface: existence and properties of interface prototype object +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchManager interface: operation fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) +PASS Unscopable handled correctly for fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation get(DOMString) +PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation getIds() +PASS Unscopable handled correctly for getIds() on BackgroundFetchManager +PASS BackgroundFetchRegistration interface: existence and properties of interface object +PASS BackgroundFetchRegistration interface object length +PASS BackgroundFetchRegistration interface object name +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchRegistration interface: attribute id +PASS Unscopable handled correctly for id property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploadTotal +PASS Unscopable handled correctly for uploadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploaded +PASS Unscopable handled correctly for uploaded property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloadTotal +PASS Unscopable handled correctly for downloadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloaded +PASS Unscopable handled correctly for downloaded property on BackgroundFetchRegistration +FAIL BackgroundFetchRegistration interface: attribute activeFetches assert_true: The prototype object must have a property "activeFetches" expected true got false +PASS Unscopable handled correctly for activeFetches property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute onprogress +PASS Unscopable handled correctly for onprogress property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: operation abort() +PASS Unscopable handled correctly for abort() on BackgroundFetchRegistration +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: operation match(RequestInfo, CacheQueryOptions) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation matchAll(RequestInfo, CacheQueryOptions) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for matchAll(RequestInfo, CacheQueryOptions) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation values() assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for values() on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: attribute responseReady assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +PASS Unscopable handled correctly for responseReady property on BackgroundFetchActiveFetch +PASS BackgroundFetchFetch interface: existence and properties of interface object +PASS BackgroundFetchFetch interface object length +PASS BackgroundFetchFetch interface object name +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchFetch interface: attribute request +PASS Unscopable handled correctly for request property on BackgroundFetchFetch +PASS BackgroundFetchEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledFetches interface: existence and properties of interface object +PASS BackgroundFetchSettledFetch interface: existence and properties of interface object +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface object +PASS BackgroundFetchClickEvent interface: existence and properties of interface object +FAIL ServiceWorkerRegistration interface: attribute backgroundFetch assert_own_property: self does not have own property "ServiceWorkerRegistration" expected property "ServiceWorkerRegistration" missing +PASS Unscopable handled correctly for backgroundFetch property on ServiceWorkerRegistration +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS ExtendableEvent interface: existence and properties of interface object +PASS WorkerGlobalScope interface: existence and properties of interface object +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.js new file mode 100644 index 0000000..ad20477 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.js
@@ -0,0 +1,25 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://wicg.github.io/background-fetch/ + +idl_test( + ['background-fetch'], + ['service-workers', 'dedicated-workers', 'dom'], + idl_array => { + const isServiceWorker = location.pathname.includes('.serviceworker.'); + if (isServiceWorker) { + idl_array.add_objects({ + ServiceWorkerGlobalScope: ['self'], + ServiceWorkerRegistration: ['registration'], + BackgroundFetchManager: ['registration.backgroundFetch'], + BackgroundFetchEvent: ['new BackgroundFetchEvent("type")'], + BackgroundFetchUpdateEvent: ['new BackgroundFetchUpdateEvent("type")'], + }); + } + }, + 'background-fetch interfaces' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.sharedworker-expected.txt new file mode 100644 index 0000000..5f3ed505 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.sharedworker-expected.txt
@@ -0,0 +1,79 @@ +This is a testharness.js-based test. +Found 75 tests; 57 PASS, 18 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS background-fetch interfaces +PASS Partial interface ServiceWorkerGlobalScope: original interface defined +PASS Partial interface ServiceWorkerRegistration: original interface defined +PASS BackgroundFetchManager interface: existence and properties of interface object +PASS BackgroundFetchManager interface object length +PASS BackgroundFetchManager interface object name +PASS BackgroundFetchManager interface: existence and properties of interface prototype object +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchManager interface: operation fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) +PASS Unscopable handled correctly for fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation get(DOMString) +PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation getIds() +PASS Unscopable handled correctly for getIds() on BackgroundFetchManager +PASS BackgroundFetchRegistration interface: existence and properties of interface object +PASS BackgroundFetchRegistration interface object length +PASS BackgroundFetchRegistration interface object name +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchRegistration interface: attribute id +PASS Unscopable handled correctly for id property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploadTotal +PASS Unscopable handled correctly for uploadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploaded +PASS Unscopable handled correctly for uploaded property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloadTotal +PASS Unscopable handled correctly for downloadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloaded +PASS Unscopable handled correctly for downloaded property on BackgroundFetchRegistration +FAIL BackgroundFetchRegistration interface: attribute activeFetches assert_true: The prototype object must have a property "activeFetches" expected true got false +PASS Unscopable handled correctly for activeFetches property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute onprogress +PASS Unscopable handled correctly for onprogress property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: operation abort() +PASS Unscopable handled correctly for abort() on BackgroundFetchRegistration +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: operation match(RequestInfo, CacheQueryOptions) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation matchAll(RequestInfo, CacheQueryOptions) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for matchAll(RequestInfo, CacheQueryOptions) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation values() assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for values() on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: attribute responseReady assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +PASS Unscopable handled correctly for responseReady property on BackgroundFetchActiveFetch +PASS BackgroundFetchFetch interface: existence and properties of interface object +PASS BackgroundFetchFetch interface object length +PASS BackgroundFetchFetch interface object name +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchFetch interface: attribute request +PASS Unscopable handled correctly for request property on BackgroundFetchFetch +PASS BackgroundFetchEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledFetches interface: existence and properties of interface object +PASS BackgroundFetchSettledFetch interface: existence and properties of interface object +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface object +PASS BackgroundFetchClickEvent interface: existence and properties of interface object +FAIL ServiceWorkerRegistration interface: attribute backgroundFetch assert_own_property: self does not have own property "ServiceWorkerRegistration" expected property "ServiceWorkerRegistration" missing +PASS Unscopable handled correctly for backgroundFetch property on ServiceWorkerRegistration +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS ExtendableEvent interface: existence and properties of interface object +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.worker-expected.txt new file mode 100644 index 0000000..5f3ed505 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.any.worker-expected.txt
@@ -0,0 +1,79 @@ +This is a testharness.js-based test. +Found 75 tests; 57 PASS, 18 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS background-fetch interfaces +PASS Partial interface ServiceWorkerGlobalScope: original interface defined +PASS Partial interface ServiceWorkerRegistration: original interface defined +PASS BackgroundFetchManager interface: existence and properties of interface object +PASS BackgroundFetchManager interface object length +PASS BackgroundFetchManager interface object name +PASS BackgroundFetchManager interface: existence and properties of interface prototype object +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchManager interface: operation fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) +PASS Unscopable handled correctly for fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation get(DOMString) +PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation getIds() +PASS Unscopable handled correctly for getIds() on BackgroundFetchManager +PASS BackgroundFetchRegistration interface: existence and properties of interface object +PASS BackgroundFetchRegistration interface object length +PASS BackgroundFetchRegistration interface object name +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchRegistration interface: attribute id +PASS Unscopable handled correctly for id property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploadTotal +PASS Unscopable handled correctly for uploadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploaded +PASS Unscopable handled correctly for uploaded property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloadTotal +PASS Unscopable handled correctly for downloadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloaded +PASS Unscopable handled correctly for downloaded property on BackgroundFetchRegistration +FAIL BackgroundFetchRegistration interface: attribute activeFetches assert_true: The prototype object must have a property "activeFetches" expected true got false +PASS Unscopable handled correctly for activeFetches property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute onprogress +PASS Unscopable handled correctly for onprogress property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: operation abort() +PASS Unscopable handled correctly for abort() on BackgroundFetchRegistration +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: operation match(RequestInfo, CacheQueryOptions) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation matchAll(RequestInfo, CacheQueryOptions) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for matchAll(RequestInfo, CacheQueryOptions) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation values() assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for values() on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: attribute responseReady assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +PASS Unscopable handled correctly for responseReady property on BackgroundFetchActiveFetch +PASS BackgroundFetchFetch interface: existence and properties of interface object +PASS BackgroundFetchFetch interface object length +PASS BackgroundFetchFetch interface object name +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchFetch interface: attribute request +PASS Unscopable handled correctly for request property on BackgroundFetchFetch +PASS BackgroundFetchEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledFetches interface: existence and properties of interface object +PASS BackgroundFetchSettledFetch interface: existence and properties of interface object +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface object +PASS BackgroundFetchClickEvent interface: existence and properties of interface object +FAIL ServiceWorkerRegistration interface: attribute backgroundFetch assert_own_property: self does not have own property "ServiceWorkerRegistration" expected property "ServiceWorkerRegistration" missing +PASS Unscopable handled correctly for backgroundFetch property on ServiceWorkerRegistration +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS ExtendableEvent interface: existence and properties of interface object +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.https.any.serviceworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.https.any.serviceworker-expected.txt new file mode 100644 index 0000000..d897833 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/idlharness.https.any.serviceworker-expected.txt
@@ -0,0 +1,130 @@ +This is a testharness.js-based test. +PASS background-fetch interfaces +PASS Partial interface ServiceWorkerGlobalScope: original interface defined +PASS Partial interface ServiceWorkerRegistration: original interface defined +PASS BackgroundFetchManager interface: existence and properties of interface object +PASS BackgroundFetchManager interface object length +PASS BackgroundFetchManager interface object name +PASS BackgroundFetchManager interface: existence and properties of interface prototype object +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchManager interface: operation fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) +PASS Unscopable handled correctly for fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation get(DOMString) +PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation getIds() +PASS Unscopable handled correctly for getIds() on BackgroundFetchManager +PASS BackgroundFetchRegistration interface: existence and properties of interface object +PASS BackgroundFetchRegistration interface object length +PASS BackgroundFetchRegistration interface object name +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchRegistration interface: attribute id +PASS Unscopable handled correctly for id property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploadTotal +PASS Unscopable handled correctly for uploadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploaded +PASS Unscopable handled correctly for uploaded property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloadTotal +PASS Unscopable handled correctly for downloadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloaded +PASS Unscopable handled correctly for downloaded property on BackgroundFetchRegistration +FAIL BackgroundFetchRegistration interface: attribute activeFetches assert_true: The prototype object must have a property "activeFetches" expected true got false +PASS Unscopable handled correctly for activeFetches property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute onprogress +PASS Unscopable handled correctly for onprogress property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: operation abort() +PASS Unscopable handled correctly for abort() on BackgroundFetchRegistration +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: operation match(RequestInfo, CacheQueryOptions) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation matchAll(RequestInfo, CacheQueryOptions) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for matchAll(RequestInfo, CacheQueryOptions) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation values() assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for values() on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: attribute responseReady assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +PASS Unscopable handled correctly for responseReady property on BackgroundFetchActiveFetch +PASS BackgroundFetchFetch interface: existence and properties of interface object +PASS BackgroundFetchFetch interface object length +PASS BackgroundFetchFetch interface object name +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchFetch interface: attribute request +PASS Unscopable handled correctly for request property on BackgroundFetchFetch +PASS BackgroundFetchEvent interface: existence and properties of interface object +PASS BackgroundFetchEvent interface object length +PASS BackgroundFetchEvent interface object name +PASS BackgroundFetchEvent interface: existence and properties of interface prototype object +PASS BackgroundFetchEvent interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchEvent interface: attribute id +PASS Unscopable handled correctly for id property on BackgroundFetchEvent +PASS BackgroundFetchSettledEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledEvent interface object length +PASS BackgroundFetchSettledEvent interface object name +PASS BackgroundFetchSettledEvent interface: existence and properties of interface prototype object +PASS BackgroundFetchSettledEvent interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchSettledEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchSettledEvent interface: attribute fetches +PASS Unscopable handled correctly for fetches property on BackgroundFetchSettledEvent +PASS BackgroundFetchSettledFetches interface: existence and properties of interface object +PASS BackgroundFetchSettledFetches interface object length +PASS BackgroundFetchSettledFetches interface object name +PASS BackgroundFetchSettledFetches interface: existence and properties of interface prototype object +PASS BackgroundFetchSettledFetches interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchSettledFetches interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchSettledFetches interface: operation match(RequestInfo, CacheQueryOptions) +PASS Unscopable handled correctly for match(RequestInfo, CacheQueryOptions) on BackgroundFetchSettledFetches +FAIL BackgroundFetchSettledFetches interface: operation matchAll(RequestInfo, CacheQueryOptions) assert_own_property: interface prototype object missing non-static operation expected property "matchAll" missing +PASS Unscopable handled correctly for matchAll(RequestInfo, CacheQueryOptions) on BackgroundFetchSettledFetches +PASS BackgroundFetchSettledFetches interface: operation values() +PASS Unscopable handled correctly for values() on BackgroundFetchSettledFetches +PASS BackgroundFetchSettledFetch interface: existence and properties of interface object +FAIL BackgroundFetchSettledFetch interface object length assert_equals: wrong value for BackgroundFetchSettledFetch.length expected 0 but got 2 +PASS BackgroundFetchSettledFetch interface object name +PASS BackgroundFetchSettledFetch interface: existence and properties of interface prototype object +PASS BackgroundFetchSettledFetch interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchSettledFetch interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchSettledFetch interface: attribute response +PASS Unscopable handled correctly for response property on BackgroundFetchSettledFetch +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface object +PASS BackgroundFetchUpdateEvent interface object length +PASS BackgroundFetchUpdateEvent interface object name +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface prototype object +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchUpdateEvent interface: operation updateUI(DOMString) +PASS Unscopable handled correctly for updateUI(DOMString) on BackgroundFetchUpdateEvent +PASS BackgroundFetchClickEvent interface: existence and properties of interface object +PASS BackgroundFetchClickEvent interface object length +PASS BackgroundFetchClickEvent interface object name +PASS BackgroundFetchClickEvent interface: existence and properties of interface prototype object +PASS BackgroundFetchClickEvent interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchClickEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchClickEvent interface: attribute state +PASS Unscopable handled correctly for state property on BackgroundFetchClickEvent +PASS ServiceWorkerRegistration interface: attribute backgroundFetch +PASS Unscopable handled correctly for backgroundFetch property on ServiceWorkerRegistration +PASS ServiceWorkerGlobalScope interface: attribute onbackgroundfetched +PASS Unscopable handled correctly for onbackgroundfetched property on ServiceWorkerGlobalScope +PASS ServiceWorkerGlobalScope interface: attribute onbackgroundfetchfail +PASS Unscopable handled correctly for onbackgroundfetchfail property on ServiceWorkerGlobalScope +PASS ServiceWorkerGlobalScope interface: attribute onbackgroundfetchabort +PASS Unscopable handled correctly for onbackgroundfetchabort property on ServiceWorkerGlobalScope +PASS ServiceWorkerGlobalScope interface: attribute onbackgroundfetchclick +PASS Unscopable handled correctly for onbackgroundfetchclick property on ServiceWorkerGlobalScope +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.js deleted file mode 100644 index b95b856..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.js +++ /dev/null
@@ -1,24 +0,0 @@ -// META: script=/resources/WebIDLParser.js -// META: script=/resources/idlharness.js - -'use strict'; - -// https://wicg.github.io/background-fetch/ - -promise_test(async () => { - const srcs = [ - 'background-fetch', - 'dedicated-workers', - 'service-workers', - 'dom' - ]; - const [idls, worker, serviceWorker, dom] = await Promise.all( - srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); - - var idlArray = new IdlArray(); - idlArray.add_idls(idls); - idlArray.add_dependency_idls(serviceWorker); - idlArray.add_dependency_idls(worker); - idlArray.add_dependency_idls(dom); - idlArray.test(); -}, 'background-fetch interfaces');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/idlharness.window.js b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/idlharness.window.js index 38fa663..6ac306c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/idlharness.window.js +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/idlharness.window.js
@@ -5,17 +5,13 @@ 'use strict'; -promise_test(async () => { - const idl = await fetch('/interfaces/csp-embedded-enforcement.idl').then(r => r.text()); - const html = await fetch('/interfaces/html.idl').then(r => r.text()); - const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); - - const idl_array = new IdlArray(); - idl_array.add_idls(idl); - idl_array.add_dependency_idls(html); - idl_array.add_dependency_idls(dom); - idl_array.add_objects({ - HTMLIFrameElement: ['document.createElement("iframe")'], - }); - idl_array.test(); -}, 'csp-embedded-enforcement IDL'); +idl_test( + ['csp-embedded-enforcement'], + ['html', 'dom'], + idl_array => { + idl_array.add_objects({ + HTMLIFrameElement: ['document.createElement("iframe")'], + }); + }, + 'csp-embedded-enforcement IDL' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/position-absolute-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/position-absolute-001.html index 3c3d593..f601740 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/position-absolute-001.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/position-absolute-001.html
@@ -692,7 +692,7 @@ flexbox.className = 'flexbox ' + flexboxClassName; flexbox.setAttribute('style', mainAxis + ': 80px;' + crossAxis + ': 20px'); - var baselineMargin = (flexDirection.indexOf('row') != -1) ? '-webkit-margin-before: 5px' : '-webkit-margin-start: 5px'; + var baselineMargin = (flexDirection.indexOf('row') != -1) ? 'margin-block-start: 5px' : 'margin-inline-start: 5px'; var testExpectations = expectations[writingMode][flexDirection][direction][justifyContent]; addChild(flexbox, mainAxis, crossAxis, 40, 10, testExpectations['child1']);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-images/idlharness-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/idlharness-expected.txt new file mode 100644 index 0000000..594163a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/idlharness-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Test IDL implementation of css-masking +FAIL Partial namespace CSS: original namespace defined assert_true: Original CSS definition should have type namespace expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-images/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/idlharness.html new file mode 100644 index 0000000..ec9c358 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/idlharness.html
@@ -0,0 +1,19 @@ +<!doctype html> +<title>css-images IDL tests</title> +<link rel="help" href="https://drafts.csswg.org/css-images-4/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/WebIDLParser.js"></script> +<script src="/resources/idlharness.js"></script> +<script> + 'use strict'; + + idl_test( + ['css-images'], + ['cssom'], + idl_array => { + // No objects, + }, + 'Test IDL implementation of css-masking' + ); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-armenian-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-armenian-ref.html new file mode 100644 index 0000000..f21dfff --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-armenian-ref.html
@@ -0,0 +1,10 @@ +<!doctype html> +<meta charset=utf8> +<title>Reference: Inside list marker and normal text render identically: armenian</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>Ա. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-armenian.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-armenian.html new file mode 100644 index 0000000..fd0df63 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-armenian.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: armenian</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-armenian-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: armenian inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-circle-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-circle-ref.html new file mode 100644 index 0000000..60a342f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-circle-ref.html
@@ -0,0 +1,12 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: circle</title> +<style> +* { + margin: 0; + padding: 0; +} +p::before { + content: counter(test, circle); +} +</style> +<p> Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-circle.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-circle.html new file mode 100644 index 0000000..138f73c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-circle.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: circle</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-circle-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: circle inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-leading-zero-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-leading-zero-ref.html new file mode 100644 index 0000000..997801d5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-leading-zero-ref.html
@@ -0,0 +1,9 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: decimal-leading-zero</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>01. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-leading-zero.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-leading-zero.html new file mode 100644 index 0000000..5044d4e6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-leading-zero.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: decimal-leading-zero</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-decimal-leading-zero-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: decimal-leading-zero inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-ref.html new file mode 100644 index 0000000..8f97cc36 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal-ref.html
@@ -0,0 +1,9 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: decimal</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>1. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal.html new file mode 100644 index 0000000..8c991bc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-decimal.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: decimal</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-decimal-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: decimal inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-disc-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-disc-ref.html new file mode 100644 index 0000000..e34a900 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-disc-ref.html
@@ -0,0 +1,12 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: disc</title> +<style> +* { + margin: 0; + padding: 0; +} +p::before { + content: counter(test, disc); +} +</style> +<p> Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-disc.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-disc.html new file mode 100644 index 0000000..e2456cb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-disc.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: disc</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-disc-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: disc inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-georgian-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-georgian-ref.html new file mode 100644 index 0000000..c400aca --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-georgian-ref.html
@@ -0,0 +1,10 @@ +<!doctype html> +<meta charset=utf8> +<title>Reference: Inside list marker and normal text render identically: georgian</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>ა. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-georgian.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-georgian.html new file mode 100644 index 0000000..ef7615f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-georgian.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: georgian</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-georgian-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: georgian inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-greek-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-greek-ref.html new file mode 100644 index 0000000..f28db82 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-greek-ref.html
@@ -0,0 +1,10 @@ +<!doctype html> +<meta charset=utf8> +<title>Reference: Inside list marker and normal text render identically: lower-greek</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>α. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-greek.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-greek.html new file mode 100644 index 0000000..96b5d811 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-greek.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: lower-greek</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-lower-greek-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: lower-greek inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-latin-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-latin-ref.html new file mode 100644 index 0000000..b86fe8ec --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-latin-ref.html
@@ -0,0 +1,9 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: lower-latin</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>a. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-latin.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-latin.html new file mode 100644 index 0000000..0f6f242 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-latin.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: lower-latin</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-lower-latin-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: lower-latin inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-roman-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-roman-ref.html new file mode 100644 index 0000000..92dfa3d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-roman-ref.html
@@ -0,0 +1,9 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: lower-roman</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>i. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-roman.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-roman.html new file mode 100644 index 0000000..db7301b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-lower-roman.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: lower-roman</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-lower-roman-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: lower-roman inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-square-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-square-ref.html new file mode 100644 index 0000000..99b64a54 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-square-ref.html
@@ -0,0 +1,12 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: square</title> +<style> +* { + margin: 0; + padding: 0; +} +p::before { + content: counter(test, square); +} +</style> +<p> Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-square.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-square.html new file mode 100644 index 0000000..9095017 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-square.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: square</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-square-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: square inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-latin-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-latin-ref.html new file mode 100644 index 0000000..6cbb712 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-latin-ref.html
@@ -0,0 +1,9 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: upper-latin</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>A. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-latin.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-latin.html new file mode 100644 index 0000000..903ef8f5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-latin.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: upper-latin</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-upper-latin-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: upper-latin inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-roman-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-roman-ref.html new file mode 100644 index 0000000..6fca49f2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-roman-ref.html
@@ -0,0 +1,9 @@ +<!doctype html> +<title>Reference: Inside list marker and normal text render identically: upper-roman</title> +<style> +* { + margin: 0; + padding: 0; +} +</style> +<p>I. Filler Text
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-roman.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-roman.html new file mode 100644 index 0000000..69f34d74 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-lists/content-property/marker-text-matches-upper-roman.html
@@ -0,0 +1,18 @@ +<!doctype html> +<title>Inside list marker and normal text render identically: upper-roman</title> +<link rel=help href="https://drafts.csswg.org/css-lists-3/#content-property"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=787382"> +<link rel=match href="marker-text-matches-upper-roman-ref.html"> +<style> +* { + padding: 0; + margin: 0; +} +ol { + list-style: upper-roman inside; +} +</style> + +<ol> + <li>Filler Text</li> +</ol>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-logical/animation-003.tentative-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-logical/animation-003.tentative-expected.txt new file mode 100644 index 0000000..24c710be --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-logical/animation-003.tentative-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Logical properties are represented as physical properties in keyframes assert_own_property: expected property "height" missing +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-logical/animation-003.tenative.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-logical/animation-003.tentative.html similarity index 100% rename from third_party/WebKit/LayoutTests/external/wpt/css/css-logical/animation-003.tenative.html rename to third_party/WebKit/LayoutTests/external/wpt/css/css-logical/animation-003.tentative.html
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-line-height-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-line-height-ref.html new file mode 100644 index 0000000..fe57a281f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-line-height-ref.html
@@ -0,0 +1,16 @@ +<!doctype html> +<title>Reference: Check that :marker inherits line-height</title> +<style> +div { + font: 128px/1 Ahem; + border: 2px solid blue; + background: orange; + color: black; +} +</style> + +<p>There should be two black rectangles below with no space between them and + the border above/below.</p> +<div> + 1. X +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-line-height.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-line-height.html new file mode 100644 index 0000000..145aedcb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-line-height.html
@@ -0,0 +1,29 @@ +<!doctype html> +<title>Check that :marker inherits line-height</title> +<link rel=help href="https://drafts.csswg.org/css-pseudo-4/#tree-abiding"> +<link rel=help href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo"> +<link rel=help href="https://drafts.csswg.org/css-display-3/#list-items"> +<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1415759"> +<link rel=match href=marker-inherit-line-height-ref.html> +<style> +div { + font: 128px/1 Ahem; + border: 2px solid blue; + background: orange; + color: black; +} +ol { + margin: 0; + padding: 0; + list-style-position: inside; + list-style-type: decimal; +} +</style> + +<p>There should be two black rectangles below with no space between them and + the border above/below.</p> +<div> + <ol> + <li>X + </ol> +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-maxlength.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-maxlength.html new file mode 100644 index 0000000..ff4e8f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-maxlength.html
@@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> + +<head> + <title>textarea maxlength</title> + <link rel="author" title="tigercosmos" href="mailto:phy.tiger@gmail.com"> + <link rel=help href="https://html.spec.whatwg.org/multipage/#attr-textarea-maxlength"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + + <textarea id="none"></textarea> + <textarea id="negative" maxlength="-5"></textarea> + <textarea id="non-numeric" maxlength="not-a-number"></textarea> + <textarea id="assign-negative"></textarea> + <textarea id="assign-non-numeric"></textarea> + + <script> + test( + function () { + assert_equals(document.getElementById("none").maxLength, -1); + }, "Unset maxlength is -1"); + + test( + function () { + assert_equals(document.getElementById("negative").maxLength, -1); + }, "Negative maxlength is always -1"); + + test( + function () { + assert_equals(document.getElementById("non-numeric").maxLength, -1); + }, "Non-numeric maxlength is -1"); + + test( + function () { + assert_throws("INDEX_SIZE_ERR", function () { + document.getElementById("assign-negative").maxLength = -5; + }); + }, "Assigning negative integer throws IndexSizeError"); + + test( + function () { + document.getElementById("assign-non-numeric").maxLength = "not-a-number"; + assert_equals(document.getElementById("assign-non-numeric").maxLength, 0); + }, "Assigning non-numeric to maxlength sets maxlength to 0"); + </script> +</body> + +</html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-minlength.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-minlength.html new file mode 100644 index 0000000..9a15a12 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-minlength.html
@@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> + +<head> + <title>textarea minlength</title> + <link rel="author" title="tigercosmos" href="mailto:phy.tiger@gmail.com"> + <link rel=help href="https://html.spec.whatwg.org/multipage/#attr-textarea-minlength"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + + <textarea id="none"></textarea> + <textarea id="negative" minlength=-5></textarea> + <textarea id="non-numeric" minlength="not-a-number"></textarea> + <textarea id="assign-negative"></textarea> + <textarea id="assign-non-numeric"></textarea> + + <script> + test( + function () { + assert_equals(document.getElementById("none").minLength, -1); + }, "Unset minlength is -1"); + + test( + function () { + assert_equals(document.getElementById("negative").minLength, -1); + }, "Negative minlength is always -1"); + + test( + function () { + assert_equals(document.getElementById("non-numeric").minLength, -1); + }, "Non-numeric minlength is -1"); + + test( + function () { + assert_throws("INDEX_SIZE_ERR", function () { + document.getElementById("assign-negative").minLength = -5; + }); + }, "Assigning negative integer throws IndexSizeError"); + + test( + function () { + document.getElementById("assign-non-numeric").minLength = "not-a-number"; + assert_equals(document.getElementById("assign-non-numeric").minLength, 0); + }, "Assigning non-numeric to minlength sets minlength to 0"); + </script> +</body> + +</html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-textLength.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-textLength.html new file mode 100644 index 0000000..d249278 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-textLength.html
@@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<title>The textLengh IDL attribute</title> +<meta content="charset=utf-16"> +<link rel="author" title="tigercosmos" href="mailto:phy.tiger@gmail.com"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-textarea-textlength"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<textarea id="textarea"></textarea> +<script> + var textarea = document.getElementById("textarea"); + + test(function () { + textarea.value= "Hello, World!"; + assert_equals(textarea.textLength, 13); + + textarea.value = "\u4f60\u597d\uff0c\u4e16\u754c\uff01"; //你好,世界! + assert_equals(textarea.textLength, 6); + }, "Textarea's 'testLength' should work for utf-16."); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-validity-clone.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-validity-clone.html new file mode 100644 index 0000000..23d90e7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-textarea-element/textarea-validity-clone.html
@@ -0,0 +1,27 @@ +<!doctype html> +<meta charset="utf-8"> +<title>HTML Test: <textarea> validity state is correct after a clone</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-textarea-element"> +<link rel="help" href="https://bugzil.la/1472169"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +test(function() { + let form = document.createElement("form"); + let textarea = document.createElement("textarea"); + textarea.required = true; + + textarea.appendChild(document.createTextNode("A")); + form.appendChild(textarea); + + assert_true(textarea.validity.valid); + + let formClone = form.cloneNode(true); + assert_equals( + formClone.querySelector('textarea').validity.valid, + textarea.validity.valid, + "Validity state should be preserved after a clone" + ); +}, "<textarea> validity state should be preserved after a clone"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/wpt-server-http.sub-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/wpt-server-http.sub-expected.txt deleted file mode 100644 index 776d0af5..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/wpt-server-http.sub-expected.txt +++ /dev/null
@@ -1,25 +0,0 @@ -This is a testharness.js-based test. -PASS HTTP protocol, no subdomain, port #1 -PASS HTTP protocol, no subdomain, port #2 -PASS HTTP protocol, www subdomain #1, port #1 -PASS HTTP protocol, www subdomain #1, port #2 -PASS HTTP protocol, www subdomain #2, port #1 -PASS HTTP protocol, www subdomain #2, port #2 -PASS HTTP protocol, www subdomain #3, port #1 -PASS HTTP protocol, www subdomain #3, port #2 -PASS HTTP protocol, punycode subdomain #1, port #1 -PASS HTTP protocol, punycode subdomain #1, port #2 -PASS HTTP protocol, punycode subdomain #2, port #1 -PASS HTTP protocol, punycode subdomain #2, port #2 -FAIL HTTP protocol, non-existent domain, port #1 assert_false: expected false got true -FAIL HTTP protocol, non-existent domain, port #2 assert_false: expected false got true -PASS HTTPS protocol, no subdomain -PASS HTTPS protocol, www subdomain #1 -PASS HTTPS protocol, www subdomain #2 -PASS HTTPS protocol, www subdomain #3 -PASS HTTPS protocol, punycode subdomain #1 -PASS HTTPS protocol, punycode subdomain #2 -PASS HTTPS protocol, non-existent domain, port #1 -PASS HTTPS protocol, non-existent domain, port #2 -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/background-fetch.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/background-fetch.idl index 68509fc1a..fc3ed8d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/background-fetch.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/background-fetch.idl
@@ -18,7 +18,7 @@ interface BackgroundFetchManager { Promise<BackgroundFetchRegistration> fetch(DOMString id, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options); Promise<BackgroundFetchRegistration?> get(DOMString id); - Promise<FrozenArray<DOMString>> getIds(); + Promise<sequence<DOMString>> getIds(); // TODO: in future this should become an async iterator for BackgroundFetchRegistration objects }; @@ -51,14 +51,10 @@ }; [Exposed=(Window,Worker)] -interface BackgroundFetchFetch { - readonly attribute Request request; -}; - -[Exposed=(Window,Worker)] interface BackgroundFetchActiveFetches { - Promise<BackgroundFetchActiveFetch> match(RequestInfo request); - Promise<FrozenArray<BackgroundFetchActiveFetch>> values(); + Promise<BackgroundFetchActiveFetch> match(RequestInfo request, optional CacheQueryOptions options); + Promise<sequence<BackgroundFetchActiveFetch>> matchAll(RequestInfo request, optional CacheQueryOptions options); + Promise<sequence<BackgroundFetchActiveFetch>> values(); }; [Exposed=(Window,Worker)] @@ -67,6 +63,11 @@ // In future this will include a fetch observer }; +[Exposed=(Window,Worker)] +interface BackgroundFetchFetch { + readonly attribute Request request; +}; + [Constructor(DOMString type, BackgroundFetchEventInit init), Exposed=ServiceWorker] interface BackgroundFetchEvent : ExtendableEvent { readonly attribute DOMString id; @@ -87,8 +88,9 @@ [Exposed=ServiceWorker] interface BackgroundFetchSettledFetches { - Promise<BackgroundFetchSettledFetch> match(RequestInfo request); - Promise<FrozenArray<BackgroundFetchSettledFetch>> values(); + Promise<BackgroundFetchSettledFetch> match(RequestInfo request, optional CacheQueryOptions options); + Promise<sequence<BackgroundFetchSettledFetch>> matchAll(RequestInfo request, optional CacheQueryOptions options); + Promise<sequence<BackgroundFetchSettledFetch>> values(); }; [Exposed=ServiceWorker]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-counter-styles.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-counter-styles.idl new file mode 100644 index 0000000..b1c3663 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-counter-styles.idl
@@ -0,0 +1,23 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "CSS Counter Styles Level 3" spec. +// See: https://drafts.csswg.org/css-counter-styles/ + +partial interface CSSRule { + const unsigned short COUNTER_STYLE_RULE = 11; +}; + +[Exposed=Window] +interface CSSCounterStyleRule : CSSRule { + attribute CSSOMString name; + attribute CSSOMString system; + attribute CSSOMString symbols; + attribute CSSOMString additiveSymbols; + attribute CSSOMString negative; + attribute CSSOMString prefix; + attribute CSSOMString suffix; + attribute CSSOMString range; + attribute CSSOMString pad; + attribute CSSOMString speakAs; + attribute CSSOMString fallback; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-images.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-images.idl new file mode 100644 index 0000000..0dbac1c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-images.idl
@@ -0,0 +1,8 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "CSS Images Module Level 4" spec. +// See: https://drafts.csswg.org/css-images-4/ + +partial namespace CSS { + // [SameObject] readonly attribute Map elementSources; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-regions.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-regions.idl new file mode 100644 index 0000000..546c21ad --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-regions.idl
@@ -0,0 +1,35 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "CSS Regions Module Level 1" spec. +// See: https://drafts.csswg.org/css-regions/ + +partial interface Document { + readonly attribute NamedFlowMap namedFlows; +}; + +[Exposed=Window, + MapClass=(CSSOMString, NamedFlow)] interface NamedFlowMap { + NamedFlow? get(CSSOMString flowName); + boolean has(CSSOMString flowName); + NamedFlowMap set(CSSOMString flowName, NamedFlow flowValue); + boolean delete(CSSOMString flowName); +}; + +[Exposed=Window] +interface NamedFlow : EventTarget { + readonly attribute CSSOMString name; + readonly attribute boolean overset; + sequence<Region> getRegions(); + readonly attribute short firstEmptyRegionIndex; + sequence<Node> getContent(); + sequence<Region> getRegionsByContent(Node node); +}; + +[Exposed=Window, + NoInterfaceObject] +interface Region { + readonly attribute CSSOMString regionOverset; + sequence<Range>? getRegionFlowRanges(); +}; + +Element implements Region;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/media-source.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/media-source.idl new file mode 100644 index 0000000..6476794 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/media-source.idl
@@ -0,0 +1,72 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "Media Source Extensions™" spec. +// See: https://w3c.github.io/media-source/ + +enum ReadyState { + "closed", + "open", + "ended" +}; +enum EndOfStreamError { + "network", + "decode" +}; +[Constructor] +interface MediaSource : EventTarget { + readonly attribute SourceBufferList sourceBuffers; + readonly attribute SourceBufferList activeSourceBuffers; + readonly attribute ReadyState readyState; + attribute unrestricted double duration; + attribute EventHandler onsourceopen; + attribute EventHandler onsourceended; + attribute EventHandler onsourceclose; + SourceBuffer addSourceBuffer(DOMString type); + void removeSourceBuffer(SourceBuffer sourceBuffer); + void endOfStream(optional EndOfStreamError error); + void setLiveSeekableRange(double start, double end); + void clearLiveSeekableRange(); + static boolean isTypeSupported(DOMString type); +}; +enum AppendMode { + "segments", + "sequence" +}; +interface SourceBuffer : EventTarget { + attribute AppendMode mode; + readonly attribute boolean updating; + readonly attribute TimeRanges buffered; + attribute double timestampOffset; + readonly attribute AudioTrackList audioTracks; + readonly attribute VideoTrackList videoTracks; + readonly attribute TextTrackList textTracks; + attribute double appendWindowStart; + attribute unrestricted double appendWindowEnd; + attribute EventHandler onupdatestart; + attribute EventHandler onupdate; + attribute EventHandler onupdateend; + attribute EventHandler onerror; + attribute EventHandler onabort; + void appendBuffer(BufferSource data); + void abort(); + void remove(double start, unrestricted double end); +}; +interface SourceBufferList : EventTarget { + readonly attribute unsigned long length; + attribute EventHandler onaddsourcebuffer; + attribute EventHandler onremovesourcebuffer; + getter SourceBuffer (unsigned long index); +}; +[Exposed=Window] +partial interface URL { + static DOMString createObjectURL(MediaSource mediaSource); +}; +partial interface AudioTrack { + readonly attribute SourceBuffer? sourceBuffer; +}; +partial interface VideoTrack { + readonly attribute SourceBuffer? sourceBuffer; +}; +partial interface TextTrack { + readonly attribute SourceBuffer? sourceBuffer; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/resource-timing.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/resource-timing.idl index 3f041e1..2668f91 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/resource-timing.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/resource-timing.idl
@@ -5,27 +5,28 @@ [Exposed=(Window,Worker)] interface PerformanceResourceTiming : PerformanceEntry { - readonly attribute DOMString initiatorType; - readonly attribute DOMString nextHopProtocol; - readonly attribute DOMHighResTimeStamp workerStart; - readonly attribute DOMHighResTimeStamp redirectStart; - readonly attribute DOMHighResTimeStamp redirectEnd; - readonly attribute DOMHighResTimeStamp fetchStart; - readonly attribute DOMHighResTimeStamp domainLookupStart; - readonly attribute DOMHighResTimeStamp domainLookupEnd; - readonly attribute DOMHighResTimeStamp connectStart; - readonly attribute DOMHighResTimeStamp connectEnd; - readonly attribute DOMHighResTimeStamp secureConnectionStart; - readonly attribute DOMHighResTimeStamp requestStart; - readonly attribute DOMHighResTimeStamp responseStart; - readonly attribute DOMHighResTimeStamp responseEnd; - readonly attribute unsigned long long transferSize; - readonly attribute unsigned long long encodedBodySize; - readonly attribute unsigned long long decodedBodySize; + readonly attribute DOMString initiatorType; + readonly attribute DOMString nextHopProtocol; + readonly attribute DOMHighResTimeStamp workerStart; + readonly attribute DOMHighResTimeStamp redirectStart; + readonly attribute DOMHighResTimeStamp redirectEnd; + readonly attribute DOMHighResTimeStamp fetchStart; + readonly attribute DOMHighResTimeStamp domainLookupStart; + readonly attribute DOMHighResTimeStamp domainLookupEnd; + readonly attribute DOMHighResTimeStamp connectStart; + readonly attribute DOMHighResTimeStamp connectEnd; + readonly attribute DOMHighResTimeStamp secureConnectionStart; + readonly attribute DOMHighResTimeStamp requestStart; + readonly attribute DOMHighResTimeStamp responseStart; + readonly attribute DOMHighResTimeStamp responseEnd; + readonly attribute unsigned long long transferSize; + readonly attribute unsigned long long encodedBodySize; + readonly attribute unsigned long long decodedBodySize; [Default] object toJSON(); }; + partial interface Performance { - void clearResourceTimings(); - void setResourceTimingBufferSize(unsigned long maxSize); - attribute EventHandler onresourcetimingbufferfull; + void clearResourceTimings(); + void setResourceTimingBufferSize(unsigned long maxSize); + attribute EventHandler onresourcetimingbufferfull; };
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/selection-api.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/selection-api.idl index b2d2f86..6e814ea 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/selection-api.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/selection-api.idl
@@ -4,42 +4,40 @@ // See: https://w3c.github.io/selection-api/ interface Selection { - readonly attribute Node? anchorNode; - readonly attribute unsigned long anchorOffset; - readonly attribute Node? focusNode; - readonly attribute unsigned long focusOffset; - readonly attribute boolean isCollapsed; - readonly attribute unsigned long rangeCount; - readonly attribute DOMString type; - Range getRangeAt(unsigned long index); - void addRange(Range range); - void removeRange(Range range); - void removeAllRanges(); - void empty(); - void collapse(Node? node, - optional unsigned long offset = 0); - void setPosition(Node? node, - optional unsigned long offset = 0); - void collapseToStart(); - void collapseToEnd(); - void extend(Node node, optional unsigned long offset = 0); - void setBaseAndExtent(Node anchorNode, - unsigned long anchorOffset, - Node focusNode, - unsigned long focusOffset); - void selectAllChildren(Node node); - [CEReactions] void deleteFromDocument(); - boolean containsNode(Node node, - optional boolean allowPartialContainment = false); - stringifier DOMString (); + readonly attribute Node? anchorNode; + readonly attribute unsigned long anchorOffset; + readonly attribute Node? focusNode; + readonly attribute unsigned long focusOffset; + readonly attribute boolean isCollapsed; + readonly attribute unsigned long rangeCount; + readonly attribute DOMString type; + Range getRangeAt(unsigned long index); + void addRange(Range range); + void removeRange(Range range); + void removeAllRanges(); + void empty(); + void collapse(Node? node, optional unsigned long offset = 0); + void setPosition(Node? node, optional unsigned long offset = 0); + void collapseToStart(); + void collapseToEnd(); + void extend(Node node, optional unsigned long offset = 0); + void setBaseAndExtent(Node anchorNode, unsigned long anchorOffset, Node focusNode, unsigned long focusOffset); + void selectAllChildren(Node node); + [CEReactions] + void deleteFromDocument(); + boolean containsNode(Node node, optional boolean allowPartialContainment = false); + stringifier DOMString (); }; + partial interface Document { - Selection? getSelection(); + Selection? getSelection(); }; + partial interface Window { - Selection? getSelection(); + Selection? getSelection(); }; + partial interface GlobalEventHandlers { - attribute EventHandler onselectstart; - attribute EventHandler onselectionchange; + attribute EventHandler onselectstart; + attribute EventHandler onselectionchange; };
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/service-workers.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/service-workers.idl index edf2985bd..38d22c6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/service-workers.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/service-workers.idl
@@ -12,7 +12,7 @@ // event attribute EventHandler onstatechange; }; -ServiceWorker implements AbstractWorker; +ServiceWorker includes AbstractWorker; enum ServiceWorkerState { "installing",
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/touch-events.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/touch-events.idl index 5c5a3ef..097b0e9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/touch-events.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/touch-events.idl
@@ -9,78 +9,74 @@ }; dictionary TouchInit { - required long identifier; + required long identifier; required EventTarget target; - double clientX = 0; - double clientY = 0; - double screenX = 0; - double screenY = 0; - double pageX = 0; - double pageY = 0; - float radiusX = 0; - float radiusY = 0; - float rotationAngle = 0; - float force = 0; - double altitudeAngle = 0; - double azimuthAngle = 0; - TouchType touchType = "direct"; + double clientX = 0; + double clientY = 0; + double screenX = 0; + double screenY = 0; + double pageX = 0; + double pageY = 0; + float radiusX = 0; + float radiusY = 0; + float rotationAngle = 0; + float force = 0; + double altitudeAngle = 0; + double azimuthAngle = 0; + TouchType touchType = "direct"; }; -[Constructor(TouchInit touchInitDict), - Exposed=Window] +[Constructor(TouchInit touchInitDict), Exposed=Window] interface Touch { - readonly attribute long identifier; - readonly attribute EventTarget target; - readonly attribute double screenX; - readonly attribute double screenY; - readonly attribute double clientX; - readonly attribute double clientY; - readonly attribute double pageX; - readonly attribute double pageY; - readonly attribute float radiusX; - readonly attribute float radiusY; - readonly attribute float rotationAngle; - readonly attribute float force; - readonly attribute float altitudeAngle; - readonly attribute float azimuthAngle; - readonly attribute TouchType touchType; + readonly attribute long identifier; + readonly attribute EventTarget target; + readonly attribute double screenX; + readonly attribute double screenY; + readonly attribute double clientX; + readonly attribute double clientY; + readonly attribute double pageX; + readonly attribute double pageY; + readonly attribute float radiusX; + readonly attribute float radiusY; + readonly attribute float rotationAngle; + readonly attribute float force; + readonly attribute float altitudeAngle; + readonly attribute float azimuthAngle; + readonly attribute TouchType touchType; }; + interface TouchList { - readonly attribute unsigned long length; + readonly attribute unsigned long length; getter Touch? item(unsigned long index); }; + dictionary TouchEventInit : EventModifierInit { - sequence<Touch> touches = []; - sequence<Touch> targetTouches = []; - sequence<Touch> changedTouches = []; + sequence<Touch> touches = []; + sequence<Touch> targetTouches = []; + sequence<Touch> changedTouches = []; }; -[Constructor(DOMString type, optional TouchEventInit eventInitDict), - Exposed=Window] +[Constructor(DOMString type, optional TouchEventInit eventInitDict), Exposed=Window] interface TouchEvent : UIEvent { - readonly attribute TouchList touches; - readonly attribute TouchList targetTouches; - readonly attribute TouchList changedTouches; - readonly attribute boolean altKey; - readonly attribute boolean metaKey; - readonly attribute boolean ctrlKey; - readonly attribute boolean shiftKey; + readonly attribute TouchList touches; + readonly attribute TouchList targetTouches; + readonly attribute TouchList changedTouches; + readonly attribute boolean altKey; + readonly attribute boolean metaKey; + readonly attribute boolean ctrlKey; + readonly attribute boolean shiftKey; }; + partial interface GlobalEventHandlers { - attribute EventHandler ontouchstart; - attribute EventHandler ontouchend; - attribute EventHandler ontouchmove; - attribute EventHandler ontouchcancel; + attribute EventHandler ontouchstart; + attribute EventHandler ontouchend; + attribute EventHandler ontouchmove; + attribute EventHandler ontouchcancel; }; + partial interface Document { - // Deprecated in this specification - Touch createTouch(WindowProxy view, - EventTarget target, - long identifier, - double pageX, - double pageY, - double screenX, - double screenY); - // Deprecated in this specification - TouchList createTouchList(Touch... touches); + // Deprecated in this specification + Touch createTouch(WindowProxy view, EventTarget target, long identifier, double pageX, double pageY, double screenX, double screenY); + // Deprecated in this specification + TouchList createTouchList(Touch... touches); };
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any-expected.txt new file mode 100644 index 0000000..4d85278 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any-expected.txt
@@ -0,0 +1,148 @@ +This is a testharness.js-based test. +Found 144 tests; 141 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS media-source interfaces +PASS Partial interface URL: original interface defined +PASS Partial interface URL: valid exposure set +PASS Partial interface AudioTrack: original interface defined +PASS Partial interface VideoTrack: original interface defined +PASS Partial interface TextTrack: original interface defined +PASS MediaSource interface: existence and properties of interface object +PASS MediaSource interface object length +PASS MediaSource interface object name +PASS MediaSource interface: existence and properties of interface prototype object +PASS MediaSource interface: existence and properties of interface prototype object's "constructor" property +PASS MediaSource interface: existence and properties of interface prototype object's @@unscopables property +PASS MediaSource interface: attribute sourceBuffers +PASS Unscopable handled correctly for sourceBuffers property on MediaSource +PASS MediaSource interface: attribute activeSourceBuffers +PASS Unscopable handled correctly for activeSourceBuffers property on MediaSource +PASS MediaSource interface: attribute readyState +PASS Unscopable handled correctly for readyState property on MediaSource +PASS MediaSource interface: attribute duration +PASS Unscopable handled correctly for duration property on MediaSource +PASS MediaSource interface: attribute onsourceopen +PASS Unscopable handled correctly for onsourceopen property on MediaSource +PASS MediaSource interface: attribute onsourceended +PASS Unscopable handled correctly for onsourceended property on MediaSource +PASS MediaSource interface: attribute onsourceclose +PASS Unscopable handled correctly for onsourceclose property on MediaSource +PASS MediaSource interface: operation addSourceBuffer(DOMString) +PASS Unscopable handled correctly for addSourceBuffer(DOMString) on MediaSource +PASS MediaSource interface: operation removeSourceBuffer(SourceBuffer) +PASS Unscopable handled correctly for removeSourceBuffer(SourceBuffer) on MediaSource +PASS MediaSource interface: operation endOfStream(EndOfStreamError) +PASS Unscopable handled correctly for endOfStream(EndOfStreamError) on MediaSource +PASS MediaSource interface: operation setLiveSeekableRange(double, double) +PASS Unscopable handled correctly for setLiveSeekableRange(double, double) on MediaSource +PASS MediaSource interface: operation clearLiveSeekableRange() +PASS Unscopable handled correctly for clearLiveSeekableRange() on MediaSource +PASS MediaSource interface: operation isTypeSupported(DOMString) +PASS Unscopable handled correctly for isTypeSupported(DOMString) on MediaSource +PASS MediaSource must be primary interface of mediaSource +PASS Stringification of mediaSource +PASS MediaSource interface: mediaSource must inherit property "sourceBuffers" with the proper type +PASS MediaSource interface: mediaSource must inherit property "activeSourceBuffers" with the proper type +PASS MediaSource interface: mediaSource must inherit property "readyState" with the proper type +PASS MediaSource interface: mediaSource must inherit property "duration" with the proper type +PASS MediaSource interface: mediaSource must inherit property "onsourceopen" with the proper type +PASS MediaSource interface: mediaSource must inherit property "onsourceended" with the proper type +PASS MediaSource interface: mediaSource must inherit property "onsourceclose" with the proper type +PASS MediaSource interface: mediaSource must inherit property "addSourceBuffer(DOMString)" with the proper type +PASS MediaSource interface: calling addSourceBuffer(DOMString) on mediaSource with too few arguments must throw TypeError +PASS MediaSource interface: mediaSource must inherit property "removeSourceBuffer(SourceBuffer)" with the proper type +PASS MediaSource interface: calling removeSourceBuffer(SourceBuffer) on mediaSource with too few arguments must throw TypeError +PASS MediaSource interface: mediaSource must inherit property "endOfStream(EndOfStreamError)" with the proper type +PASS MediaSource interface: calling endOfStream(EndOfStreamError) on mediaSource with too few arguments must throw TypeError +PASS MediaSource interface: mediaSource must inherit property "setLiveSeekableRange(double, double)" with the proper type +PASS MediaSource interface: calling setLiveSeekableRange(double, double) on mediaSource with too few arguments must throw TypeError +PASS MediaSource interface: mediaSource must inherit property "clearLiveSeekableRange()" with the proper type +PASS MediaSource interface: mediaSource must inherit property "isTypeSupported(DOMString)" with the proper type +PASS MediaSource interface: calling isTypeSupported(DOMString) on mediaSource with too few arguments must throw TypeError +PASS SourceBuffer interface: existence and properties of interface object +PASS SourceBuffer interface object length +PASS SourceBuffer interface object name +PASS SourceBuffer interface: existence and properties of interface prototype object +PASS SourceBuffer interface: existence and properties of interface prototype object's "constructor" property +PASS SourceBuffer interface: existence and properties of interface prototype object's @@unscopables property +PASS SourceBuffer interface: attribute mode +PASS Unscopable handled correctly for mode property on SourceBuffer +PASS SourceBuffer interface: attribute updating +PASS Unscopable handled correctly for updating property on SourceBuffer +PASS SourceBuffer interface: attribute buffered +PASS Unscopable handled correctly for buffered property on SourceBuffer +PASS SourceBuffer interface: attribute timestampOffset +PASS Unscopable handled correctly for timestampOffset property on SourceBuffer +PASS SourceBuffer interface: attribute audioTracks +PASS Unscopable handled correctly for audioTracks property on SourceBuffer +PASS SourceBuffer interface: attribute videoTracks +PASS Unscopable handled correctly for videoTracks property on SourceBuffer +FAIL SourceBuffer interface: attribute textTracks assert_true: The prototype object must have a property "textTracks" expected true got false +PASS Unscopable handled correctly for textTracks property on SourceBuffer +PASS SourceBuffer interface: attribute appendWindowStart +PASS Unscopable handled correctly for appendWindowStart property on SourceBuffer +PASS SourceBuffer interface: attribute appendWindowEnd +PASS Unscopable handled correctly for appendWindowEnd property on SourceBuffer +PASS SourceBuffer interface: attribute onupdatestart +PASS Unscopable handled correctly for onupdatestart property on SourceBuffer +PASS SourceBuffer interface: attribute onupdate +PASS Unscopable handled correctly for onupdate property on SourceBuffer +PASS SourceBuffer interface: attribute onupdateend +PASS Unscopable handled correctly for onupdateend property on SourceBuffer +PASS SourceBuffer interface: attribute onerror +PASS Unscopable handled correctly for onerror property on SourceBuffer +PASS SourceBuffer interface: attribute onabort +PASS Unscopable handled correctly for onabort property on SourceBuffer +PASS SourceBuffer interface: operation appendBuffer(BufferSource) +PASS Unscopable handled correctly for appendBuffer(BufferSource) on SourceBuffer +PASS SourceBuffer interface: operation abort() +PASS Unscopable handled correctly for abort() on SourceBuffer +PASS SourceBuffer interface: operation remove(double, unrestricted double) +PASS Unscopable handled correctly for remove(double, unrestricted double) on SourceBuffer +PASS SourceBuffer must be primary interface of sourceBuffer +PASS Stringification of sourceBuffer +PASS SourceBuffer interface: sourceBuffer must inherit property "mode" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "updating" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "buffered" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "timestampOffset" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "audioTracks" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "videoTracks" with the proper type +FAIL SourceBuffer interface: sourceBuffer must inherit property "textTracks" with the proper type assert_inherits: property "textTracks" not found in prototype chain +PASS SourceBuffer interface: sourceBuffer must inherit property "appendWindowStart" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "appendWindowEnd" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "onupdatestart" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "onupdate" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "onupdateend" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "onerror" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "onabort" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "appendBuffer(BufferSource)" with the proper type +PASS SourceBuffer interface: calling appendBuffer(BufferSource) on sourceBuffer with too few arguments must throw TypeError +PASS SourceBuffer interface: sourceBuffer must inherit property "abort()" with the proper type +PASS SourceBuffer interface: sourceBuffer must inherit property "remove(double, unrestricted double)" with the proper type +PASS SourceBuffer interface: calling remove(double, unrestricted double) on sourceBuffer with too few arguments must throw TypeError +PASS SourceBufferList interface: existence and properties of interface object +PASS SourceBufferList interface object length +PASS SourceBufferList interface object name +PASS SourceBufferList interface: existence and properties of interface prototype object +PASS SourceBufferList interface: existence and properties of interface prototype object's "constructor" property +PASS SourceBufferList interface: existence and properties of interface prototype object's @@unscopables property +PASS SourceBufferList interface: attribute length +PASS Unscopable handled correctly for length property on SourceBufferList +PASS SourceBufferList interface: attribute onaddsourcebuffer +PASS Unscopable handled correctly for onaddsourcebuffer property on SourceBufferList +PASS SourceBufferList interface: attribute onremovesourcebuffer +PASS Unscopable handled correctly for onremovesourcebuffer property on SourceBufferList +PASS SourceBufferList must be primary interface of mediaSource.sourceBuffers +PASS Stringification of mediaSource.sourceBuffers +PASS SourceBufferList interface: mediaSource.sourceBuffers must inherit property "length" with the proper type +PASS SourceBufferList interface: mediaSource.sourceBuffers must inherit property "onaddsourcebuffer" with the proper type +PASS SourceBufferList interface: mediaSource.sourceBuffers must inherit property "onremovesourcebuffer" with the proper type +PASS AudioTrack interface: attribute sourceBuffer +PASS Unscopable handled correctly for sourceBuffer property on AudioTrack +PASS VideoTrack interface: attribute sourceBuffer +PASS Unscopable handled correctly for sourceBuffer property on VideoTrack +FAIL TextTrack interface: attribute sourceBuffer assert_true: The prototype object must have a property "sourceBuffer" expected true got false +PASS Unscopable handled correctly for sourceBuffer property on TextTrack +PASS URL interface: operation createObjectURL(MediaSource) +PASS Unscopable handled correctly for createObjectURL(MediaSource) on URL +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any.js b/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any.js new file mode 100644 index 0000000..7992b11 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any.js
@@ -0,0 +1,59 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// https://w3c.github.io/media-source/ + +'use strict'; + +var mediaSource; +var sourceBuffer; +var video = document.createElement("video"); + +promise_test(async t => { + const srcs = ['media-source', 'dom', 'html', 'url']; + const [idl, dom, html, url] = await Promise.all( + srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); + + var idlArray = new IdlArray(); + idlArray.add_idls(idl); + idlArray.add_dependency_idls(dom); + idlArray.add_dependency_idls(html); + idlArray.add_dependency_idls(url); + + const testIdls = new Promise(resolve => { + try { + mediaSource = new MediaSource(); + video.src = URL.createObjectURL(mediaSource); + mediaSource.addEventListener("sourceopen", function () { + var defaultType ='video/webm;codecs="vp8,vorbis"'; + if (MediaSource.isTypeSupported(defaultType)) { + sourceBuffer = mediaSource.addSourceBuffer(defaultType); + } else { + sourceBuffer = mediaSource.addSourceBuffer('video/mp4'); + } + sourceBuffer.addEventListener("updateend", function (e) { + mediaSource.endOfStream(); + resolve(); + }); + sourceBuffer.appendBuffer(new ArrayBuffer()); + }); + } catch (e) { + // Will be surfaced in idlharness.js's test_object below. + } + }) + + idlArray.add_objects({ + MediaSource: ['mediaSource'], + SourceBuffer: ['sourceBuffer'], + SourceBufferList: ['mediaSource.sourceBuffers'] + }); + + const timeout = new Promise((_, reject) => t.step_timeout(reject, 3000)); + return Promise + .race([testIdls, timeout]) + .then(() => { idlArray.test(); }) + .catch(() => { + idlArray.test(); + return Promise.reject('Failed to create media-source objects') + }); +}, 'media-source interfaces');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any.worker-expected.txt new file mode 100644 index 0000000..b86bc74 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/media-source/idlharness.any.worker-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL idlharness Uncaught ReferenceError: document is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-source/interfaces.html b/third_party/WebKit/LayoutTests/external/wpt/media-source/interfaces.html deleted file mode 100644 index 13e3148..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/media-source/interfaces.html +++ /dev/null
@@ -1,144 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<title>Media Source Extensions IDL tests</title> -<div id=log></div> -<script src=/resources/testharness.js></script> -<script src=/resources/testharnessreport.js></script> -<script src=/resources/WebIDLParser.js></script> -<script src=/resources/idlharness.js></script> -<script type=text/plain class=untested> -interface EventTarget { - void addEventListener(DOMString type, EventListener? callback, optional boolean capture /* = false */); - void removeEventListener(DOMString type, EventListener? callback, optional boolean capture /* = false */); - boolean dispatchEvent(Event event); -}; -interface EventHandler {}; -interface URL {}; -interface HTMLVideoElement {}; -interface AudioTrack {}; -interface AudioTrackList {}; -interface VideoTrack {}; -interface VideoTrackList {}; -interface TextTrack {}; -interface TextTrackList {}; -interface TimeRanges {}; -typedef double DOMHighResTimeStamp; -</script> -<script type=text/plain> -[Constructor] -interface MediaSource : EventTarget { - readonly attribute SourceBufferList sourceBuffers; - readonly attribute SourceBufferList activeSourceBuffers; - readonly attribute ReadyState readyState; - attribute unrestricted double duration; - attribute EventHandler onsourceopen; - attribute EventHandler onsourceended; - attribute EventHandler onsourceclose; - SourceBuffer addSourceBuffer(DOMString type); - void removeSourceBuffer(SourceBuffer sourceBuffer); - void endOfStream(optional EndOfStreamError error); - void setLiveSeekableRange(double start, double end); - void clearLiveSeekableRange(); - static boolean isTypeSupported(DOMString type); -}; - -interface SourceBuffer : EventTarget { - attribute AppendMode mode; - readonly attribute boolean updating; - readonly attribute TimeRanges buffered; - attribute double timestampOffset; - readonly attribute AudioTrackList audioTracks; - readonly attribute VideoTrackList videoTracks; - readonly attribute TextTrackList textTracks; - attribute double appendWindowStart; - attribute unrestricted double appendWindowEnd; - attribute EventHandler onupdatestart; - attribute EventHandler onupdate; - attribute EventHandler onupdateend; - attribute EventHandler onerror; - attribute EventHandler onabort; - void appendBuffer(BufferSource data); - void abort(); - void changeType(DOMString type); - void remove(double start, unrestricted double end); -}; - -interface SourceBufferList : EventTarget { - readonly attribute unsigned long length; - attribute EventHandler onaddsourcebuffer; - attribute EventHandler onremovesourcebuffer; - getter SourceBuffer (unsigned long index); -}; - -[Exposed=Window,DedicatedWorker,SharedWorker] -partial interface URL { - static DOMString createObjectURL(MediaSource mediaSource); -}; - -partial interface AudioTrack { - readonly attribute SourceBuffer? sourceBuffer; -}; - -partial interface VideoTrack { - readonly attribute SourceBuffer? sourceBuffer; -}; - -partial interface TextTrack { - readonly attribute SourceBuffer? sourceBuffer; -}; - -enum EndOfStreamError { - "network", - "decode" -}; - -enum AppendMode { - "segments", - "sequence" -}; - -enum ReadyState { - "closed", - "open", - "ended" -}; -</script> -<script> -"use strict"; -setup({ explicit_done: true }); -var mediaSource; -var sourceBuffer; -var video = document.createElement("video"); -var idlCheck = function() { - var idlArray = new IdlArray(); - [].forEach.call(document.querySelectorAll("script[type=text\\/plain]"), function(node) { - if (node.className == "untested") { - idlArray.add_untested_idls(node.textContent); - } else { - idlArray.add_idls(node.textContent); - } - }); - idlArray.add_objects({ - MediaSource: ['mediaSource'], - SourceBuffer: ['sourceBuffer'], - SourceBufferList: ['mediaSource.sourceBuffers'] - }); - idlArray.test(); - done(); -} -mediaSource = new MediaSource(); -video.src = URL.createObjectURL(mediaSource); -mediaSource.addEventListener("sourceopen", function () { - var defaultType ='video/webm;codecs="vp8,vorbis"'; - if (MediaSource.isTypeSupported(defaultType)) { - sourceBuffer = mediaSource.addSourceBuffer(defaultType); - } else { - sourceBuffer = mediaSource.addSourceBuffer('video/mp4'); - } - sourceBuffer.addEventListener("updateend", function (e) { - mediaSource.endOfStream(); - idlCheck(); - }); - sourceBuffer.appendBuffer(new ArrayBuffer()); -}); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-method-basic-card/idlharness.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/payment-method-basic-card/idlharness.window-expected.txt deleted file mode 100644 index d29913a..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/payment-method-basic-card/idlharness.window-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL payment-method-basic-card interfaces. promise_test: Unhandled rejection with value: object "TypeError: idl_setup_func is not a function" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/disable-picture-in-picture.html b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/disable-picture-in-picture.html index 1a59b7a3..fdd8e97 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/disable-picture-in-picture.html +++ b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/disable-picture-in-picture.html
@@ -33,7 +33,7 @@ promise_test(async t => { const video = await loadVideo(); - return callWithTrustedClick(async () => { + return test_driver.bless('request picture in picture', async () => { const promise = video.requestPictureInPicture(); video.disablePictureInPicture = true; await promise_rejects(t, 'InvalidStateError', promise);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/idlharness.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/idlharness.window-expected.txt index 5f0cb84..ed8f389 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/idlharness.window-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/idlharness.window-expected.txt
@@ -1,6 +1,5 @@ This is a testharness.js-based test. -PASS idlharness -PASS picture-in-picture interfaces. +FAIL picture-in-picture interfaces. promise_test: Unhandled rejection with value: object "NotSupportedError: Picture-in-Picture is not available." PASS Partial interface HTMLVideoElement: original interface defined PASS Partial interface Document: original interface defined PASS Partial interface DocumentOrShadowRoot: original interface defined
diff --git a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/idlharness.window.js b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/idlharness.window.js index 6ada0fe..ac4c0bf 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/idlharness.window.js +++ b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/idlharness.window.js
@@ -8,24 +8,19 @@ // https://wicg.github.io/picture-in-picture/ -promise_test(async () => { - try { +idl_test( + ['picture-in-picture'], + ['html', 'dom'], + async idl_array => { + idl_array.add_objects({ + Document: ['document'], + DocumentOrShadowRoot: ['document'], + HTMLVideoElement: ['video'], + PictureInPictureWindow: ['pipw'], + }); + self.video = await loadVideo(); self.pipw = await requestPictureInPictureWithTrustedClick(video); - } catch (e) { - // Will be surfaced when video/pipw are undefined below. - } - - idl_test( - ['picture-in-picture'], - ['html', 'dom'], - idl_array => { - idl_array.add_objects({ - Document: ['document'], - DocumentOrShadowRoot: ['document'], - HTMLVideoElement: ['video'], - PictureInPictureWindow: ['pipw'], - }); - }, - 'picture-in-picture interfaces.'); -}) + }, + 'picture-in-picture interfaces.' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/request-picture-in-picture-twice.html b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/request-picture-in-picture-twice.html index 7f1f81f8..556cf83 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/request-picture-in-picture-twice.html +++ b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/request-picture-in-picture-twice.html
@@ -10,13 +10,12 @@ promise_test(async t => { const video1 = await loadVideo(); const video2 = await loadVideo(); - return callWithTrustedClick(() => { - const first = video1.requestPictureInPicture(); - const second = video2.requestPictureInPicture(); - return Promise.all([ - first, - promise_rejects(t, 'NotAllowedError', second) - ]); - }); + return test_driver.bless( + 'request picture in picture', + async () => { + await video1.requestPictureInPicture(); + promise_rejects(t, 'NotAllowedError', video2.requestPictureInPicture()); + } + ); }, 'request Picture-in-Picture consumes user gesture'); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/resources/picture-in-picture-helpers.js b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/resources/picture-in-picture-helpers.js index 4514edf..86b9f29 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/resources/picture-in-picture-helpers.js +++ b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/resources/picture-in-picture-helpers.js
@@ -4,38 +4,19 @@ } } -function callWithTrustedClick(callback) { - return new Promise((resolve, reject) => { - let button = document.createElement('button'); - button.textContent = 'click to continue test'; - button.style.display = 'block'; - button.style.fontSize = '20px'; - button.style.padding = '10px'; - button.onclick = () => { - document.body.removeChild(button); - resolve(callback()); - }; - document.body.appendChild(button); - test_driver.click(button).catch(_ => reject('Click failed')); - }); -} - function loadVideo(activeDocument, sourceUrl) { return new Promise((resolve, reject) => { const document = activeDocument || window.document; const video = document.createElement('video'); video.src = sourceUrl || '/media/movie_5.ogv'; - video.onloadedmetadata = () => { - resolve(video); - }; - video.onerror = error => { - reject(error); - }; + video.onloadedmetadata = () => { resolve(video); }; + video.onerror = error => { reject(error); }; }); } // Calls requestPictureInPicture() in a context that's 'allowed to request PiP'. function requestPictureInPictureWithTrustedClick(videoElement) { - return callWithTrustedClick( - () => videoElement.requestPictureInPicture()); + return test_driver.bless( + 'request picture in picture', + () => videoElement.requestPictureInPicture()); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/presentation-api/controlling-ua/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/presentation-api/controlling-ua/idlharness.https.html index 04d1741..52aa8c5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/presentation-api/controlling-ua/idlharness.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/presentation-api/controlling-ua/idlharness.https.html
@@ -26,16 +26,24 @@ idl_array.add_dependency_idls(dom); idl_array.add_dependency_idls(html); - window.presentation_request = new PresentationRequest("/presentation-api/receiving-ua/idlharness.html"); - window.presentation_request_urls = new PresentationRequest([ - "/presentation-api/receiving-ua/idlharness.html", - "https://www.example.com/presentation.html" - ]); - navigator.presentation.defaultRequest = presentation_request; + try { + window.presentation_request = new PresentationRequest("/presentation-api/receiving-ua/idlharness.html"); + window.presentation_request_urls = new PresentationRequest([ + "/presentation-api/receiving-ua/idlharness.html", + "https://www.example.com/presentation.html" + ]); + navigator.presentation.defaultRequest = window.presentation_request; + } catch (e) { + // Will be surfaced in idlharness.js's test_object below. + } idl_array.add_objects({ - Presentation: ['navigator.presentation'], - PresentationRequest: ['navigator.presentation.defaultRequest', 'presentation_request', 'presentation_request_urls'] + Presentation: ['navigator.presentation'], + PresentationRequest: [ + 'navigator.presentation.defaultRequest', + 'presentation_request', + 'presentation_request_urls' + ], }); idl_array.test(); }, "Test IDL implementation of Presentation API");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.html deleted file mode 100644 index 51ab4fd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!doctype html> -<title>ResizeObserver IDL tests</title> -<link rel="help" href="https://wicg.github.io/ResizeObserver/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/WebIDLParser.js"></script> -<script src="/resources/idlharness.js"></script> -<script> - "use strict"; - - promise_test(async () => { - const idl_array = new IdlArray(); - const idl = await fetch("/interfaces/ResizeObserver.idl").then(r => r.text()); - idl_array.add_idls(idl); - idl_array.add_objects({ - ResizeObserver: ["new ResizeObserver(entries => {})"], - }); - idl_array.test(); - }, "Test IDL implementation of ResizeObserver"); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.window-expected.txt new file mode 100644 index 0000000..f07e46a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.window-expected.txt
@@ -0,0 +1,52 @@ +This is a testharness.js-based test. +PASS Test IDL implementation of ResizeObserver +PASS ResizeObserverEntry creator +PASS ResizeObserver interface: existence and properties of interface object +PASS ResizeObserver interface object length +PASS ResizeObserver interface object name +PASS ResizeObserver interface: existence and properties of interface prototype object +PASS ResizeObserver interface: existence and properties of interface prototype object's "constructor" property +PASS ResizeObserver interface: existence and properties of interface prototype object's @@unscopables property +PASS ResizeObserver interface: operation observe(Element) +PASS Unscopable handled correctly for observe(Element) on ResizeObserver +PASS ResizeObserver interface: operation unobserve(Element) +PASS Unscopable handled correctly for unobserve(Element) on ResizeObserver +PASS ResizeObserver interface: operation disconnect() +PASS Unscopable handled correctly for disconnect() on ResizeObserver +PASS ResizeObserver must be primary interface of observer +PASS Stringification of observer +PASS ResizeObserver interface: observer must inherit property "observe(Element)" with the proper type +PASS ResizeObserver interface: calling observe(Element) on observer with too few arguments must throw TypeError +PASS ResizeObserver interface: observer must inherit property "unobserve(Element)" with the proper type +PASS ResizeObserver interface: calling unobserve(Element) on observer with too few arguments must throw TypeError +PASS ResizeObserver interface: observer must inherit property "disconnect()" with the proper type +PASS ResizeObserverEntry interface: existence and properties of interface object +FAIL ResizeObserverEntry interface object length assert_equals: wrong value for ResizeObserverEntry.length expected 1 but got 0 +PASS ResizeObserverEntry interface object name +PASS ResizeObserverEntry interface: existence and properties of interface prototype object +PASS ResizeObserverEntry interface: existence and properties of interface prototype object's "constructor" property +PASS ResizeObserverEntry interface: existence and properties of interface prototype object's @@unscopables property +PASS ResizeObserverEntry interface: attribute target +PASS Unscopable handled correctly for target property on ResizeObserverEntry +PASS ResizeObserverEntry interface: attribute contentRect +PASS Unscopable handled correctly for contentRect property on ResizeObserverEntry +PASS ResizeObserverEntry must be primary interface of entry +PASS Stringification of entry +PASS ResizeObserverEntry interface: entry must inherit property "target" with the proper type +PASS ResizeObserverEntry interface: entry must inherit property "contentRect" with the proper type +FAIL ResizeObservation interface: existence and properties of interface object assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface object length assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface object name assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: attribute target assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +PASS Unscopable handled correctly for target property on ResizeObservation +FAIL ResizeObservation interface: attribute broadcastWidth assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +PASS Unscopable handled correctly for broadcastWidth property on ResizeObservation +FAIL ResizeObservation interface: attribute broadcastHeight assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +PASS Unscopable handled correctly for broadcastHeight property on ResizeObservation +FAIL ResizeObservation interface: operation isActive() assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +PASS Unscopable handled correctly for isActive() on ResizeObservation +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.window.js b/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.window.js new file mode 100644 index 0000000..240f5ec --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/resize-observer/idlharness.window.js
@@ -0,0 +1,38 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: script=resources/resizeTestHelper.js + +'use strict'; + +// https://wicg.github.io/ResizeObserver/ + +idl_test( + ['ResizeObserver'], + ['dom', 'geometry'], + async idl_array => { + idl_array.add_objects({ + ResizeObserver: ['observer'], + ResizeObserverEntry: ['entry'], + }); + + const div = document.createElement('div'); + document.body.appendChild(div); + let helper = new ResizeTestHelper( + "ResizeObserverEntry creator", + [ + { + setup: observer => { + self.observer = observer; + observer.observe(div); + div.style.width = "5px"; + }, + notify: entries => { + self.entry = entries[0]; + assert_equals(entries[0].contentRect.width, 5, "target width"); + } + } + ]); + await helper.start(); + }, + 'Test IDL implementation of ResizeObserver' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resource-timing/idlharness.any.js b/third_party/WebKit/LayoutTests/external/wpt/resource-timing/idlharness.any.js index d522aae..6dff5e85 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resource-timing/idlharness.any.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resource-timing/idlharness.any.js
@@ -5,24 +5,20 @@ // https://w3c.github.io/resource-timing/ -promise_test(async () => { - const [idl, perf, hrtime, dom, html] = await Promise.all([ - '/interfaces/resource-timing.idl', - '/interfaces/performance-timeline.idl', - '/interfaces/hr-time.idl', - '/interfaces/dom.idl', - '/interfaces/html.idl', - ].map(url => fetch(url).then(r => r.text()))); +idl_test( + ['resource-timing'], + ['performance-timeline', 'hr-time', 'dom', 'html'], + idl_array => { + try { + self.resource = performance.getEntriesByType('resource')[0]; + } catch (e) { + // Will be surfaced when resource is undefined below. + } - const idl_array = new IdlArray(); - idl_array.add_idls(idl); - idl_array.add_dependency_idls(perf); - idl_array.add_dependency_idls(hrtime); - idl_array.add_dependency_idls(dom); - idl_array.add_dependency_idls(html); - idl_array.add_objects({ - Performance: ['performance'], - PerformanceResourceTiming: ["performance.getEntriesByType('resource')[0]"] - }); - idl_array.test(); -}, 'Test server-timing IDL implementation'); + idl_array.add_objects({ + Performance: ['performance'], + PerformanceResourceTiming: ['resource'] + }); + }, + 'Test server-timing IDL implementation' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/webxr-test.js b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/webxr-test.js index 74be1f0..224befd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/webxr-test.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/webxr-test.js
@@ -62,11 +62,14 @@ } // Implements both VRDisplayHost and VRMagicWindowProvider. Maintains a mock for -// VRPresentationProvider. +// XRPresentationProvider. class MockDevice { constructor(fakeDeviceInit, service) { this.displayClient_ = new device.mojom.VRDisplayClientPtr(); - this.presentation_provider_ = new MockVRPresentationProvider(); + this.presentation_provider_ = new MockXRPresentationProvider(); + + this.pose_ = null; + this.next_frame_id_ = 0; this.service_ = service; @@ -101,7 +104,7 @@ if (poseMatrix == null) { this.presentation_provider_.pose_ = null; } else { - this.presentation_provider_.setPoseFromMatrix(poseMatrix); + this.setPoseFromMatrix(poseMatrix); } if (views) { @@ -122,6 +125,49 @@ } } + + setPoseFromMatrix(poseMatrix) { + this.pose_ = { + orientation: null, + position: null, + angularVelocity: null, + linearVelocity: null, + angularAcceleration: null, + linearAcceleration: null, + inputState: null, + poseIndex: 0 + }; + + let pose = this.poseFromMatrix(poseMatrix); + for (let field in pose) { + if (this.pose_.hasOwnProperty(field)) { + this.pose_[field] = pose[field]; + } + } + } + + poseFromMatrix(m) { + let orientation = []; + + let m00 = m[0]; + let m11 = m[5]; + let m22 = m[10]; + // The max( 0, ... ) is just a safeguard against rounding error. + orientation[3] = Math.sqrt(Math.max(0, 1 + m00 + m11 + m22)) / 2; + orientation[0] = Math.sqrt(Math.max(0, 1 + m00 - m11 - m22)) / 2; + orientation[1] = Math.sqrt(Math.max(0, 1 - m00 + m11 - m22)) / 2; + orientation[2] = Math.sqrt(Math.max(0, 1 - m00 - m11 + m22)) / 2; + + let position = []; + position[0] = m[12]; + position[1] = m[13]; + position[2] = m[14]; + + return { + orientation, position + } + } + getNonImmersiveDisplayInfo() { let displayInfo = this.getImmersiveDisplayInfo(); @@ -202,158 +248,7 @@ // Mojo function implementations. - // VRMagicWindowProvider implementation. - - getFrameData() { - // Convert current document time to monotonic time. - let now = window.performance.now() / 1000.0; - let diff = now - internals.monotonicTimeToZeroBasedDocumentTime(now); - now += diff; - now *= 1000000; - - return Promise.resolve({ - frameData: { - pose: this.presentation_provider_.pose_, - bufferHolder: null, - bufferSize: {}, - timeDelta: [], - projectionMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - } - }); - } - - updateSessionGeometry(frame_size, display_rotation) { - // This function must exist to ensure that calls to it do not crash, but we - // do not have any use for this data at present. - } - - // VRDisplayHost implementation. - - requestSession(sessionOptions, was_activation) { - return this.supportsSession(sessionOptions).then((result) => { - // The JavaScript bindings convert c_style_names to camelCase names. - let options = new device.mojom.VRDisplayFrameTransportOptions(); - options.transportMethod = - device.mojom.VRDisplayFrameTransportMethod.SUBMIT_AS_MAILBOX_HOLDER; - options.waitForTransferNotification = true; - options.waitForRenderNotification = true; - - let connection; - if (result.supportsSession) { - connection = { - clientRequest: this.presentation_provider_.getClientRequest(), - provider: this.presentation_provider_.bindProvider(sessionOptions), - transportOptions: options - }; - - let magicWindowPtr = new device.mojom.VRMagicWindowProviderPtr(); - let magicWindowRequest = mojo.makeRequest(magicWindowPtr); - let magicWindowBinding = new mojo.Binding( - device.mojom.VRMagicWindowProvider, this, magicWindowRequest); - - return Promise.resolve({ - session: - {connection: connection, magicWindowProvider: magicWindowPtr} - }); - } else { - return Promise.resolve({session: null}); - } - }); - } - - supportsSession(options) { - return Promise.resolve({ - supportsSession: - !options.exclusive || this.displayInfo_.capabilities.canPresent - }); - }; -} - -class MockVRPresentationProvider { - constructor() { - this.binding_ = new mojo.Binding(device.mojom.VRPresentationProvider, this); - this.pose_ = null; - this.next_frame_id_ = 0; - this.submit_frame_count_ = 0; - this.missing_frame_count_ = 0; - } - - bindProvider(request) { - let providerPtr = new device.mojom.VRPresentationProviderPtr(); - let providerRequest = mojo.makeRequest(providerPtr); - - this.binding_.close(); - - this.binding_ = new mojo.Binding( - device.mojom.VRPresentationProvider, this, providerRequest); - - return providerPtr; - } - - getClientRequest() { - this.submitFrameClient_ = new device.mojom.VRSubmitFrameClientPtr(); - return mojo.makeRequest(this.submitFrameClient_); - } - - setPoseFromMatrix(poseMatrix) { - this.pose_ = { - orientation: null, - position: null, - angularVelocity: null, - linearVelocity: null, - angularAcceleration: null, - linearAcceleration: null, - inputState: null, - poseIndex: 0 - }; - - let pose = this.poseFromMatrix(poseMatrix); - for (let field in pose) { - if (this.pose_.hasOwnProperty(field)) { - this.pose_[field] = pose[field]; - } - } - } - - poseFromMatrix(m) { - let orientation = []; - - let m00 = m[0]; - let m11 = m[5]; - let m22 = m[10]; - // The max( 0, ... ) is just a safeguard against rounding error. - orientation[3] = Math.sqrt(Math.max(0, 1 + m00 + m11 + m22)) / 2; - orientation[0] = Math.sqrt(Math.max(0, 1 + m00 - m11 - m22)) / 2; - orientation[1] = Math.sqrt(Math.max(0, 1 - m00 + m11 - m22)) / 2; - orientation[2] = Math.sqrt(Math.max(0, 1 - m00 - m11 + m22)) / 2; - - let position = []; - position[0] = m[12]; - position[1] = m[13]; - position[2] = m[14]; - - return { - orientation, position - } - } - - // VRPresentationProvider mojo implementation - submitFrameMissing(frameId, mailboxHolder, timeWaited) { - this.missing_frame_count_++; - } - - submitFrame(frameId, mailboxHolder, timeWaited) { - this.submit_frame_count_++; - - // Trigger the submit completion callbacks here. WARNING: The - // Javascript-based mojo mocks are *not* re-entrant. It's OK to - // wait for these notifications on the next frame, but waiting - // within the current frame would never finish since the incoming - // calls would be queued until the current execution context finishes. - this.submitFrameClient_.onSubmitFrameTransferred(true); - this.submitFrameClient_.onSubmitFrameRendered(); - } - + // XRFrameDataProvider implementation. getFrameData() { if (this.pose_) { this.pose_.poseIndex++; @@ -378,6 +273,105 @@ } }); } + + updateSessionGeometry(frame_size, display_rotation) { + // This function must exist to ensure that calls to it do not crash, but we + // do not have any use for this data at present. + } + + // VRDisplayHost implementation. + + requestSession(sessionOptions, was_activation) { + return this.supportsSession(sessionOptions).then((result) => { + // The JavaScript bindings convert c_style_names to camelCase names. + let options = new device.mojom.XRPresentationTransportOptions(); + options.transportMethod = + device.mojom.XRPresentationTransportMethod.SUBMIT_AS_MAILBOX_HOLDER; + options.waitForTransferNotification = true; + options.waitForRenderNotification = true; + + let submit_frame_sink; + if (result.supportsSession) { + submit_frame_sink = { + clientRequest: this.presentation_provider_.getClientRequest(), + provider: this.presentation_provider_.bindProvider(sessionOptions), + transportOptions: options + }; + + let dataProviderPtr = new device.mojom.XRFrameDataProviderPtr(); + let dataProviderRequest = mojo.makeRequest(dataProviderPtr); + let dataProviderBinding = new mojo.Binding( + device.mojom.XRFrameDataProvider, this, dataProviderRequest); + + let enviromentProviderPtr = + new device.mojom.XREnviromentIntegrationProviderPtr(); + let enviromentProviderRequest = mojo.makeRequest(enviromentProviderPtr); + let enviromentProviderBinding = new mojo.Binding( + device.mojom.XREnviromentIntegrationProvider, this, + enviromentProviderRequest); + + return Promise.resolve({ + session: { + submitFrameSink: submit_frame_sink, + dataProvider: dataProviderPtr, + enviromentProvider: enviromentProviderPtr + } + }); + } else { + return Promise.resolve({session: null}); + } + }); + } + + supportsSession(options) { + return Promise.resolve({ + supportsSession: + !options.exclusive || this.displayInfo_.capabilities.canPresent + }); + }; +} + +class MockXRPresentationProvider { + constructor() { + this.binding_ = new mojo.Binding(device.mojom.XRPresentationProvider, this); + + this.submit_frame_count_ = 0; + this.missing_frame_count_ = 0; + } + + bindProvider(request) { + let providerPtr = new device.mojom.XRPresentationProviderPtr(); + let providerRequest = mojo.makeRequest(providerPtr); + + this.binding_.close(); + + this.binding_ = new mojo.Binding( + device.mojom.XRPresentationProvider, this, providerRequest); + + return providerPtr; + } + + getClientRequest() { + this.submitFrameClient_ = new device.mojom.XRPresentationClientPtr(); + return mojo.makeRequest(this.submitFrameClient_); + } + + // XRPresentationProvider mojo implementation + submitFrameMissing(frameId, mailboxHolder, timeWaited) { + this.missing_frame_count_++; + } + + submitFrame(frameId, mailboxHolder, timeWaited) { + this.submit_frame_count_++; + + // Trigger the submit completion callbacks here. WARNING: The + // Javascript-based mojo mocks are *not* re-entrant. It's OK to + // wait for these notifications on the next frame, but waiting + // within the current frame would never finish since the incoming + // calls would be queued until the current execution context finishes. + this.submitFrameClient_.onSubmitFrameTransferred(true); + this.submitFrameClient_.onSubmitFrameRendered(); + } } let XRTest = new ChromeXRTest(); \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js index bfb2582..6f89a71 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
@@ -870,6 +870,16 @@ test(function () { assert_true(originalExists, `Original ${parsed_idl.type} should be defined`); + + var expected = IdlInterface; + switch (parsed_idl.type) { + case 'interface': expected = IdlInterface; break; + case 'dictionary': expected = IdlDictionary; break; + case 'namespace': expected = IdlNamespace; break; + } + assert_true( + expected.prototype.isPrototypeOf(this.members[parsed_idl.name]), + `Original ${parsed_idl.name} definition should have type ${parsed_idl.type}`); }.bind(this), `Partial ${parsed_idl.type} ${partialTestName}: original ${parsed_idl.type} defined`); } if (!originalExists) { @@ -3187,7 +3197,9 @@ } }) .then(function() { - return idl_setup_func(idl_array, t); + if (idl_setup_func) { + return idl_setup_func(idl_array, t); + } }) .then(function() { idl_array.test(); }) .catch(function (reason) {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/selection/idlharness.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/selection/idlharness.window-expected.txt new file mode 100644 index 0000000..949a6b7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/selection/idlharness.window-expected.txt
@@ -0,0 +1,103 @@ +This is a testharness.js-based test. +Found 99 tests; 93 PASS, 6 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS selection-api interfaces +PASS Partial interface Document: original interface defined +PASS Partial interface Window: original interface defined +PASS Partial interface GlobalEventHandlers: original interface defined +PASS Selection interface: existence and properties of interface object +PASS Selection interface object length +PASS Selection interface object name +PASS Selection interface: existence and properties of interface prototype object +PASS Selection interface: existence and properties of interface prototype object's "constructor" property +PASS Selection interface: existence and properties of interface prototype object's @@unscopables property +PASS Selection interface: attribute anchorNode +PASS Unscopable handled correctly for anchorNode property on Selection +PASS Selection interface: attribute anchorOffset +PASS Unscopable handled correctly for anchorOffset property on Selection +PASS Selection interface: attribute focusNode +PASS Unscopable handled correctly for focusNode property on Selection +PASS Selection interface: attribute focusOffset +PASS Unscopable handled correctly for focusOffset property on Selection +PASS Selection interface: attribute isCollapsed +PASS Unscopable handled correctly for isCollapsed property on Selection +PASS Selection interface: attribute rangeCount +PASS Unscopable handled correctly for rangeCount property on Selection +PASS Selection interface: attribute type +PASS Unscopable handled correctly for type property on Selection +PASS Selection interface: operation getRangeAt(unsigned long) +PASS Unscopable handled correctly for getRangeAt(unsigned long) on Selection +PASS Selection interface: operation addRange(Range) +PASS Unscopable handled correctly for addRange(Range) on Selection +PASS Selection interface: operation removeRange(Range) +PASS Unscopable handled correctly for removeRange(Range) on Selection +PASS Selection interface: operation removeAllRanges() +PASS Unscopable handled correctly for removeAllRanges() on Selection +PASS Selection interface: operation empty() +PASS Unscopable handled correctly for empty() on Selection +PASS Selection interface: operation collapse(Node, unsigned long) +PASS Unscopable handled correctly for collapse(Node, unsigned long) on Selection +PASS Selection interface: operation setPosition(Node, unsigned long) +PASS Unscopable handled correctly for setPosition(Node, unsigned long) on Selection +PASS Selection interface: operation collapseToStart() +PASS Unscopable handled correctly for collapseToStart() on Selection +PASS Selection interface: operation collapseToEnd() +PASS Unscopable handled correctly for collapseToEnd() on Selection +PASS Selection interface: operation extend(Node, unsigned long) +PASS Unscopable handled correctly for extend(Node, unsigned long) on Selection +PASS Selection interface: operation setBaseAndExtent(Node, unsigned long, Node, unsigned long) +PASS Unscopable handled correctly for setBaseAndExtent(Node, unsigned long, Node, unsigned long) on Selection +PASS Selection interface: operation selectAllChildren(Node) +PASS Unscopable handled correctly for selectAllChildren(Node) on Selection +PASS Selection interface: operation deleteFromDocument() +PASS Unscopable handled correctly for deleteFromDocument() on Selection +PASS Selection interface: operation containsNode(Node, boolean) +PASS Unscopable handled correctly for containsNode(Node, boolean) on Selection +PASS Selection interface: stringifier +PASS Selection must be primary interface of getSelection() +PASS Stringification of getSelection() +PASS Selection interface: getSelection() must inherit property "anchorNode" with the proper type +PASS Selection interface: getSelection() must inherit property "anchorOffset" with the proper type +PASS Selection interface: getSelection() must inherit property "focusNode" with the proper type +PASS Selection interface: getSelection() must inherit property "focusOffset" with the proper type +PASS Selection interface: getSelection() must inherit property "isCollapsed" with the proper type +PASS Selection interface: getSelection() must inherit property "rangeCount" with the proper type +PASS Selection interface: getSelection() must inherit property "type" with the proper type +PASS Selection interface: getSelection() must inherit property "getRangeAt(unsigned long)" with the proper type +PASS Selection interface: calling getRangeAt(unsigned long) on getSelection() with too few arguments must throw TypeError +PASS Selection interface: getSelection() must inherit property "addRange(Range)" with the proper type +PASS Selection interface: calling addRange(Range) on getSelection() with too few arguments must throw TypeError +PASS Selection interface: getSelection() must inherit property "removeRange(Range)" with the proper type +PASS Selection interface: calling removeRange(Range) on getSelection() with too few arguments must throw TypeError +PASS Selection interface: getSelection() must inherit property "removeAllRanges()" with the proper type +PASS Selection interface: getSelection() must inherit property "empty()" with the proper type +PASS Selection interface: getSelection() must inherit property "collapse(Node, unsigned long)" with the proper type +PASS Selection interface: calling collapse(Node, unsigned long) on getSelection() with too few arguments must throw TypeError +PASS Selection interface: getSelection() must inherit property "setPosition(Node, unsigned long)" with the proper type +PASS Selection interface: calling setPosition(Node, unsigned long) on getSelection() with too few arguments must throw TypeError +PASS Selection interface: getSelection() must inherit property "collapseToStart()" with the proper type +PASS Selection interface: getSelection() must inherit property "collapseToEnd()" with the proper type +PASS Selection interface: getSelection() must inherit property "extend(Node, unsigned long)" with the proper type +PASS Selection interface: calling extend(Node, unsigned long) on getSelection() with too few arguments must throw TypeError +PASS Selection interface: getSelection() must inherit property "setBaseAndExtent(Node, unsigned long, Node, unsigned long)" with the proper type +PASS Selection interface: calling setBaseAndExtent(Node, unsigned long, Node, unsigned long) on getSelection() with too few arguments must throw TypeError +PASS Selection interface: getSelection() must inherit property "selectAllChildren(Node)" with the proper type +PASS Selection interface: calling selectAllChildren(Node) on getSelection() with too few arguments must throw TypeError +PASS Selection interface: getSelection() must inherit property "deleteFromDocument()" with the proper type +PASS Selection interface: getSelection() must inherit property "containsNode(Node, boolean)" with the proper type +PASS Selection interface: calling containsNode(Node, boolean) on getSelection() with too few arguments must throw TypeError +PASS Document interface: operation getSelection() +PASS Unscopable handled correctly for getSelection() on Document +PASS Document interface: document must inherit property "getSelection()" with the proper type +PASS Window interface: operation getSelection() +PASS Unscopable handled correctly for getSelection() on Window +FAIL Window interface: attribute onselectstart assert_own_property: The global object must have a property "onselectstart" expected property "onselectstart" missing +PASS Unscopable handled correctly for onselectstart property on Window +FAIL Window interface: attribute onselectionchange assert_own_property: The global object must have a property "onselectionchange" expected property "onselectionchange" missing +PASS Unscopable handled correctly for onselectionchange property on Window +PASS Window interface: window must inherit property "getSelection()" with the proper type +FAIL Window interface: window must inherit property "onselectstart" with the proper type assert_own_property: expected property "onselectstart" missing +FAIL Window interface: window must inherit property "onselectionchange" with the proper type assert_own_property: expected property "onselectionchange" missing +FAIL GlobalEventHandlers interface: self must inherit property "onselectstart" with the proper type assert_inherits: property "onselectstart" not found in prototype chain +FAIL GlobalEventHandlers interface: self must inherit property "onselectionchange" with the proper type assert_inherits: property "onselectionchange" not found in prototype chain +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/selection/idlharness.window.js b/third_party/WebKit/LayoutTests/external/wpt/selection/idlharness.window.js new file mode 100644 index 0000000..d7b851d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/selection/idlharness.window.js
@@ -0,0 +1,20 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://w3c.github.io/selection-api/ + +idl_test( + ['selection-api'], + ['dom', 'html'], + idlArray => { + idlArray.add_objects({ + Window: ['window'], + Document: ['document'], + Selection: ['getSelection()'], + GlobalEventHandlers: ['self'], + }); + }, + 'selection-api interfaces' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/selection/interfaces.html b/third_party/WebKit/LayoutTests/external/wpt/selection/interfaces.html deleted file mode 100644 index 6b72f28..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/selection/interfaces.html +++ /dev/null
@@ -1,33 +0,0 @@ -<!doctype html> -<title>Selection interface tests</title> -<div id=log></div> -<script src=/resources/testharness.js></script> -<script src=/resources/testharnessreport.js></script> -<script src=/resources/WebIDLParser.js></script> -<script src=/resources/idlharness.js></script> -<script> -"use strict"; - -function doTest([selection, dom, cssom, touchevents, uievents, html]) { - var idlArray = new IdlArray(); - idlArray.add_untested_idls('interface SVGElement {};'); - idlArray.add_untested_idls(dom + cssom + touchevents + uievents + html); - idlArray.add_idls(selection); - idlArray.add_objects({Selection: ['getSelection()']}); - idlArray.test(); -} - -function fetchData(url) { - return fetch(url).then((response) => response.text()); -} - -promise_test(function() { - return Promise.all([fetchData("/interfaces/selection-api.idl"), - fetchData("/interfaces/dom.idl"), - fetchData("/interfaces/cssom.idl"), - fetchData("/interfaces/touchevents.idl"), - fetchData("/interfaces/uievents.idl"), - fetchData("/interfaces/html.idl")]) - .then(doTest); -}, "Test driver"); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/interfaces-window.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/interfaces-window.https.html index 8786b29..d3e85f2 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/interfaces-window.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/interfaces-window.https.html
@@ -4,18 +4,16 @@ <script src="/resources/testharnessreport.js"></script> <script src="/resources/WebIDLParser.js"></script> <script src="/resources/idlharness.js"></script> -<script src="resources/interfaces-idls.js"></script> <script src="resources/test-helpers.sub.js"></script> <script> 'use strict'; promise_test(async (t) => { - const srcs = ['dom', 'service-workers']; - const [dom, serviceWorkerIdl] = await Promise.all( + const srcs = ['dom', 'html', 'service-workers', 'dedicated-workers']; + const [dom, html, serviceWorkerIdl, dedicated] = await Promise.all( srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); var idlArray = new IdlArray(); - idlArray.add_untested_idls(idls.untested); idlArray.add_idls(serviceWorkerIdl, { only: [ 'ServiceWorkerGlobalScope', 'Client', @@ -30,7 +28,9 @@ 'Cache', 'CacheStorage', ]}); + idlArray.add_dependency_idls(dedicated); idlArray.add_dependency_idls(dom); + idlArray.add_dependency_idls(html); idlArray.add_objects({ ServiceWorkerContainer: ['navigator.serviceWorker'] });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/interfaces-idls.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/interfaces-idls.js deleted file mode 100644 index 3db45c6..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/interfaces-idls.js +++ /dev/null
@@ -1,14 +0,0 @@ -var idls = {}; -idls.untested = ` -[Exposed=Worker] -interface WorkerGlobalScope {}; - -[TreatNonObjectAsNull] -callback EventHandlerNonNull = any (Event event); -typedef EventHandlerNonNull? EventHandler; - -[NoInterfaceObject, Exposed=(Window,Worker)] -interface AbstractWorker { - attribute EventHandler onerror; -}; -`;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/interfaces-worker.sub.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/interfaces-worker.sub.js index 606ec07..10fe14d5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/interfaces-worker.sub.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/interfaces-worker.sub.js
@@ -1,17 +1,15 @@ 'use strict'; -importScripts('interfaces-idls.js'); importScripts('worker-testharness.js'); importScripts('/resources/WebIDLParser.js'); importScripts('/resources/idlharness.js'); promise_test(async (t) => { - const srcs = ['dom', 'service-workers']; - const [dom, serviceWorkerIdl] = await Promise.all( + const srcs = ['dom', 'html', 'service-workers', 'dedicated-workers']; + const [dom, html, serviceWorkerIdl, dedicated] = await Promise.all( srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); var idlArray = new IdlArray(); - idlArray.add_untested_idls(idls.untested); idlArray.add_idls(serviceWorkerIdl, { only: [ 'ServiceWorkerGlobalScope', 'Client', @@ -26,7 +24,9 @@ 'Cache', 'CacheStorage', ]}); + idlArray.add_dependency_idls(dedicated); idlArray.add_dependency_idls(dom); + idlArray.add_dependency_idls(html); idlArray.add_objects({ ServiceWorkerGlobalScope: ['self'], Clients: ['self.clients'],
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/linking/reftests/use-descendant-combinator-003.html b/third_party/WebKit/LayoutTests/external/wpt/svg/linking/reftests/use-descendant-combinator-003.html new file mode 100644 index 0000000..14bf5bd1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/linking/reftests/use-descendant-combinator-003.html
@@ -0,0 +1,37 @@ +<!doctype html> +<meta charset=utf-8> +<title>CSS Test: use element doesn't cross shadow tree boundaries in selector-matching, and is invalidated properly</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="help" href="https://svgwg.org/svg2-draft/struct.html#UseElement"> +<link rel="match" href="/svg/linking/reftests/use-descendant-combinator-ref.html"> +<style> +#test rect { + stroke: red; + stroke-width: 10px; +} +.inside-use rect { + fill: red; +} +defs .inside-use rect { + fill: red; +} +</style> +<p> + You should see a green square, and no red. +</p> +<svg> + <defs> + <g id="square"> + <g class="inside-use"> + <rect width="100" height="100"/> + </g> + </g> + </defs> + <g id="test"> + <use href="#square" /> + </g> +</svg> +<script> + document.body.offsetTop; + document.styleSheets[0].cssRules[1].style.fill = 'green'; +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-001-ref.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-001-ref.svg new file mode 100644 index 0000000..dcd39a8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-001-ref.svg
@@ -0,0 +1,32 @@ +<svg id="svg-root" + width="100%" height="100%" viewBox="0 0 480 360" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:html="http://www.w3.org/1999/xhtml"> + <g id="testmeta"> + <title>'mix-blend-mode' with 'isolation'</title> + <html:link rel="author" + title="Tavmjong Bah" + href="http://tavmjong.free.fr"/> + </g> + + <g id="test-body-content"> + <g> + <rect x="120" y="80" width="160" height="160" fill="red"/> + <rect x="200" y="80" width="160" height="160" fill="lime"/> + <rect x="160" y="160" width="160" height="160" fill="blue"/> + <rect x="200" y="160" width="80" height="80" fill="#ffffff"/> + <rect x="200" y="80" width="80" height="80" fill="#ffff00"/> + <rect x="160" y="160" width="40" height="80" fill="#ff00ff"/> + <rect x="280" y="160" width="40" height="80" fill="#00ffff"/> + </g> + + <!-- Stroke to prevent aliasing from effecting results. --> + <g style="fill:none;stroke:black;stroke-width:2px"> + <rect x="120" y="80" width="160" height="160"/> + <rect x="200" y="80" width="160" height="160"/> + <rect x="160" y="160" width="160" height="160"/> + </g> + </g> + +</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-001.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-001.svg new file mode 100644 index 0000000..2278019c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-001.svg
@@ -0,0 +1,43 @@ +<svg id="svg-root" + width="100%" height="100%" viewBox="0 0 480 360" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:html="http://www.w3.org/1999/xhtml"> + <g id="testmeta"> + <title>'mix-blend-mode'</title> + <html:link rel="author" + title="Tavmjong Bah" + href="http://tavmjong.free.fr"/> + <html:link rel="help" + href="https://www.w3.org/TR/SVG2/render.html#PaintersModel"/> + <html:link rel="match" href="blending-001-ref.svg" /> + </g> + + <style id="test-font" type="text/css"> + rect { + mix-blend-mode: screen; + } + + g { + isolation: isolate; + } + </style> + + <g id="test-body-content"> + + <g> + <rect x="120" y="80" width="160" height="160" fill="red"/> + <rect x="200" y="80" width="160" height="160" fill="lime"/> + <rect x="160" y="160" width="160" height="160" fill="blue"/> + </g> + + <!-- Stroke to prevent aliasing from effecting results. --> + <g style="mix-blend-mode:normal;fill:none;stroke:black;stroke-width:2px"> + <rect x="120" y="80" width="160" height="160"/> + <rect x="200" y="80" width="160" height="160"/> + <rect x="160" y="160" width="160" height="160"/> + </g> + + </g> + +</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-002-ref.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-002-ref.svg new file mode 100644 index 0000000..df6f29f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-002-ref.svg
@@ -0,0 +1,32 @@ +<svg id="svg-root" + width="100%" height="100%" viewBox="0 0 480 360" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:html="http://www.w3.org/1999/xhtml"> + <g id="testmeta"> + <title>'mix-blend-mode' with 'isolation'</title> + <html:link rel="author" + title="Tavmjong Bah" + href="http://tavmjong.free.fr"/> + </g> + + <g id="test-body-content"> + <g> + <rect x="120" y="80" width="160" height="160" fill="red"/> + <rect x="200" y="80" width="160" height="160" fill="lime"/> + <rect x="160" y="160" width="160" height="160" fill="blue"/> + <rect x="200" y="160" width="80" height="80" fill="#00ffff"/> + <rect x="200" y="80" width="80" height="80" fill="#00ff00"/> + <rect x="160" y="160" width="40" height="80" fill="#0000ff"/> + <rect x="280" y="160" width="40" height="80" fill="#00ffff"/> + </g> + + <!-- Stroke to prevent aliasing from effecting results. --> + <g style="fill:none;stroke:black;stroke-width:2px"> + <rect x="120" y="80" width="160" height="160"/> + <rect x="200" y="80" width="160" height="160"/> + <rect x="160" y="160" width="160" height="160"/> + </g> + </g> + +</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-002.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-002.svg new file mode 100644 index 0000000..01e180f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/render/reftests/blending-002.svg
@@ -0,0 +1,43 @@ +<svg id="svg-root" + width="100%" height="100%" viewBox="0 0 480 360" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:html="http://www.w3.org/1999/xhtml"> + <g id="testmeta"> + <title>'mix-blend-mode' with 'isolation'</title> + <html:link rel="author" + title="Tavmjong Bah" + href="http://tavmjong.free.fr"/> + <html:link rel="help" + href="https://www.w3.org/TR/SVG2/render.html#PaintersModel"/> + <html:link rel="match" href="blending-002-ref.svg" /> + </g> + + <style id="test-font" type="text/css"> + rect { + mix-blend-mode: screen; + } + + g { + isolation: isolate; + } + </style> + + <g id="test-body-content"> + + <rect x="120" y="80" width="160" height="160" fill="red"/> + <g> + <rect x="200" y="80" width="160" height="160" fill="lime"/> + <rect x="160" y="160" width="160" height="160" fill="blue"/> + </g> + + <!-- Stroke to prevent aliasing from effecting results. --> + <g style="mix-blend-mode:normal;fill:none;stroke:black;stroke-width:2px"> + <rect x="120" y="80" width="160" height="160"/> + <rect x="200" y="80" width="160" height="160"/> + <rect x="160" y="160" width="160" height="160"/> + </g> + + </g> + +</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window.js b/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window.js index 6a95892..dbea07a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window.js +++ b/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window.js
@@ -5,21 +5,16 @@ 'use strict'; -promise_test(async () => { - const srcs = ['touch-events', 'uievents', 'dom', 'html']; - const [idl, uievents, dom, html] = await Promise.all( - srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); - - const idl_array = new IdlArray(); - idl_array.add_idls(idl); - idl_array.add_dependency_idls(uievents); - idl_array.add_dependency_idls(dom); - idl_array.add_dependency_idls(html); - idl_array.add_objects({ - Document: ['document'], - GlobalEventHandlers: ['window', 'document', 'document.body'], - Touch: ['new Touch({identifier: 1, target: document})'], - TouchEvent: ['new TouchEvent("name")'], - }); - idl_array.test(); -}, 'Test IDL implementation of touch-events API'); +idl_test( + ['touch-events'], + ['uievents', 'dom', 'html'], + idl_array => { + idl_array.add_objects({ + Document: ['document'], + GlobalEventHandlers: ['window', 'document', 'document.body'], + Touch: ['new Touch({identifier: 1, target: document})'], + TouchEvent: ['new TouchEvent("name")'], + }); + }, + 'Test IDL implementation of touch-events API' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.html deleted file mode 100644 index f68e51e5e..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.html +++ /dev/null
@@ -1,32 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>WebShare IDL test</title> - <link rel="help" href="https://wicg.github.io/web-share/"> - <script src=/resources/testharness.js></script> - <script src=/resources/testharnessreport.js></script> - <script src=/resources/WebIDLParser.js></script> - <script src=/resources/idlharness.js></script> - </head> - <body> - <script> - "use strict"; - var idl_array = new IdlArray(); - - function doTest(idl) { - idl_array.add_untested_idls('interface Navigator {};'); - idl_array.add_idls(idl); - idl_array.add_objects({ - Navigator: ['navigator'] - }); - idl_array.test(); - } - - promise_test(async () => { - const response = await fetch('../interfaces/web-share.idl'); - doTest(await response.text()); - }, 'Test driver'); - </script> - </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.window.js b/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.window.js new file mode 100644 index 0000000..6a69c8d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.window.js
@@ -0,0 +1,17 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// https://wicg.github.io/web-share/ + +'use strict'; + +idl_test( + ['web-share'], + ['html'], + idl_array => { + idl_array.add_objects({ + Navigator: ['navigator'] + }); + }, + 'Test driver' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/historical.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/historical.html index 2407a87..1f3146c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webaudio/historical.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/historical.html
@@ -12,4 +12,18 @@ assert_false(name in window); }, name + " interface should not exist"); }); + +[ + "dopplerFactor", + "speedOfSound", + "setVelocity" +].forEach(name => { + test(function() { + assert_false(name in AudioListener.prototype); + }, name + " member should not exist on the AudioListener."); +}); + +test(function() { + assert_false("setVelocity" in PannerNode.prototype); +}, "setVelocity should not exist on PannerNodes."); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.html deleted file mode 100644 index bd1df62..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.html +++ /dev/null
@@ -1,97 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>WebAudio IDL tests</title> -<link rel="help" href="https://webaudio.github.io/web-audio-api/"/> -<meta name="timeout" content="long"><!-- Heavy computation of the idl_objects --> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/WebIDLParser.js"></script> -<script src="/resources/idlharness.js"></script> -<script> -'use strict'; - -let sample_rate, context, buffer, worklet_node; - -promise_test(async t => { - const srcs = ['cssom', 'dom', 'html', 'uievents', 'mediacapture-streams', 'webaudio']; - const [cssom, dom, html, uievents, mediacapture, webaudio] = - await Promise.all( - srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); - - const idl_array = new IdlArray(); - idl_array.add_idls(webaudio); - - // Dependencies of HTML - idl_array.add_dependency_idls(html); - idl_array.add_dependency_idls(uievents); - idl_array.add_dependency_idls(dom); - idl_array.add_dependency_idls(mediacapture); - idl_array.add_dependency_idls(cssom); - - idl_array.add_untested_idls('interface SVGElement {};'); - idl_array.add_untested_idls('interface WorkletGlobalScope {};'); - idl_array.add_untested_idls('interface Worklet {};'); - - try { - sample_rate = 44100; - context = new AudioContext; - buffer = new AudioBuffer({length: 1, sampleRate: sample_rate}); - await context.audioWorklet.addModule( - 'the-audio-api/the-audioworklet-interface/processors/dummy-processor.js'); - worklet_node = new AudioWorkletNode(context, 'dummy'); - } catch (e) { - // Ignore - errors will surface in each test_object below. - } - - idl_array.add_objects({ - BaseAudioContext: [], - AudioContext: ['context'], - OfflineAudioContext: ['new OfflineAudioContext(1, 1, sample_rate)'], - OfflineAudioCompletionEvent: [ - 'new OfflineAudioCompletionEvent("", {renderedBuffer: buffer})'], - AudioBuffer: ['buffer'], - AudioNode: [], - AudioParam: ['new AudioBufferSourceNode(context).playbackRate'], - AudioScheduledSourceNode: [], - AnalyserNode: ['new AnalyserNode(context)'], - AudioBufferSourceNode: ['new AudioBufferSourceNode(context)'], - AudioDestinationNode: ['context.destination'], - AudioListener: ['context.listener'], - AudioProcessingEvent: [`new AudioProcessingEvent('', { - playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer - })`], - BiquadFilterNode: ['new BiquadFilterNode(context)'], - ChannelMergerNode: ['new ChannelMergerNode(context)'], - ChannelSplitterNode: ['new ChannelSplitterNode(context)'], - ConstantSourceNode: ['new ConstantSourceNode(context)'], - ConvolverNode: ['new ConvolverNode(context)'], - DelayNode: ['new DelayNode(context)'], - DynamicsCompressorNode: ['new DynamicsCompressorNode(context)'], - GainNode: ['new GainNode(context)'], - IIRFilterNode: [ - 'new IIRFilterNode(context, {feedforward: [1], feedback: [1]})' - ], - MediaElementAudioSourceNode: [ - 'new MediaElementAudioSourceNode(context, {mediaElement: new Audio})' - ], - MediaStreamAudioDestinationNode: [ - 'new MediaStreamAudioDestinationNode(context)' - ], - MediaStreamAudioSourceNode: [], - MediaStreamTrackAudioSourceNode: [], - OscillatorNode: ['new OscillatorNode(context)'], - PannerNode: ['new PannerNode(context)'], - PeriodicWave: ['new PeriodicWave(context)'], - ScriptProcessorNode: ['context.createScriptProcessor()'], - StereoPannerNode: ['new StereoPannerNode(context)'], - WaveShaperNode: ['new WaveShaperNode(context)'], - AudioWorklet: ['context.audioWorklet'], - AudioWorkletGlobalScope: [], - AudioParamMap: ['worklet_node.parameters'], - AudioWorkletNode: ['worklet_node'], - AudioWorkletProcessor: [], - }); - idl_array.test(); - -}, 'Test driver'); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.window-expected.txt new file mode 100644 index 0000000..5bdb954 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.window-expected.txt
@@ -0,0 +1,1285 @@ +This is a testharness.js-based test. +PASS Test driver +PASS BaseAudioContext interface: existence and properties of interface object +PASS BaseAudioContext interface object length +PASS BaseAudioContext interface object name +PASS BaseAudioContext interface: existence and properties of interface prototype object +PASS BaseAudioContext interface: existence and properties of interface prototype object's "constructor" property +PASS BaseAudioContext interface: existence and properties of interface prototype object's @@unscopables property +PASS BaseAudioContext interface: attribute destination +PASS Unscopable handled correctly for destination property on BaseAudioContext +PASS BaseAudioContext interface: attribute sampleRate +PASS Unscopable handled correctly for sampleRate property on BaseAudioContext +PASS BaseAudioContext interface: attribute currentTime +PASS Unscopable handled correctly for currentTime property on BaseAudioContext +PASS BaseAudioContext interface: attribute listener +PASS Unscopable handled correctly for listener property on BaseAudioContext +PASS BaseAudioContext interface: attribute state +PASS Unscopable handled correctly for state property on BaseAudioContext +PASS BaseAudioContext interface: attribute audioWorklet +PASS Unscopable handled correctly for audioWorklet property on BaseAudioContext +PASS BaseAudioContext interface: attribute onstatechange +PASS Unscopable handled correctly for onstatechange property on BaseAudioContext +PASS BaseAudioContext interface: operation createAnalyser() +PASS Unscopable handled correctly for createAnalyser() on BaseAudioContext +PASS BaseAudioContext interface: operation createBiquadFilter() +PASS Unscopable handled correctly for createBiquadFilter() on BaseAudioContext +PASS BaseAudioContext interface: operation createBuffer(unsigned long, unsigned long, float) +PASS Unscopable handled correctly for createBuffer(unsigned long, unsigned long, float) on BaseAudioContext +PASS BaseAudioContext interface: operation createBufferSource() +PASS Unscopable handled correctly for createBufferSource() on BaseAudioContext +PASS BaseAudioContext interface: operation createChannelMerger(unsigned long) +PASS Unscopable handled correctly for createChannelMerger(unsigned long) on BaseAudioContext +PASS BaseAudioContext interface: operation createChannelSplitter(unsigned long) +PASS Unscopable handled correctly for createChannelSplitter(unsigned long) on BaseAudioContext +PASS BaseAudioContext interface: operation createConstantSource() +PASS Unscopable handled correctly for createConstantSource() on BaseAudioContext +PASS BaseAudioContext interface: operation createConvolver() +PASS Unscopable handled correctly for createConvolver() on BaseAudioContext +PASS BaseAudioContext interface: operation createDelay(double) +PASS Unscopable handled correctly for createDelay(double) on BaseAudioContext +PASS BaseAudioContext interface: operation createDynamicsCompressor() +PASS Unscopable handled correctly for createDynamicsCompressor() on BaseAudioContext +PASS BaseAudioContext interface: operation createGain() +PASS Unscopable handled correctly for createGain() on BaseAudioContext +PASS BaseAudioContext interface: operation createIIRFilter([object Object], [object Object]) +PASS Unscopable handled correctly for createIIRFilter([object Object], [object Object]) on BaseAudioContext +PASS BaseAudioContext interface: operation createOscillator() +PASS Unscopable handled correctly for createOscillator() on BaseAudioContext +PASS BaseAudioContext interface: operation createPanner() +PASS Unscopable handled correctly for createPanner() on BaseAudioContext +PASS BaseAudioContext interface: operation createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) +PASS Unscopable handled correctly for createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) on BaseAudioContext +PASS BaseAudioContext interface: operation createScriptProcessor(unsigned long, unsigned long, unsigned long) +PASS Unscopable handled correctly for createScriptProcessor(unsigned long, unsigned long, unsigned long) on BaseAudioContext +PASS BaseAudioContext interface: operation createStereoPanner() +PASS Unscopable handled correctly for createStereoPanner() on BaseAudioContext +PASS BaseAudioContext interface: operation createWaveShaper() +PASS Unscopable handled correctly for createWaveShaper() on BaseAudioContext +PASS BaseAudioContext interface: operation decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) +PASS Unscopable handled correctly for decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on BaseAudioContext +PASS BaseAudioContext interface: operation resume() +PASS Unscopable handled correctly for resume() on BaseAudioContext +PASS AudioContext interface: existence and properties of interface object +PASS AudioContext interface object length +PASS AudioContext interface object name +PASS AudioContext interface: existence and properties of interface prototype object +PASS AudioContext interface: existence and properties of interface prototype object's "constructor" property +PASS AudioContext interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioContext interface: attribute baseLatency +PASS Unscopable handled correctly for baseLatency property on AudioContext +FAIL AudioContext interface: attribute outputLatency assert_true: The prototype object must have a property "outputLatency" expected true got false +PASS Unscopable handled correctly for outputLatency property on AudioContext +PASS AudioContext interface: operation getOutputTimestamp() +PASS Unscopable handled correctly for getOutputTimestamp() on AudioContext +PASS AudioContext interface: operation suspend() +PASS Unscopable handled correctly for suspend() on AudioContext +PASS AudioContext interface: operation close() +PASS Unscopable handled correctly for close() on AudioContext +FAIL AudioContext interface: operation createMediaElementSource(HTMLMediaElement) assert_own_property: interface prototype object missing non-static operation expected property "createMediaElementSource" missing +PASS Unscopable handled correctly for createMediaElementSource(HTMLMediaElement) on AudioContext +FAIL AudioContext interface: operation createMediaStreamSource(MediaStream) assert_own_property: interface prototype object missing non-static operation expected property "createMediaStreamSource" missing +PASS Unscopable handled correctly for createMediaStreamSource(MediaStream) on AudioContext +FAIL AudioContext interface: operation createMediaStreamTrackSource(MediaStreamTrack) assert_own_property: interface prototype object missing non-static operation expected property "createMediaStreamTrackSource" missing +PASS Unscopable handled correctly for createMediaStreamTrackSource(MediaStreamTrack) on AudioContext +FAIL AudioContext interface: operation createMediaStreamDestination() assert_own_property: interface prototype object missing non-static operation expected property "createMediaStreamDestination" missing +PASS Unscopable handled correctly for createMediaStreamDestination() on AudioContext +PASS AudioContext must be primary interface of context +PASS Stringification of context +PASS AudioContext interface: context must inherit property "baseLatency" with the proper type +FAIL AudioContext interface: context must inherit property "outputLatency" with the proper type assert_inherits: property "outputLatency" not found in prototype chain +PASS AudioContext interface: context must inherit property "getOutputTimestamp()" with the proper type +PASS AudioContext interface: context must inherit property "suspend()" with the proper type +PASS AudioContext interface: context must inherit property "close()" with the proper type +PASS AudioContext interface: context must inherit property "createMediaElementSource(HTMLMediaElement)" with the proper type +PASS AudioContext interface: calling createMediaElementSource(HTMLMediaElement) on context with too few arguments must throw TypeError +PASS AudioContext interface: context must inherit property "createMediaStreamSource(MediaStream)" with the proper type +PASS AudioContext interface: calling createMediaStreamSource(MediaStream) on context with too few arguments must throw TypeError +FAIL AudioContext interface: context must inherit property "createMediaStreamTrackSource(MediaStreamTrack)" with the proper type assert_inherits: property "createMediaStreamTrackSource" not found in prototype chain +FAIL AudioContext interface: calling createMediaStreamTrackSource(MediaStreamTrack) on context with too few arguments must throw TypeError assert_inherits: property "createMediaStreamTrackSource" not found in prototype chain +PASS AudioContext interface: context must inherit property "createMediaStreamDestination()" with the proper type +PASS BaseAudioContext interface: context must inherit property "destination" with the proper type +PASS BaseAudioContext interface: context must inherit property "sampleRate" with the proper type +PASS BaseAudioContext interface: context must inherit property "currentTime" with the proper type +PASS BaseAudioContext interface: context must inherit property "listener" with the proper type +PASS BaseAudioContext interface: context must inherit property "state" with the proper type +PASS BaseAudioContext interface: context must inherit property "audioWorklet" with the proper type +PASS BaseAudioContext interface: context must inherit property "onstatechange" with the proper type +PASS BaseAudioContext interface: context must inherit property "createAnalyser()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createBiquadFilter()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createBuffer(unsigned long, unsigned long, float)" with the proper type +PASS BaseAudioContext interface: calling createBuffer(unsigned long, unsigned long, float) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createBufferSource()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createChannelMerger(unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createChannelMerger(unsigned long) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createChannelSplitter(unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createChannelSplitter(unsigned long) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createConstantSource()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createConvolver()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createDelay(double)" with the proper type +PASS BaseAudioContext interface: calling createDelay(double) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createDynamicsCompressor()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createGain()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createIIRFilter([object Object], [object Object])" with the proper type +PASS BaseAudioContext interface: calling createIIRFilter([object Object], [object Object]) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createOscillator()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createPanner()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints)" with the proper type +PASS BaseAudioContext interface: calling createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createScriptProcessor(unsigned long, unsigned long, unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createScriptProcessor(unsigned long, unsigned long, unsigned long) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createStereoPanner()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createWaveShaper()" with the proper type +PASS BaseAudioContext interface: context must inherit property "decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback)" with the proper type +PASS BaseAudioContext interface: calling decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "resume()" with the proper type +PASS OfflineAudioContext interface: existence and properties of interface object +PASS OfflineAudioContext interface object length +PASS OfflineAudioContext interface object name +PASS OfflineAudioContext interface: existence and properties of interface prototype object +PASS OfflineAudioContext interface: existence and properties of interface prototype object's "constructor" property +PASS OfflineAudioContext interface: existence and properties of interface prototype object's @@unscopables property +PASS OfflineAudioContext interface: operation startRendering() +PASS Unscopable handled correctly for startRendering() on OfflineAudioContext +PASS OfflineAudioContext interface: operation suspend(double) +PASS Unscopable handled correctly for suspend(double) on OfflineAudioContext +PASS OfflineAudioContext interface: attribute length +PASS Unscopable handled correctly for length property on OfflineAudioContext +PASS OfflineAudioContext interface: attribute oncomplete +PASS Unscopable handled correctly for oncomplete property on OfflineAudioContext +PASS OfflineAudioContext must be primary interface of new OfflineAudioContext(1, 1, sample_rate) +PASS Stringification of new OfflineAudioContext(1, 1, sample_rate) +PASS OfflineAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "startRendering()" with the proper type +PASS OfflineAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "suspend(double)" with the proper type +PASS OfflineAudioContext interface: calling suspend(double) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS OfflineAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "length" with the proper type +PASS OfflineAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "oncomplete" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "destination" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "sampleRate" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "currentTime" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "listener" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "state" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "audioWorklet" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "onstatechange" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createAnalyser()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createBiquadFilter()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createBuffer(unsigned long, unsigned long, float)" with the proper type +PASS BaseAudioContext interface: calling createBuffer(unsigned long, unsigned long, float) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createBufferSource()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createChannelMerger(unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createChannelMerger(unsigned long) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createChannelSplitter(unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createChannelSplitter(unsigned long) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createConstantSource()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createConvolver()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createDelay(double)" with the proper type +PASS BaseAudioContext interface: calling createDelay(double) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createDynamicsCompressor()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createGain()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createIIRFilter([object Object], [object Object])" with the proper type +PASS BaseAudioContext interface: calling createIIRFilter([object Object], [object Object]) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createOscillator()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createPanner()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints)" with the proper type +PASS BaseAudioContext interface: calling createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createScriptProcessor(unsigned long, unsigned long, unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createScriptProcessor(unsigned long, unsigned long, unsigned long) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createStereoPanner()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createWaveShaper()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback)" with the proper type +PASS BaseAudioContext interface: calling decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "resume()" with the proper type +PASS OfflineAudioCompletionEvent interface: existence and properties of interface object +PASS OfflineAudioCompletionEvent interface object length +PASS OfflineAudioCompletionEvent interface object name +PASS OfflineAudioCompletionEvent interface: existence and properties of interface prototype object +PASS OfflineAudioCompletionEvent interface: existence and properties of interface prototype object's "constructor" property +PASS OfflineAudioCompletionEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS OfflineAudioCompletionEvent interface: attribute renderedBuffer +PASS Unscopable handled correctly for renderedBuffer property on OfflineAudioCompletionEvent +PASS OfflineAudioCompletionEvent must be primary interface of new OfflineAudioCompletionEvent("", {renderedBuffer: buffer}) +PASS Stringification of new OfflineAudioCompletionEvent("", {renderedBuffer: buffer}) +PASS OfflineAudioCompletionEvent interface: new OfflineAudioCompletionEvent("", {renderedBuffer: buffer}) must inherit property "renderedBuffer" with the proper type +PASS AudioBuffer interface: existence and properties of interface object +PASS AudioBuffer interface object length +PASS AudioBuffer interface object name +PASS AudioBuffer interface: existence and properties of interface prototype object +PASS AudioBuffer interface: existence and properties of interface prototype object's "constructor" property +PASS AudioBuffer interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioBuffer interface: attribute sampleRate +PASS Unscopable handled correctly for sampleRate property on AudioBuffer +PASS AudioBuffer interface: attribute length +PASS Unscopable handled correctly for length property on AudioBuffer +PASS AudioBuffer interface: attribute duration +PASS Unscopable handled correctly for duration property on AudioBuffer +PASS AudioBuffer interface: attribute numberOfChannels +PASS Unscopable handled correctly for numberOfChannels property on AudioBuffer +PASS AudioBuffer interface: operation getChannelData(unsigned long) +PASS Unscopable handled correctly for getChannelData(unsigned long) on AudioBuffer +PASS AudioBuffer interface: operation copyFromChannel(Float32Array, unsigned long, unsigned long) +PASS Unscopable handled correctly for copyFromChannel(Float32Array, unsigned long, unsigned long) on AudioBuffer +PASS AudioBuffer interface: operation copyToChannel(Float32Array, unsigned long, unsigned long) +PASS Unscopable handled correctly for copyToChannel(Float32Array, unsigned long, unsigned long) on AudioBuffer +PASS AudioBuffer must be primary interface of buffer +PASS Stringification of buffer +PASS AudioBuffer interface: buffer must inherit property "sampleRate" with the proper type +PASS AudioBuffer interface: buffer must inherit property "length" with the proper type +PASS AudioBuffer interface: buffer must inherit property "duration" with the proper type +PASS AudioBuffer interface: buffer must inherit property "numberOfChannels" with the proper type +PASS AudioBuffer interface: buffer must inherit property "getChannelData(unsigned long)" with the proper type +PASS AudioBuffer interface: calling getChannelData(unsigned long) on buffer with too few arguments must throw TypeError +PASS AudioBuffer interface: buffer must inherit property "copyFromChannel(Float32Array, unsigned long, unsigned long)" with the proper type +PASS AudioBuffer interface: calling copyFromChannel(Float32Array, unsigned long, unsigned long) on buffer with too few arguments must throw TypeError +PASS AudioBuffer interface: buffer must inherit property "copyToChannel(Float32Array, unsigned long, unsigned long)" with the proper type +PASS AudioBuffer interface: calling copyToChannel(Float32Array, unsigned long, unsigned long) on buffer with too few arguments must throw TypeError +PASS AudioNode interface: existence and properties of interface object +PASS AudioNode interface object length +PASS AudioNode interface object name +PASS AudioNode interface: existence and properties of interface prototype object +PASS AudioNode interface: existence and properties of interface prototype object's "constructor" property +PASS AudioNode interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioNode interface: operation connect(AudioNode, unsigned long, unsigned long) +PASS Unscopable handled correctly for connect(AudioNode, unsigned long, unsigned long) on AudioNode +PASS AudioNode interface: operation connect(AudioParam, unsigned long) +PASS Unscopable handled correctly for connect(AudioParam, unsigned long) on AudioNode +PASS AudioNode interface: operation disconnect() +PASS Unscopable handled correctly for disconnect() on AudioNode +PASS AudioNode interface: operation disconnect(unsigned long) +PASS Unscopable handled correctly for disconnect(unsigned long) on AudioNode +PASS AudioNode interface: operation disconnect(AudioNode) +PASS Unscopable handled correctly for disconnect(AudioNode) on AudioNode +PASS AudioNode interface: operation disconnect(AudioNode, unsigned long) +PASS Unscopable handled correctly for disconnect(AudioNode, unsigned long) on AudioNode +PASS AudioNode interface: operation disconnect(AudioNode, unsigned long, unsigned long) +PASS Unscopable handled correctly for disconnect(AudioNode, unsigned long, unsigned long) on AudioNode +PASS AudioNode interface: operation disconnect(AudioParam) +PASS Unscopable handled correctly for disconnect(AudioParam) on AudioNode +PASS AudioNode interface: operation disconnect(AudioParam, unsigned long) +PASS Unscopable handled correctly for disconnect(AudioParam, unsigned long) on AudioNode +PASS AudioNode interface: attribute context +PASS Unscopable handled correctly for context property on AudioNode +PASS AudioNode interface: attribute numberOfInputs +PASS Unscopable handled correctly for numberOfInputs property on AudioNode +PASS AudioNode interface: attribute numberOfOutputs +PASS Unscopable handled correctly for numberOfOutputs property on AudioNode +PASS AudioNode interface: attribute channelCount +PASS Unscopable handled correctly for channelCount property on AudioNode +PASS AudioNode interface: attribute channelCountMode +PASS Unscopable handled correctly for channelCountMode property on AudioNode +PASS AudioNode interface: attribute channelInterpretation +PASS Unscopable handled correctly for channelInterpretation property on AudioNode +PASS AudioParam interface: existence and properties of interface object +PASS AudioParam interface object length +PASS AudioParam interface object name +PASS AudioParam interface: existence and properties of interface prototype object +PASS AudioParam interface: existence and properties of interface prototype object's "constructor" property +PASS AudioParam interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioParam interface: attribute value +PASS Unscopable handled correctly for value property on AudioParam +PASS AudioParam interface: attribute automationRate +PASS Unscopable handled correctly for automationRate property on AudioParam +PASS AudioParam interface: attribute defaultValue +PASS Unscopable handled correctly for defaultValue property on AudioParam +PASS AudioParam interface: attribute minValue +PASS Unscopable handled correctly for minValue property on AudioParam +PASS AudioParam interface: attribute maxValue +PASS Unscopable handled correctly for maxValue property on AudioParam +PASS AudioParam interface: operation setValueAtTime(float, double) +PASS Unscopable handled correctly for setValueAtTime(float, double) on AudioParam +PASS AudioParam interface: operation linearRampToValueAtTime(float, double) +PASS Unscopable handled correctly for linearRampToValueAtTime(float, double) on AudioParam +PASS AudioParam interface: operation exponentialRampToValueAtTime(float, double) +PASS Unscopable handled correctly for exponentialRampToValueAtTime(float, double) on AudioParam +PASS AudioParam interface: operation setTargetAtTime(float, double, float) +PASS Unscopable handled correctly for setTargetAtTime(float, double, float) on AudioParam +PASS AudioParam interface: operation setValueCurveAtTime([object Object], double, double) +PASS Unscopable handled correctly for setValueCurveAtTime([object Object], double, double) on AudioParam +PASS AudioParam interface: operation cancelScheduledValues(double) +PASS Unscopable handled correctly for cancelScheduledValues(double) on AudioParam +PASS AudioParam interface: operation cancelAndHoldAtTime(double) +PASS Unscopable handled correctly for cancelAndHoldAtTime(double) on AudioParam +PASS AudioParam must be primary interface of new AudioBufferSourceNode(context).playbackRate +PASS Stringification of new AudioBufferSourceNode(context).playbackRate +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "value" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "automationRate" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "defaultValue" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "minValue" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "maxValue" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "setValueAtTime(float, double)" with the proper type +PASS AudioParam interface: calling setValueAtTime(float, double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "linearRampToValueAtTime(float, double)" with the proper type +PASS AudioParam interface: calling linearRampToValueAtTime(float, double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "exponentialRampToValueAtTime(float, double)" with the proper type +PASS AudioParam interface: calling exponentialRampToValueAtTime(float, double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "setTargetAtTime(float, double, float)" with the proper type +PASS AudioParam interface: calling setTargetAtTime(float, double, float) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "setValueCurveAtTime([object Object], double, double)" with the proper type +PASS AudioParam interface: calling setValueCurveAtTime([object Object], double, double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "cancelScheduledValues(double)" with the proper type +PASS AudioParam interface: calling cancelScheduledValues(double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "cancelAndHoldAtTime(double)" with the proper type +PASS AudioParam interface: calling cancelAndHoldAtTime(double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: existence and properties of interface object +PASS AudioScheduledSourceNode interface object length +PASS AudioScheduledSourceNode interface object name +PASS AudioScheduledSourceNode interface: existence and properties of interface prototype object +PASS AudioScheduledSourceNode interface: existence and properties of interface prototype object's "constructor" property +PASS AudioScheduledSourceNode interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioScheduledSourceNode interface: attribute onended +PASS Unscopable handled correctly for onended property on AudioScheduledSourceNode +PASS AudioScheduledSourceNode interface: operation start(double) +PASS Unscopable handled correctly for start(double) on AudioScheduledSourceNode +PASS AudioScheduledSourceNode interface: operation stop(double) +PASS Unscopable handled correctly for stop(double) on AudioScheduledSourceNode +PASS AnalyserNode interface: existence and properties of interface object +PASS AnalyserNode interface object length +PASS AnalyserNode interface object name +PASS AnalyserNode interface: existence and properties of interface prototype object +PASS AnalyserNode interface: existence and properties of interface prototype object's "constructor" property +PASS AnalyserNode interface: existence and properties of interface prototype object's @@unscopables property +PASS AnalyserNode interface: operation getFloatFrequencyData(Float32Array) +PASS Unscopable handled correctly for getFloatFrequencyData(Float32Array) on AnalyserNode +PASS AnalyserNode interface: operation getByteFrequencyData(Uint8Array) +PASS Unscopable handled correctly for getByteFrequencyData(Uint8Array) on AnalyserNode +PASS AnalyserNode interface: operation getFloatTimeDomainData(Float32Array) +PASS Unscopable handled correctly for getFloatTimeDomainData(Float32Array) on AnalyserNode +PASS AnalyserNode interface: operation getByteTimeDomainData(Uint8Array) +PASS Unscopable handled correctly for getByteTimeDomainData(Uint8Array) on AnalyserNode +PASS AnalyserNode interface: attribute fftSize +PASS Unscopable handled correctly for fftSize property on AnalyserNode +PASS AnalyserNode interface: attribute frequencyBinCount +PASS Unscopable handled correctly for frequencyBinCount property on AnalyserNode +PASS AnalyserNode interface: attribute minDecibels +PASS Unscopable handled correctly for minDecibels property on AnalyserNode +PASS AnalyserNode interface: attribute maxDecibels +PASS Unscopable handled correctly for maxDecibels property on AnalyserNode +PASS AnalyserNode interface: attribute smoothingTimeConstant +PASS Unscopable handled correctly for smoothingTimeConstant property on AnalyserNode +PASS AnalyserNode must be primary interface of new AnalyserNode(context) +PASS Stringification of new AnalyserNode(context) +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "getFloatFrequencyData(Float32Array)" with the proper type +PASS AnalyserNode interface: calling getFloatFrequencyData(Float32Array) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "getByteFrequencyData(Uint8Array)" with the proper type +PASS AnalyserNode interface: calling getByteFrequencyData(Uint8Array) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "getFloatTimeDomainData(Float32Array)" with the proper type +PASS AnalyserNode interface: calling getFloatTimeDomainData(Float32Array) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "getByteTimeDomainData(Uint8Array)" with the proper type +PASS AnalyserNode interface: calling getByteTimeDomainData(Uint8Array) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "fftSize" with the proper type +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "frequencyBinCount" with the proper type +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "minDecibels" with the proper type +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "maxDecibels" with the proper type +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "smoothingTimeConstant" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "channelInterpretation" with the proper type +PASS AudioBufferSourceNode interface: existence and properties of interface object +PASS AudioBufferSourceNode interface object length +PASS AudioBufferSourceNode interface object name +PASS AudioBufferSourceNode interface: existence and properties of interface prototype object +PASS AudioBufferSourceNode interface: existence and properties of interface prototype object's "constructor" property +PASS AudioBufferSourceNode interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioBufferSourceNode interface: attribute buffer +PASS Unscopable handled correctly for buffer property on AudioBufferSourceNode +PASS AudioBufferSourceNode interface: attribute playbackRate +PASS Unscopable handled correctly for playbackRate property on AudioBufferSourceNode +PASS AudioBufferSourceNode interface: attribute detune +PASS Unscopable handled correctly for detune property on AudioBufferSourceNode +PASS AudioBufferSourceNode interface: attribute loop +PASS Unscopable handled correctly for loop property on AudioBufferSourceNode +PASS AudioBufferSourceNode interface: attribute loopStart +PASS Unscopable handled correctly for loopStart property on AudioBufferSourceNode +PASS AudioBufferSourceNode interface: attribute loopEnd +PASS Unscopable handled correctly for loopEnd property on AudioBufferSourceNode +PASS AudioBufferSourceNode interface: operation start(double, double, double) +PASS Unscopable handled correctly for start(double, double, double) on AudioBufferSourceNode +PASS AudioBufferSourceNode must be primary interface of new AudioBufferSourceNode(context) +PASS Stringification of new AudioBufferSourceNode(context) +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "buffer" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "playbackRate" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "detune" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "loop" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "loopStart" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "loopEnd" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "start(double, double, double)" with the proper type +PASS AudioBufferSourceNode interface: calling start(double, double, double) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new AudioBufferSourceNode(context) must inherit property "onended" with the proper type +PASS AudioScheduledSourceNode interface: new AudioBufferSourceNode(context) must inherit property "start(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling start(double) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new AudioBufferSourceNode(context) must inherit property "stop(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling stop(double) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "channelInterpretation" with the proper type +PASS AudioDestinationNode interface: existence and properties of interface object +PASS AudioDestinationNode interface object length +PASS AudioDestinationNode interface object name +PASS AudioDestinationNode interface: existence and properties of interface prototype object +PASS AudioDestinationNode interface: existence and properties of interface prototype object's "constructor" property +PASS AudioDestinationNode interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioDestinationNode interface: attribute maxChannelCount +PASS Unscopable handled correctly for maxChannelCount property on AudioDestinationNode +PASS AudioDestinationNode must be primary interface of context.destination +PASS Stringification of context.destination +PASS AudioDestinationNode interface: context.destination must inherit property "maxChannelCount" with the proper type +PASS AudioNode interface: context.destination must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect()" with the proper type +PASS AudioNode interface: context.destination must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "context" with the proper type +PASS AudioNode interface: context.destination must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: context.destination must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: context.destination must inherit property "channelCount" with the proper type +PASS AudioNode interface: context.destination must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: context.destination must inherit property "channelInterpretation" with the proper type +PASS AudioListener interface: existence and properties of interface object +PASS AudioListener interface object length +PASS AudioListener interface object name +PASS AudioListener interface: existence and properties of interface prototype object +PASS AudioListener interface: existence and properties of interface prototype object's "constructor" property +PASS AudioListener interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioListener interface: attribute positionX +PASS Unscopable handled correctly for positionX property on AudioListener +PASS AudioListener interface: attribute positionY +PASS Unscopable handled correctly for positionY property on AudioListener +PASS AudioListener interface: attribute positionZ +PASS Unscopable handled correctly for positionZ property on AudioListener +PASS AudioListener interface: attribute forwardX +PASS Unscopable handled correctly for forwardX property on AudioListener +PASS AudioListener interface: attribute forwardY +PASS Unscopable handled correctly for forwardY property on AudioListener +PASS AudioListener interface: attribute forwardZ +PASS Unscopable handled correctly for forwardZ property on AudioListener +PASS AudioListener interface: attribute upX +PASS Unscopable handled correctly for upX property on AudioListener +PASS AudioListener interface: attribute upY +PASS Unscopable handled correctly for upY property on AudioListener +PASS AudioListener interface: attribute upZ +PASS Unscopable handled correctly for upZ property on AudioListener +PASS AudioListener interface: operation setPosition(float, float, float) +PASS Unscopable handled correctly for setPosition(float, float, float) on AudioListener +PASS AudioListener interface: operation setOrientation(float, float, float, float, float, float) +PASS Unscopable handled correctly for setOrientation(float, float, float, float, float, float) on AudioListener +PASS AudioListener must be primary interface of context.listener +PASS Stringification of context.listener +PASS AudioListener interface: context.listener must inherit property "positionX" with the proper type +PASS AudioListener interface: context.listener must inherit property "positionY" with the proper type +PASS AudioListener interface: context.listener must inherit property "positionZ" with the proper type +PASS AudioListener interface: context.listener must inherit property "forwardX" with the proper type +PASS AudioListener interface: context.listener must inherit property "forwardY" with the proper type +PASS AudioListener interface: context.listener must inherit property "forwardZ" with the proper type +PASS AudioListener interface: context.listener must inherit property "upX" with the proper type +PASS AudioListener interface: context.listener must inherit property "upY" with the proper type +PASS AudioListener interface: context.listener must inherit property "upZ" with the proper type +PASS AudioListener interface: context.listener must inherit property "setPosition(float, float, float)" with the proper type +PASS AudioListener interface: calling setPosition(float, float, float) on context.listener with too few arguments must throw TypeError +PASS AudioListener interface: context.listener must inherit property "setOrientation(float, float, float, float, float, float)" with the proper type +PASS AudioListener interface: calling setOrientation(float, float, float, float, float, float) on context.listener with too few arguments must throw TypeError +PASS AudioProcessingEvent interface: existence and properties of interface object +PASS AudioProcessingEvent interface object length +PASS AudioProcessingEvent interface object name +PASS AudioProcessingEvent interface: existence and properties of interface prototype object +PASS AudioProcessingEvent interface: existence and properties of interface prototype object's "constructor" property +PASS AudioProcessingEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioProcessingEvent interface: attribute playbackTime +PASS Unscopable handled correctly for playbackTime property on AudioProcessingEvent +PASS AudioProcessingEvent interface: attribute inputBuffer +PASS Unscopable handled correctly for inputBuffer property on AudioProcessingEvent +PASS AudioProcessingEvent interface: attribute outputBuffer +PASS Unscopable handled correctly for outputBuffer property on AudioProcessingEvent +PASS AudioProcessingEvent must be primary interface of new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) +PASS Stringification of new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) +PASS AudioProcessingEvent interface: new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) must inherit property "playbackTime" with the proper type +PASS AudioProcessingEvent interface: new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) must inherit property "inputBuffer" with the proper type +PASS AudioProcessingEvent interface: new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) must inherit property "outputBuffer" with the proper type +PASS BiquadFilterNode interface: existence and properties of interface object +PASS BiquadFilterNode interface object length +PASS BiquadFilterNode interface object name +PASS BiquadFilterNode interface: existence and properties of interface prototype object +PASS BiquadFilterNode interface: existence and properties of interface prototype object's "constructor" property +PASS BiquadFilterNode interface: existence and properties of interface prototype object's @@unscopables property +PASS BiquadFilterNode interface: attribute type +PASS Unscopable handled correctly for type property on BiquadFilterNode +PASS BiquadFilterNode interface: attribute frequency +PASS Unscopable handled correctly for frequency property on BiquadFilterNode +PASS BiquadFilterNode interface: attribute detune +PASS Unscopable handled correctly for detune property on BiquadFilterNode +PASS BiquadFilterNode interface: attribute Q +PASS Unscopable handled correctly for Q property on BiquadFilterNode +PASS BiquadFilterNode interface: attribute gain +PASS Unscopable handled correctly for gain property on BiquadFilterNode +PASS BiquadFilterNode interface: operation getFrequencyResponse(Float32Array, Float32Array, Float32Array) +PASS Unscopable handled correctly for getFrequencyResponse(Float32Array, Float32Array, Float32Array) on BiquadFilterNode +PASS BiquadFilterNode must be primary interface of new BiquadFilterNode(context) +PASS Stringification of new BiquadFilterNode(context) +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "type" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "frequency" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "detune" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "Q" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "gain" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "getFrequencyResponse(Float32Array, Float32Array, Float32Array)" with the proper type +PASS BiquadFilterNode interface: calling getFrequencyResponse(Float32Array, Float32Array, Float32Array) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "channelInterpretation" with the proper type +PASS ChannelMergerNode interface: existence and properties of interface object +PASS ChannelMergerNode interface object length +PASS ChannelMergerNode interface object name +PASS ChannelMergerNode interface: existence and properties of interface prototype object +PASS ChannelMergerNode interface: existence and properties of interface prototype object's "constructor" property +PASS ChannelMergerNode interface: existence and properties of interface prototype object's @@unscopables property +PASS ChannelMergerNode must be primary interface of new ChannelMergerNode(context) +PASS Stringification of new ChannelMergerNode(context) +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "channelInterpretation" with the proper type +PASS ChannelSplitterNode interface: existence and properties of interface object +PASS ChannelSplitterNode interface object length +PASS ChannelSplitterNode interface object name +PASS ChannelSplitterNode interface: existence and properties of interface prototype object +PASS ChannelSplitterNode interface: existence and properties of interface prototype object's "constructor" property +PASS ChannelSplitterNode interface: existence and properties of interface prototype object's @@unscopables property +PASS ChannelSplitterNode must be primary interface of new ChannelSplitterNode(context) +PASS Stringification of new ChannelSplitterNode(context) +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "channelInterpretation" with the proper type +PASS ConstantSourceNode interface: existence and properties of interface object +PASS ConstantSourceNode interface object length +PASS ConstantSourceNode interface object name +PASS ConstantSourceNode interface: existence and properties of interface prototype object +PASS ConstantSourceNode interface: existence and properties of interface prototype object's "constructor" property +PASS ConstantSourceNode interface: existence and properties of interface prototype object's @@unscopables property +PASS ConstantSourceNode interface: attribute offset +PASS Unscopable handled correctly for offset property on ConstantSourceNode +PASS ConstantSourceNode must be primary interface of new ConstantSourceNode(context) +PASS Stringification of new ConstantSourceNode(context) +PASS ConstantSourceNode interface: new ConstantSourceNode(context) must inherit property "offset" with the proper type +PASS AudioScheduledSourceNode interface: new ConstantSourceNode(context) must inherit property "onended" with the proper type +PASS AudioScheduledSourceNode interface: new ConstantSourceNode(context) must inherit property "start(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling start(double) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new ConstantSourceNode(context) must inherit property "stop(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling stop(double) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "channelInterpretation" with the proper type +PASS ConvolverNode interface: existence and properties of interface object +PASS ConvolverNode interface object length +PASS ConvolverNode interface object name +PASS ConvolverNode interface: existence and properties of interface prototype object +PASS ConvolverNode interface: existence and properties of interface prototype object's "constructor" property +PASS ConvolverNode interface: existence and properties of interface prototype object's @@unscopables property +PASS ConvolverNode interface: attribute buffer +PASS Unscopable handled correctly for buffer property on ConvolverNode +PASS ConvolverNode interface: attribute normalize +PASS Unscopable handled correctly for normalize property on ConvolverNode +PASS ConvolverNode must be primary interface of new ConvolverNode(context) +PASS Stringification of new ConvolverNode(context) +PASS ConvolverNode interface: new ConvolverNode(context) must inherit property "buffer" with the proper type +PASS ConvolverNode interface: new ConvolverNode(context) must inherit property "normalize" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "channelInterpretation" with the proper type +PASS DelayNode interface: existence and properties of interface object +PASS DelayNode interface object length +PASS DelayNode interface object name +PASS DelayNode interface: existence and properties of interface prototype object +PASS DelayNode interface: existence and properties of interface prototype object's "constructor" property +PASS DelayNode interface: existence and properties of interface prototype object's @@unscopables property +PASS DelayNode interface: attribute delayTime +PASS Unscopable handled correctly for delayTime property on DelayNode +PASS DelayNode must be primary interface of new DelayNode(context) +PASS Stringification of new DelayNode(context) +PASS DelayNode interface: new DelayNode(context) must inherit property "delayTime" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "channelInterpretation" with the proper type +PASS DynamicsCompressorNode interface: existence and properties of interface object +PASS DynamicsCompressorNode interface object length +PASS DynamicsCompressorNode interface object name +PASS DynamicsCompressorNode interface: existence and properties of interface prototype object +PASS DynamicsCompressorNode interface: existence and properties of interface prototype object's "constructor" property +PASS DynamicsCompressorNode interface: existence and properties of interface prototype object's @@unscopables property +PASS DynamicsCompressorNode interface: attribute threshold +PASS Unscopable handled correctly for threshold property on DynamicsCompressorNode +PASS DynamicsCompressorNode interface: attribute knee +PASS Unscopable handled correctly for knee property on DynamicsCompressorNode +PASS DynamicsCompressorNode interface: attribute ratio +PASS Unscopable handled correctly for ratio property on DynamicsCompressorNode +PASS DynamicsCompressorNode interface: attribute reduction +PASS Unscopable handled correctly for reduction property on DynamicsCompressorNode +PASS DynamicsCompressorNode interface: attribute attack +PASS Unscopable handled correctly for attack property on DynamicsCompressorNode +PASS DynamicsCompressorNode interface: attribute release +PASS Unscopable handled correctly for release property on DynamicsCompressorNode +PASS DynamicsCompressorNode must be primary interface of new DynamicsCompressorNode(context) +PASS Stringification of new DynamicsCompressorNode(context) +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "threshold" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "knee" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "ratio" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "reduction" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "attack" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "release" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "channelInterpretation" with the proper type +PASS GainNode interface: existence and properties of interface object +PASS GainNode interface object length +PASS GainNode interface object name +PASS GainNode interface: existence and properties of interface prototype object +PASS GainNode interface: existence and properties of interface prototype object's "constructor" property +PASS GainNode interface: existence and properties of interface prototype object's @@unscopables property +PASS GainNode interface: attribute gain +PASS Unscopable handled correctly for gain property on GainNode +PASS GainNode must be primary interface of new GainNode(context) +PASS Stringification of new GainNode(context) +PASS GainNode interface: new GainNode(context) must inherit property "gain" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "channelInterpretation" with the proper type +PASS IIRFilterNode interface: existence and properties of interface object +PASS IIRFilterNode interface object length +PASS IIRFilterNode interface object name +PASS IIRFilterNode interface: existence and properties of interface prototype object +PASS IIRFilterNode interface: existence and properties of interface prototype object's "constructor" property +PASS IIRFilterNode interface: existence and properties of interface prototype object's @@unscopables property +PASS IIRFilterNode interface: operation getFrequencyResponse(Float32Array, Float32Array, Float32Array) +PASS Unscopable handled correctly for getFrequencyResponse(Float32Array, Float32Array, Float32Array) on IIRFilterNode +PASS IIRFilterNode must be primary interface of new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) +PASS Stringification of new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) +PASS IIRFilterNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "getFrequencyResponse(Float32Array, Float32Array, Float32Array)" with the proper type +PASS IIRFilterNode interface: calling getFrequencyResponse(Float32Array, Float32Array, Float32Array) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "context" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "channelInterpretation" with the proper type +PASS MediaElementAudioSourceNode interface: existence and properties of interface object +PASS MediaElementAudioSourceNode interface object length +PASS MediaElementAudioSourceNode interface object name +PASS MediaElementAudioSourceNode interface: existence and properties of interface prototype object +PASS MediaElementAudioSourceNode interface: existence and properties of interface prototype object's "constructor" property +PASS MediaElementAudioSourceNode interface: existence and properties of interface prototype object's @@unscopables property +PASS MediaElementAudioSourceNode interface: attribute mediaElement +PASS Unscopable handled correctly for mediaElement property on MediaElementAudioSourceNode +PASS MediaElementAudioSourceNode must be primary interface of new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) +PASS Stringification of new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) +PASS MediaElementAudioSourceNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "mediaElement" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "context" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "channelInterpretation" with the proper type +PASS MediaStreamAudioDestinationNode interface: existence and properties of interface object +PASS MediaStreamAudioDestinationNode interface object length +PASS MediaStreamAudioDestinationNode interface object name +PASS MediaStreamAudioDestinationNode interface: existence and properties of interface prototype object +PASS MediaStreamAudioDestinationNode interface: existence and properties of interface prototype object's "constructor" property +PASS MediaStreamAudioDestinationNode interface: existence and properties of interface prototype object's @@unscopables property +PASS MediaStreamAudioDestinationNode interface: attribute stream +PASS Unscopable handled correctly for stream property on MediaStreamAudioDestinationNode +PASS MediaStreamAudioDestinationNode must be primary interface of new MediaStreamAudioDestinationNode(context) +PASS Stringification of new MediaStreamAudioDestinationNode(context) +PASS MediaStreamAudioDestinationNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "stream" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "channelInterpretation" with the proper type +PASS MediaStreamAudioSourceNode interface: existence and properties of interface object +PASS MediaStreamAudioSourceNode interface object length +PASS MediaStreamAudioSourceNode interface object name +PASS MediaStreamAudioSourceNode interface: existence and properties of interface prototype object +PASS MediaStreamAudioSourceNode interface: existence and properties of interface prototype object's "constructor" property +PASS MediaStreamAudioSourceNode interface: existence and properties of interface prototype object's @@unscopables property +PASS MediaStreamAudioSourceNode interface: attribute mediaStream +PASS Unscopable handled correctly for mediaStream property on MediaStreamAudioSourceNode +FAIL MediaStreamTrackAudioSourceNode interface: existence and properties of interface object assert_own_property: self does not have own property "MediaStreamTrackAudioSourceNode" expected property "MediaStreamTrackAudioSourceNode" missing +FAIL MediaStreamTrackAudioSourceNode interface object length assert_own_property: self does not have own property "MediaStreamTrackAudioSourceNode" expected property "MediaStreamTrackAudioSourceNode" missing +FAIL MediaStreamTrackAudioSourceNode interface object name assert_own_property: self does not have own property "MediaStreamTrackAudioSourceNode" expected property "MediaStreamTrackAudioSourceNode" missing +FAIL MediaStreamTrackAudioSourceNode interface: existence and properties of interface prototype object assert_own_property: self does not have own property "MediaStreamTrackAudioSourceNode" expected property "MediaStreamTrackAudioSourceNode" missing +FAIL MediaStreamTrackAudioSourceNode interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "MediaStreamTrackAudioSourceNode" expected property "MediaStreamTrackAudioSourceNode" missing +FAIL MediaStreamTrackAudioSourceNode interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "MediaStreamTrackAudioSourceNode" expected property "MediaStreamTrackAudioSourceNode" missing +PASS OscillatorNode interface: existence and properties of interface object +PASS OscillatorNode interface object length +PASS OscillatorNode interface object name +PASS OscillatorNode interface: existence and properties of interface prototype object +PASS OscillatorNode interface: existence and properties of interface prototype object's "constructor" property +PASS OscillatorNode interface: existence and properties of interface prototype object's @@unscopables property +PASS OscillatorNode interface: attribute type +PASS Unscopable handled correctly for type property on OscillatorNode +PASS OscillatorNode interface: attribute frequency +PASS Unscopable handled correctly for frequency property on OscillatorNode +PASS OscillatorNode interface: attribute detune +PASS Unscopable handled correctly for detune property on OscillatorNode +PASS OscillatorNode interface: operation setPeriodicWave(PeriodicWave) +PASS Unscopable handled correctly for setPeriodicWave(PeriodicWave) on OscillatorNode +PASS OscillatorNode must be primary interface of new OscillatorNode(context) +PASS Stringification of new OscillatorNode(context) +PASS OscillatorNode interface: new OscillatorNode(context) must inherit property "type" with the proper type +PASS OscillatorNode interface: new OscillatorNode(context) must inherit property "frequency" with the proper type +PASS OscillatorNode interface: new OscillatorNode(context) must inherit property "detune" with the proper type +PASS OscillatorNode interface: new OscillatorNode(context) must inherit property "setPeriodicWave(PeriodicWave)" with the proper type +PASS OscillatorNode interface: calling setPeriodicWave(PeriodicWave) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new OscillatorNode(context) must inherit property "onended" with the proper type +PASS AudioScheduledSourceNode interface: new OscillatorNode(context) must inherit property "start(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling start(double) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new OscillatorNode(context) must inherit property "stop(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling stop(double) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "channelInterpretation" with the proper type +PASS PannerNode interface: existence and properties of interface object +PASS PannerNode interface object length +PASS PannerNode interface object name +PASS PannerNode interface: existence and properties of interface prototype object +PASS PannerNode interface: existence and properties of interface prototype object's "constructor" property +PASS PannerNode interface: existence and properties of interface prototype object's @@unscopables property +PASS PannerNode interface: attribute panningModel +PASS Unscopable handled correctly for panningModel property on PannerNode +PASS PannerNode interface: attribute positionX +PASS Unscopable handled correctly for positionX property on PannerNode +PASS PannerNode interface: attribute positionY +PASS Unscopable handled correctly for positionY property on PannerNode +PASS PannerNode interface: attribute positionZ +PASS Unscopable handled correctly for positionZ property on PannerNode +PASS PannerNode interface: attribute orientationX +PASS Unscopable handled correctly for orientationX property on PannerNode +PASS PannerNode interface: attribute orientationY +PASS Unscopable handled correctly for orientationY property on PannerNode +PASS PannerNode interface: attribute orientationZ +PASS Unscopable handled correctly for orientationZ property on PannerNode +PASS PannerNode interface: attribute distanceModel +PASS Unscopable handled correctly for distanceModel property on PannerNode +PASS PannerNode interface: attribute refDistance +PASS Unscopable handled correctly for refDistance property on PannerNode +PASS PannerNode interface: attribute maxDistance +PASS Unscopable handled correctly for maxDistance property on PannerNode +PASS PannerNode interface: attribute rolloffFactor +PASS Unscopable handled correctly for rolloffFactor property on PannerNode +PASS PannerNode interface: attribute coneInnerAngle +PASS Unscopable handled correctly for coneInnerAngle property on PannerNode +PASS PannerNode interface: attribute coneOuterAngle +PASS Unscopable handled correctly for coneOuterAngle property on PannerNode +PASS PannerNode interface: attribute coneOuterGain +PASS Unscopable handled correctly for coneOuterGain property on PannerNode +PASS PannerNode interface: operation setPosition(float, float, float) +PASS Unscopable handled correctly for setPosition(float, float, float) on PannerNode +PASS PannerNode interface: operation setOrientation(float, float, float) +PASS Unscopable handled correctly for setOrientation(float, float, float) on PannerNode +PASS PannerNode must be primary interface of new PannerNode(context) +PASS Stringification of new PannerNode(context) +PASS PannerNode interface: new PannerNode(context) must inherit property "panningModel" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "positionX" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "positionY" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "positionZ" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "orientationX" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "orientationY" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "orientationZ" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "distanceModel" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "refDistance" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "maxDistance" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "rolloffFactor" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "coneInnerAngle" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "coneOuterAngle" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "coneOuterGain" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "setPosition(float, float, float)" with the proper type +PASS PannerNode interface: calling setPosition(float, float, float) on new PannerNode(context) with too few arguments must throw TypeError +PASS PannerNode interface: new PannerNode(context) must inherit property "setOrientation(float, float, float)" with the proper type +PASS PannerNode interface: calling setOrientation(float, float, float) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "channelInterpretation" with the proper type +PASS PeriodicWave interface: existence and properties of interface object +PASS PeriodicWave interface object length +PASS PeriodicWave interface object name +PASS PeriodicWave interface: existence and properties of interface prototype object +PASS PeriodicWave interface: existence and properties of interface prototype object's "constructor" property +PASS PeriodicWave interface: existence and properties of interface prototype object's @@unscopables property +PASS PeriodicWave must be primary interface of new PeriodicWave(context) +PASS Stringification of new PeriodicWave(context) +PASS ScriptProcessorNode interface: existence and properties of interface object +PASS ScriptProcessorNode interface object length +PASS ScriptProcessorNode interface object name +PASS ScriptProcessorNode interface: existence and properties of interface prototype object +PASS ScriptProcessorNode interface: existence and properties of interface prototype object's "constructor" property +PASS ScriptProcessorNode interface: existence and properties of interface prototype object's @@unscopables property +PASS ScriptProcessorNode interface: attribute onaudioprocess +PASS Unscopable handled correctly for onaudioprocess property on ScriptProcessorNode +PASS ScriptProcessorNode interface: attribute bufferSize +PASS Unscopable handled correctly for bufferSize property on ScriptProcessorNode +PASS ScriptProcessorNode must be primary interface of context.createScriptProcessor() +PASS Stringification of context.createScriptProcessor() +PASS ScriptProcessorNode interface: context.createScriptProcessor() must inherit property "onaudioprocess" with the proper type +PASS ScriptProcessorNode interface: context.createScriptProcessor() must inherit property "bufferSize" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect()" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "context" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "channelCount" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "channelInterpretation" with the proper type +PASS StereoPannerNode interface: existence and properties of interface object +PASS StereoPannerNode interface object length +PASS StereoPannerNode interface object name +PASS StereoPannerNode interface: existence and properties of interface prototype object +PASS StereoPannerNode interface: existence and properties of interface prototype object's "constructor" property +PASS StereoPannerNode interface: existence and properties of interface prototype object's @@unscopables property +PASS StereoPannerNode interface: attribute pan +PASS Unscopable handled correctly for pan property on StereoPannerNode +PASS StereoPannerNode must be primary interface of new StereoPannerNode(context) +PASS Stringification of new StereoPannerNode(context) +PASS StereoPannerNode interface: new StereoPannerNode(context) must inherit property "pan" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "channelInterpretation" with the proper type +PASS WaveShaperNode interface: existence and properties of interface object +PASS WaveShaperNode interface object length +PASS WaveShaperNode interface object name +PASS WaveShaperNode interface: existence and properties of interface prototype object +PASS WaveShaperNode interface: existence and properties of interface prototype object's "constructor" property +PASS WaveShaperNode interface: existence and properties of interface prototype object's @@unscopables property +PASS WaveShaperNode interface: attribute curve +PASS Unscopable handled correctly for curve property on WaveShaperNode +PASS WaveShaperNode interface: attribute oversample +PASS Unscopable handled correctly for oversample property on WaveShaperNode +PASS WaveShaperNode must be primary interface of new WaveShaperNode(context) +PASS Stringification of new WaveShaperNode(context) +PASS WaveShaperNode interface: new WaveShaperNode(context) must inherit property "curve" with the proper type +PASS WaveShaperNode interface: new WaveShaperNode(context) must inherit property "oversample" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "channelInterpretation" with the proper type +PASS AudioWorklet interface: existence and properties of interface object +PASS AudioWorklet interface object length +PASS AudioWorklet interface object name +PASS AudioWorklet interface: existence and properties of interface prototype object +PASS AudioWorklet interface: existence and properties of interface prototype object's "constructor" property +PASS AudioWorklet interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioWorklet must be primary interface of context.audioWorklet +PASS Stringification of context.audioWorklet +PASS AudioWorkletGlobalScope interface: existence and properties of interface object +PASS AudioParamMap interface: existence and properties of interface object +PASS AudioParamMap interface object length +PASS AudioParamMap interface object name +PASS AudioParamMap interface: existence and properties of interface prototype object +PASS AudioParamMap interface: existence and properties of interface prototype object's "constructor" property +PASS AudioParamMap interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioParamMap must be primary interface of worklet_node.parameters +PASS Stringification of worklet_node.parameters +PASS AudioWorkletNode interface: existence and properties of interface object +PASS AudioWorkletNode interface object length +PASS AudioWorkletNode interface object name +PASS AudioWorkletNode interface: existence and properties of interface prototype object +PASS AudioWorkletNode interface: existence and properties of interface prototype object's "constructor" property +PASS AudioWorkletNode interface: existence and properties of interface prototype object's @@unscopables property +PASS AudioWorkletNode interface: attribute parameters +PASS Unscopable handled correctly for parameters property on AudioWorkletNode +PASS AudioWorkletNode interface: attribute port +PASS Unscopable handled correctly for port property on AudioWorkletNode +PASS AudioWorkletNode interface: attribute onprocessorerror +PASS Unscopable handled correctly for onprocessorerror property on AudioWorkletNode +PASS AudioWorkletNode must be primary interface of worklet_node +PASS Stringification of worklet_node +PASS AudioWorkletNode interface: worklet_node must inherit property "parameters" with the proper type +PASS AudioWorkletNode interface: worklet_node must inherit property "port" with the proper type +PASS AudioWorkletNode interface: worklet_node must inherit property "onprocessorerror" with the proper type +PASS AudioNode interface: worklet_node must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect()" with the proper type +PASS AudioNode interface: worklet_node must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "context" with the proper type +PASS AudioNode interface: worklet_node must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: worklet_node must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: worklet_node must inherit property "channelCount" with the proper type +PASS AudioNode interface: worklet_node must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: worklet_node must inherit property "channelInterpretation" with the proper type +PASS AudioWorkletProcessor interface: existence and properties of interface object +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.window.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.window.js new file mode 100644 index 0000000..eb4734b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.window.js
@@ -0,0 +1,75 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: timeout=long + +// https://webaudio.github.io/web-audio-api/ + +'use strict'; + +idl_test( + ['webaudio'], + ['cssom', 'uievents', 'mediacapture-streams', 'html', 'dom'], + async idl_array => { + idl_array.add_untested_idls('interface SVGElement {};'); + idl_array.add_untested_idls('interface WorkletGlobalScope {};'); + idl_array.add_untested_idls('interface Worklet {};'); + + idl_array.add_objects({ + BaseAudioContext: [], + AudioContext: ['context'], + OfflineAudioContext: ['new OfflineAudioContext(1, 1, sample_rate)'], + OfflineAudioCompletionEvent: [ + 'new OfflineAudioCompletionEvent("", {renderedBuffer: buffer})' + ], + AudioBuffer: ['buffer'], + AudioNode: [], + AudioParam: ['new AudioBufferSourceNode(context).playbackRate'], + AudioScheduledSourceNode: [], + AnalyserNode: ['new AnalyserNode(context)'], + AudioBufferSourceNode: ['new AudioBufferSourceNode(context)'], + AudioDestinationNode: ['context.destination'], + AudioListener: ['context.listener'], + AudioProcessingEvent: [`new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + })`], + BiquadFilterNode: ['new BiquadFilterNode(context)'], + ChannelMergerNode: ['new ChannelMergerNode(context)'], + ChannelSplitterNode: ['new ChannelSplitterNode(context)'], + ConstantSourceNode: ['new ConstantSourceNode(context)'], + ConvolverNode: ['new ConvolverNode(context)'], + DelayNode: ['new DelayNode(context)'], + DynamicsCompressorNode: ['new DynamicsCompressorNode(context)'], + GainNode: ['new GainNode(context)'], + IIRFilterNode: [ + 'new IIRFilterNode(context, {feedforward: [1], feedback: [1]})' + ], + MediaElementAudioSourceNode: [ + 'new MediaElementAudioSourceNode(context, {mediaElement: new Audio})' + ], + MediaStreamAudioDestinationNode: [ + 'new MediaStreamAudioDestinationNode(context)' + ], + MediaStreamAudioSourceNode: [], + MediaStreamTrackAudioSourceNode: [], + OscillatorNode: ['new OscillatorNode(context)'], + PannerNode: ['new PannerNode(context)'], + PeriodicWave: ['new PeriodicWave(context)'], + ScriptProcessorNode: ['context.createScriptProcessor()'], + StereoPannerNode: ['new StereoPannerNode(context)'], + WaveShaperNode: ['new WaveShaperNode(context)'], + AudioWorklet: ['context.audioWorklet'], + AudioWorkletGlobalScope: [], + AudioParamMap: ['worklet_node.parameters'], + AudioWorkletNode: ['worklet_node'], + AudioWorkletProcessor: [], + }); + + self.sample_rate = 44100; + self.context = new AudioContext; + self.buffer = new AudioBuffer({length: 1, sampleRate: sample_rate}); + await context.audioWorklet.addModule( + 'the-audio-api/the-audioworklet-interface/processors/dummy-processor.js'); + self.worklet_node = new AudioWorkletNode(context, 'dummy'); + }, + 'Test driver' +);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webstorage/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/webstorage/idlharness.html deleted file mode 100644 index efff8302..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/webstorage/idlharness.html +++ /dev/null
@@ -1,83 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<meta charset="utf-8"> -<title>Web Storage IDL tests</title> -<link rel="author" title="W3C" href="http://www.w3.org/" /> -<link rel="help" href="http://www.w3.org/TR/webstorage/#storage"/> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/WebIDLParser.js"></script> -<script src="/resources/idlharness.js"></script> -</head> -<body> -<h1>Web Storage IDL tests</h1> -<div id="log"></div> - -<pre id='untested_idl' style='display:none'> -[Global=Window, Exposed=Window] -interface Window { -}; -</pre> - -<pre id='idl'> -interface Storage { - readonly attribute unsigned long length; - DOMString? key(unsigned long index); - getter DOMString? getItem(DOMString key); - setter void setItem(DOMString key, DOMString value); - deleter void removeItem(DOMString key); - void clear(); -}; -[NoInterfaceObject] -interface WindowSessionStorage { - readonly attribute Storage sessionStorage; -}; -Window implements WindowSessionStorage; -[NoInterfaceObject] -interface WindowLocalStorage { - readonly attribute Storage localStorage; -}; -Window implements WindowLocalStorage; -[Constructor(DOMString type, optional StorageEventInit eventInitDict)] -interface StorageEvent : Event { - readonly attribute DOMString? key; - readonly attribute DOMString? oldValue; - readonly attribute DOMString? newValue; - readonly attribute DOMString url; - readonly attribute Storage? storageArea; -}; - -dictionary StorageEventInit : EventInit { - DOMString? key; - DOMString? oldValue; - DOMString? newValue; - DOMString url; - Storage? storageArea; -}; -</pre> - -<script> -function do_test([html, dom]) { - var idl_array = new IdlArray(); - - idl_array.add_untested_idls(dom, { only: ['Event', 'EventInit'] }); - idl_array.add_untested_idls(html, { only: ['EventStorageInit'] }); - idl_array.add_untested_idls(document.getElementById("untested_idl").textContent); - idl_array.add_idls(document.getElementById("idl").textContent); - - idl_array.add_objects({Storage: ["window.localStorage"]}); - - idl_array.test(); -} - -function fetch_text(url) { - return fetch(url).then(response => response.text()); -} - -promise_test(function () { - return Promise.all(['/interfaces/html.idl', '/interfaces/dom.idl'].map(fetch_text)).then(do_test); -}, 'webstorage interfaces'); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webstorage/idlharness.window.js b/third_party/WebKit/LayoutTests/external/wpt/webstorage/idlharness.window.js new file mode 100644 index 0000000..7a6f16a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webstorage/idlharness.window.js
@@ -0,0 +1,30 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// http://www.w3.org/TR/webstorage/#storage + +idl_test( + [], [], // Srcs + deps manually handled below. + async idl_array => { + const [html, dom] = await Promise.all(['html', 'dom'] + .map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); + idl_array.add_idls(html, { + only: [ + 'Storage', + 'WindowSessionStorage', + 'WindowLocalStorage', + 'StorageEvent', + 'StorageEventInit', + ]}); + idl_array.add_dependency_idls(dom); + + idl_array.add_objects({ + Storage: [ + 'localStorage', + 'sessionStorage', + ], + StorageEvent: ['new StorageEvent("storage")'] + }); + }, + 'webstorage interfaces' +);
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/bug420029.html b/third_party/WebKit/LayoutTests/fast/backgrounds/bug420029.html index 20e5c0c..4bcfe4f 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/bug420029.html +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/bug420029.html
@@ -1,6 +1,6 @@ <style> *{ - -webkit-padding-start: 6801059; + padding-inline-start: 6801059; background-image:-webkit-cross-fade(url(foo1), url(foo2), 50%); } </style>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/float-list-changed-before-layout-crash.html b/third_party/WebKit/LayoutTests/fast/block/float/float-list-changed-before-layout-crash.html index ee2f26e..820e7bc8 100644 --- a/third_party/WebKit/LayoutTests/fast/block/float/float-list-changed-before-layout-crash.html +++ b/third_party/WebKit/LayoutTests/fast/block/float/float-list-changed-before-layout-crash.html
@@ -26,7 +26,7 @@ display: table-header-group; } #el6 { - -webkit-border-after: solid; + border-block-end: solid; float: left; } #el6:last-of-type {
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/intruding-float-not-removed-from-next-sibling-crash.html b/third_party/WebKit/LayoutTests/fast/block/float/intruding-float-not-removed-from-next-sibling-crash.html index 544e62e..3960955f 100644 --- a/third_party/WebKit/LayoutTests/fast/block/float/intruding-float-not-removed-from-next-sibling-crash.html +++ b/third_party/WebKit/LayoutTests/fast/block/float/intruding-float-not-removed-from-next-sibling-crash.html
@@ -9,7 +9,7 @@ padding-top: 1em; padding-bottom: 1em; margin-bottom: 1em; - -webkit-margin-before: -100px; + margin-block-start: -100px; } </style> <script>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/overhanging-float-crashes-when-sibling-becomes-formatting-context.html b/third_party/WebKit/LayoutTests/fast/block/float/overhanging-float-crashes-when-sibling-becomes-formatting-context.html index 1e39e89..7216f0e8 100644 --- a/third_party/WebKit/LayoutTests/fast/block/float/overhanging-float-crashes-when-sibling-becomes-formatting-context.html +++ b/third_party/WebKit/LayoutTests/fast/block/float/overhanging-float-crashes-when-sibling-becomes-formatting-context.html
@@ -20,7 +20,7 @@ document.documentElement.style.webkitWritingMode='vertical-rl'; iframe.style.all='unset'; document.documentElement.clientWidth; - iframe.style.webkitMarginAfter='22vmin'; + iframe.style.marginBlockEnd='22vmin'; if (window.testRunner) testRunner.notifyDone(); }
diff --git a/third_party/WebKit/LayoutTests/fast/block/margin-collapse/self-collapsing-block-discards-margin.html b/third_party/WebKit/LayoutTests/fast/block/margin-collapse/self-collapsing-block-discards-margin.html index 2b73efef..0ea6273 100644 --- a/third_party/WebKit/LayoutTests/fast/block/margin-collapse/self-collapsing-block-discards-margin.html +++ b/third_party/WebKit/LayoutTests/fast/block/margin-collapse/self-collapsing-block-discards-margin.html
@@ -3,7 +3,7 @@ <style> * { clear:both; } .discard { clear:none; -webkit-margin-after-collapse:discard; } -.float { display:inherit; -webkit-border-before-style:dashed; float:left; margin-top:2%; } +.float { display:inherit; border-block-start-style:dashed; float:left; margin-top:2%; } </style> <div class="float"></div> <div class="discard"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-lr/003.html b/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-lr/003.html index 9ace83e2f..c8f83de 100644 --- a/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-lr/003.html +++ b/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-lr/003.html
@@ -24,7 +24,7 @@ div#two { background: green; - -webkit-margin-before: -100px; + margin-block-start: -100px; } body { -webkit-writing-mode: vertical-lr }
diff --git a/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-lr/004.html b/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-lr/004.html index 77c51fa..fffcdb2 100644 --- a/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-lr/004.html +++ b/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-lr/004.html
@@ -24,7 +24,7 @@ div#two { background: green; - -webkit-margin-before: -100px; + margin-block-start: -100px; } body { -webkit-writing-mode: vertical-lr }
diff --git a/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-rl/003.html b/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-rl/003.html index ff29337..b938d603 100644 --- a/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-rl/003.html +++ b/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-rl/003.html
@@ -24,7 +24,7 @@ div#two { background: green; - -webkit-margin-before: -100px; + margin-block-start: -100px; } body { -webkit-writing-mode: vertical-rl }
diff --git a/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-rl/004.html b/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-rl/004.html index 74757f8..31c3618 100644 --- a/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-rl/004.html +++ b/third_party/WebKit/LayoutTests/fast/block/positioning/vertical-rl/004.html
@@ -24,7 +24,7 @@ div#two { background: green; - -webkit-margin-before: -100px; + margin-block-start: -100px; } body { -webkit-writing-mode: vertical-rl }
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-border-radius.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-border-radius.html index 1504fc1..ef3bf20 100644 --- a/third_party/WebKit/LayoutTests/fast/borders/border-image-border-radius.html +++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-border-radius.html
@@ -1,3 +1,4 @@ +<!DOCTYPE html> <html> <head> <style>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-styles-split.html b/third_party/WebKit/LayoutTests/fast/borders/border-styles-split.html index 6a71032..427ca95 100644 --- a/third_party/WebKit/LayoutTests/fast/borders/border-styles-split.html +++ b/third_party/WebKit/LayoutTests/fast/borders/border-styles-split.html
@@ -3,7 +3,7 @@ display: inline-block; } span { - -webkit-padding-start: 15px; -webkit-padding-end:15px; + padding-inline-start: 15px; padding-inline-end:15px; font-size: 48px; background-color: #DDD; line-height: 2em;
diff --git a/third_party/WebKit/LayoutTests/fast/css/border-start-end-expected.txt b/third_party/WebKit/LayoutTests/fast/css/border-start-end-expected.txt index fe7f945..da92363 100644 --- a/third_party/WebKit/LayoutTests/fast/css/border-start-end-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/border-start-end-expected.txt
@@ -3,46 +3,46 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS testWidth("ltr", "-webkit-border-start-width: 10px; -webkit-border-start-style: solid") is 110 -PASS testWidth("ltr", "-webkit-border-end-width: 20px; -webkit-border-end-style: solid") is 120 -PASS testWidth("rtl", "-webkit-border-start-width: 10px; -webkit-border-start-style: solid") is 110 -PASS testWidth("rtl", "-webkit-border-end-width: 20px; -webkit-border-end-style: solid") is 120 -PASS test("ltr", "-webkit-border-start-color: rgb(255, 0, 0)", "border-left-color") is "rgb(255, 0, 0)" -PASS test("ltr", "border-left-color: rgb(255, 0, 0)", "-webkit-border-start-color") is "rgb(255, 0, 0)" -PASS test("ltr", "-webkit-border-end-color: rgb(255, 0, 0)", "border-right-color") is "rgb(255, 0, 0)" -PASS test("ltr", "border-right-color: rgb(255, 0, 0)", "-webkit-border-end-color") is "rgb(255, 0, 0)" -PASS test("rtl", "-webkit-border-start-color: rgb(255, 0, 0)", "border-right-color") is "rgb(255, 0, 0)" -PASS test("rtl", "border-right-color: rgb(255, 0, 0)", "-webkit-border-start-color") is "rgb(255, 0, 0)" -PASS test("rtl", "-webkit-border-end-color: rgb(255, 0, 0)", "border-left-color") is "rgb(255, 0, 0)" -PASS test("rtl", "border-left-color: rgb(255, 0, 0)", "-webkit-border-end-color") is "rgb(255, 0, 0)" -PASS test("ltr", "-webkit-border-start-style: dotted", "border-left-style") is "dotted" -PASS test("ltr", "border-left-style: dotted", "-webkit-border-start-style") is "dotted" -PASS test("ltr", "-webkit-border-end-style: dotted", "border-right-style") is "dotted" -PASS test("ltr", "border-right-style: dotted", "-webkit-border-end-style") is "dotted" -PASS test("rtl", "-webkit-border-start-style: dotted", "border-right-style") is "dotted" -PASS test("rtl", "border-right-style: dotted", "-webkit-border-start-style") is "dotted" -PASS test("rtl", "-webkit-border-end-style: dotted", "border-left-style") is "dotted" -PASS test("rtl", "border-left-style: dotted", "-webkit-border-end-style") is "dotted" -PASS test("ltr", "-webkit-border-start-width: 10px; -webkit-border-start-style: solid", "border-left-width") is "10px" -PASS test("ltr", "-webkit-border-end-width: 10px; -webkit-border-end-style: solid", "border-right-width") is "10px" -PASS test("rtl", "-webkit-border-start-width: 10px; -webkit-border-start-style: solid", "border-right-width") is "10px" -PASS test("rtl", "-webkit-border-end-width: 10px; -webkit-border-end-style: solid", "border-left-width") is "10px" -PASS test("ltr", "border-left: 10px solid", "-webkit-border-start-width") is "10px" -PASS test("ltr", "border-right: 10px solid", "-webkit-border-end-width") is "10px" -PASS test("rtl", "border-left: 10px solid", "-webkit-border-end-width") is "10px" -PASS test("rtl", "border-right: 10px solid", "-webkit-border-start-width") is "10px" -PASS test("ltr", "-webkit-border-start: 10px solid red", "border-left-color") is "rgb(255, 0, 0)" -PASS test("ltr", "-webkit-border-start: 10px solid red", "border-left-style") is "solid" -PASS test("ltr", "-webkit-border-start: 10px solid red", "border-left-width") is "10px" -PASS test("rtl", "-webkit-border-start: 10px solid red", "border-right-color") is "rgb(255, 0, 0)" -PASS test("rtl", "-webkit-border-start: 10px solid red", "border-right-style") is "solid" -PASS test("rtl", "-webkit-border-start: 10px solid red", "border-right-width") is "10px" -PASS test("ltr", "-webkit-border-end: 10px solid red", "border-right-color") is "rgb(255, 0, 0)" -PASS test("ltr", "-webkit-border-end: 10px solid red", "border-right-style") is "solid" -PASS test("ltr", "-webkit-border-end: 10px solid red", "border-right-width") is "10px" -PASS test("rtl", "-webkit-border-end: 10px solid red", "border-left-color") is "rgb(255, 0, 0)" -PASS test("rtl", "-webkit-border-end: 10px solid red", "border-left-style") is "solid" -PASS test("rtl", "-webkit-border-end: 10px solid red", "border-left-width") is "10px" +PASS testWidth("ltr", "border-inline-start-width: 10px; border-inline-start-style: solid") is 110 +PASS testWidth("ltr", "border-inline-end-width: 20px; border-inline-end-style: solid") is 120 +PASS testWidth("rtl", "border-inline-start-width: 10px; border-inline-start-style: solid") is 110 +PASS testWidth("rtl", "border-inline-end-width: 20px; border-inline-end-style: solid") is 120 +PASS test("ltr", "border-inline-start-color: rgb(255, 0, 0)", "border-left-color") is "rgb(255, 0, 0)" +PASS test("ltr", "border-left-color: rgb(255, 0, 0)", "border-inline-start-color") is "rgb(255, 0, 0)" +PASS test("ltr", "border-inline-end-color: rgb(255, 0, 0)", "border-right-color") is "rgb(255, 0, 0)" +PASS test("ltr", "border-right-color: rgb(255, 0, 0)", "border-inline-end-color") is "rgb(255, 0, 0)" +PASS test("rtl", "border-inline-start-color: rgb(255, 0, 0)", "border-right-color") is "rgb(255, 0, 0)" +PASS test("rtl", "border-right-color: rgb(255, 0, 0)", "border-inline-start-color") is "rgb(255, 0, 0)" +PASS test("rtl", "border-inline-end-color: rgb(255, 0, 0)", "border-left-color") is "rgb(255, 0, 0)" +PASS test("rtl", "border-left-color: rgb(255, 0, 0)", "border-inline-end-color") is "rgb(255, 0, 0)" +PASS test("ltr", "border-inline-start-style: dotted", "border-left-style") is "dotted" +PASS test("ltr", "border-left-style: dotted", "border-inline-start-style") is "dotted" +PASS test("ltr", "border-inline-end-style: dotted", "border-right-style") is "dotted" +PASS test("ltr", "border-right-style: dotted", "border-inline-end-style") is "dotted" +PASS test("rtl", "border-inline-start-style: dotted", "border-right-style") is "dotted" +PASS test("rtl", "border-right-style: dotted", "border-inline-start-style") is "dotted" +PASS test("rtl", "border-inline-end-style: dotted", "border-left-style") is "dotted" +PASS test("rtl", "border-left-style: dotted", "border-inline-end-style") is "dotted" +PASS test("ltr", "border-inline-start-width: 10px; border-inline-start-style: solid", "border-left-width") is "10px" +PASS test("ltr", "border-inline-end-width: 10px; border-inline-end-style: solid", "border-right-width") is "10px" +PASS test("rtl", "border-inline-start-width: 10px; border-inline-start-style: solid", "border-right-width") is "10px" +PASS test("rtl", "border-inline-end-width: 10px; border-inline-end-style: solid", "border-left-width") is "10px" +PASS test("ltr", "border-left: 10px solid", "border-inline-start-width") is "10px" +PASS test("ltr", "border-right: 10px solid", "border-inline-end-width") is "10px" +PASS test("rtl", "border-left: 10px solid", "border-inline-end-width") is "10px" +PASS test("rtl", "border-right: 10px solid", "border-inline-start-width") is "10px" +PASS test("ltr", "border-inline-start: 10px solid red", "border-left-color") is "rgb(255, 0, 0)" +PASS test("ltr", "border-inline-start: 10px solid red", "border-left-style") is "solid" +PASS test("ltr", "border-inline-start: 10px solid red", "border-left-width") is "10px" +PASS test("rtl", "border-inline-start: 10px solid red", "border-right-color") is "rgb(255, 0, 0)" +PASS test("rtl", "border-inline-start: 10px solid red", "border-right-style") is "solid" +PASS test("rtl", "border-inline-start: 10px solid red", "border-right-width") is "10px" +PASS test("ltr", "border-inline-end: 10px solid red", "border-right-color") is "rgb(255, 0, 0)" +PASS test("ltr", "border-inline-end: 10px solid red", "border-right-style") is "solid" +PASS test("ltr", "border-inline-end: 10px solid red", "border-right-width") is "10px" +PASS test("rtl", "border-inline-end: 10px solid red", "border-left-color") is "rgb(255, 0, 0)" +PASS test("rtl", "border-inline-end: 10px solid red", "border-left-style") is "solid" +PASS test("rtl", "border-inline-end: 10px solid red", "border-left-width") is "10px" PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/css/crash-inherit-value-font-family.html b/third_party/WebKit/LayoutTests/fast/css/crash-inherit-value-font-family.html index 100a041..48a6bae 100644 --- a/third_party/WebKit/LayoutTests/fast/css/crash-inherit-value-font-family.html +++ b/third_party/WebKit/LayoutTests/fast/css/crash-inherit-value-font-family.html
@@ -1,6 +1,6 @@ <!DOCTYPE html> <body> -<var style="float: right; -webkit-border-before: groove; font-family: inherit"></var> +<var style="float: right; border-block-start: groove; font-family: inherit"></var> <script> if (window.testRunner)
diff --git a/third_party/WebKit/LayoutTests/fast/css/fontMetric-webkit-border-end-width-null-crash.html b/third_party/WebKit/LayoutTests/fast/css/fontMetric-webkit-border-end-width-null-crash.html index a3aa5d4..b0538f8 100644 --- a/third_party/WebKit/LayoutTests/fast/css/fontMetric-webkit-border-end-width-null-crash.html +++ b/third_party/WebKit/LayoutTests/fast/css/fontMetric-webkit-border-end-width-null-crash.html
@@ -2,7 +2,7 @@ if (window.testRunner) testRunner.dumpAsText(); document.writeln("<v>"); - document.body.innerHTML="<style>*{-webkit-border-end-width:0ex;}</style>"; + document.body.innerHTML="<style>*{border-inline-end-width:0ex;}</style>"; document.write("<title>x"); document.body.innerHTML = "<a href='https://bugs.webkit.org/show_bug.cgi?id=57756'>chrome.dll!WebCore::ComputedStyle::fontMetrics ReadAV@NULL (two crashes)<br>PASSED: This test did not crash!"; </script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/identical-logical-height-decl.html b/third_party/WebKit/LayoutTests/fast/css/identical-logical-height-decl.html index 20888a1..bd5d8910 100644 --- a/third_party/WebKit/LayoutTests/fast/css/identical-logical-height-decl.html +++ b/third_party/WebKit/LayoutTests/fast/css/identical-logical-height-decl.html
@@ -5,9 +5,9 @@ </head> <body style="overflow:hidden;"> <p>There should be no red on this page.</p> - <div style="-webkit-logical-height:10px;"></div> <!-- set height --> + <div style="block-size:10px;"></div> <!-- set height --> <div style="-webkit-writing-mode:vertical-lr; width:100px; height:100px; background:red;"> - <div style="-webkit-logical-height:10px;"> <!-- set width! --> + <div style="block-size:10px;"> <!-- set width! --> <div style="width:100px; background:white;"></div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/css/inherit-initial-shorthand-values-expected.txt b/third_party/WebKit/LayoutTests/fast/css/inherit-initial-shorthand-values-expected.txt index 83374a0..adda70d8 100644 --- a/third_party/WebKit/LayoutTests/fast/css/inherit-initial-shorthand-values-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/inherit-initial-shorthand-values-expected.txt
@@ -2,8 +2,12 @@ PASS test('background-position') is "inherit, initial" PASS test('background-repeat') is "inherit, initial" PASS test('border') is "inherit, initial" +PASS test('border-block-end') is "inherit, initial" +PASS test('border-block-start') is "inherit, initial" PASS test('border-bottom') is "inherit, initial" PASS test('border-color') is "inherit, initial" +PASS test('border-inline-end') is "inherit, initial" +PASS test('border-inline-start') is "inherit, initial" PASS test('border-left') is "inherit, initial" PASS test('border-radius') is "inherit, initial" PASS test('border-right') is "inherit, initial" @@ -18,10 +22,6 @@ PASS test('overflow') is "inherit, initial" PASS test('padding') is "inherit, initial" PASS test('webkit-animation') is "inherit, initial" -PASS test('webkit-border-after') is "inherit, initial" -PASS test('webkit-border-before') is "inherit, initial" -PASS test('webkit-border-end') is "inherit, initial" -PASS test('webkit-border-start') is "inherit, initial" PASS test('webkit-columns') is "inherit, initial" PASS test('webkit-column-rule') is "inherit, initial" PASS test('webkit-flex-flow') is "inherit, initial"
diff --git a/third_party/WebKit/LayoutTests/fast/css/inherit-initial-shorthand-values.html b/third_party/WebKit/LayoutTests/fast/css/inherit-initial-shorthand-values.html index fbc93530..6e49ec44 100644 --- a/third_party/WebKit/LayoutTests/fast/css/inherit-initial-shorthand-values.html +++ b/third_party/WebKit/LayoutTests/fast/css/inherit-initial-shorthand-values.html
@@ -18,10 +18,14 @@ "background-position", "background-repeat", "border", + "border-block-end", + "border-block-start", "border-bottom", "border-color", // getPropertyValue() functionality not supported, see http://webkit.org/b/103245. // "border-image", + "border-inline-end", + "border-inline-start", "border-left", "border-radius", "border-right", @@ -36,10 +40,6 @@ "overflow", "padding", "webkit-animation", - "webkit-border-after", - "webkit-border-before", - "webkit-border-end", - "webkit-border-start", "webkit-columns", "webkit-column-rule", "webkit-flex-flow",
diff --git a/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution-webkit-prefix-expected.txt b/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution-webkit-prefix-expected.txt new file mode 100644 index 0000000..88f7c87 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution-webkit-prefix-expected.txt
@@ -0,0 +1,38 @@ +This test has incorrect results but reflects what's happening as we bring block-flow online. +Block #1: +Margins: 1px 2px 3px 4px +Padding: 4px 3px 2px 1px +Borders: 1px solid rgb(0, 0, 0), 2px dotted rgb(0, 128, 0), 3px dashed rgb(255, 255, 0), 4px double rgb(128, 0, 128) +Width: 100px +Height: 50px +Block #2: +Margins: 4px 3px 2px 1px +Padding: 1px 2px 3px 4px +Borders: 4px double rgb(128, 0, 128), 3px dashed rgb(255, 255, 0), 2px dotted rgb(0, 128, 0), 1px solid rgb(0, 0, 0) +Width: 50px +Height: 100px +Block #3: +Margins: 4px 1px 2px 3px +Padding: 1px 4px 3px 2px +Borders: 4px double rgb(128, 0, 128), 1px solid rgb(0, 0, 0), 2px dotted rgb(0, 128, 0), 3px dashed rgb(255, 255, 0) +Width: 50px +Height: 100px +Block #4: +Margins: 1px 4px 3px 2px +Padding: 4px 1px 2px 3px +Borders: 1px solid rgb(0, 0, 0), 4px double rgb(128, 0, 128), 3px dashed rgb(255, 255, 0), 2px dotted rgb(0, 128, 0) +Width: 100px +Height: 50px +Block #5: +Margins: 2px 3px 4px 1px +Padding: 3px 2px 1px 4px +Borders: 2px dotted rgb(0, 128, 0), 3px dashed rgb(255, 255, 0), 4px double rgb(128, 0, 128), 1px solid rgb(0, 0, 0) +Width: 50px +Height: 100px +Block #6: +Margins: 2px 1px 4px 3px +Padding: 3px 4px 1px 2px +Borders: 2px dotted rgb(0, 128, 0), 1px solid rgb(0, 0, 0), 4px double rgb(128, 0, 128), 3px dashed rgb(255, 255, 0) +Width: 50px +Height: 100px +
diff --git a/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution-webkit-prefix.html b/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution-webkit-prefix.html new file mode 100644 index 0000000..48d1570 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution-webkit-prefix.html
@@ -0,0 +1,93 @@ +<html> +<head> +<style> +.ltr-text { + direction: ltr +} + +.rtl-text { + direction: rtl +} + +.tb-block { + -webkit-writing-mode: horizontal-tb; +} + +.lr-block { + -webkit-writing-mode: vertical-lr +} + +.rl-block { + -webkit-writing-mode: vertical-rl +} + +.test { + -webkit-margin-before: 1px; + -webkit-margin-end: 2px; + -webkit-margin-after: 3px; + -webkit-margin-start: 4px; + -webkit-padding-before:4px; + -webkit-padding-end:3px; + -webkit-padding-after:2px; + -webkit-padding-start:1px; + -webkit-logical-width:100px; + -webkit-logical-height:50px; + -webkit-border-before: 1px solid black; + -webkit-border-end: 2px dotted green; + -webkit-border-after: 3px dashed yellow; + -webkit-border-start: 4px double purple; + float:left; +} +</style> +<script> +if (window.testRunner) + testRunner.dumpAsText() + +function dumpBlockProperties() +{ + result = document.getElementById('result'); + blocks = document.getElementsByTagName('div'); + resultStr = "This test has incorrect results but reflects what's happening as we bring block-flow online.<br>"; + for (i = 0; i < blocks.length; ++i) { + resultStr += "<b>Block #" + (i+1) + ":</b><br>"; + resultStr += "Margins: "; + c = getComputedStyle(blocks[i], null); + resultStr += c.getPropertyValue("margin-top") + " " + + c.getPropertyValue("margin-right") + " " + + c.getPropertyValue("margin-bottom") + " " + + c.getPropertyValue("margin-left") + "<br>"; + + resultStr += "Padding: "; + c = getComputedStyle(blocks[i], null); + resultStr += c.getPropertyValue("padding-top") + " " + + c.getPropertyValue("padding-right") + " " + + c.getPropertyValue("padding-bottom") + " " + + c.getPropertyValue("padding-left") + "<br>"; + + resultStr += "Borders: " + resultStr += c.getPropertyValue("border-top-width") + " " + c.getPropertyValue("border-top-style") + " " + c.getPropertyValue("border-top-color") + ", " + + c.getPropertyValue("border-right-width") + " " + c.getPropertyValue("border-right-style") + " " + c.getPropertyValue("border-right-color") + ", " + + c.getPropertyValue("border-bottom-width") + " " + c.getPropertyValue("border-bottom-style") + " " + c.getPropertyValue("border-bottom-color") + ", " + + c.getPropertyValue("border-left-width") + " " + c.getPropertyValue("border-left-style") + " " + c.getPropertyValue("border-left-color") + "<br>" + + resultStr += "Width: " + resultStr += c.getPropertyValue("width") + "<br>"; + + resultStr += "Height: " + resultStr += c.getPropertyValue("height") + "<br>"; + } + result.innerHTML = resultStr; +} +</script> +</head> +<body onload="dumpBlockProperties()"> +<div class="ltr-text tb-block test"></div> +<div class="ltr-text lr-block test"></div> +<div class="ltr-text rl-block test"></div> +<div class="rtl-text tb-block test"></div> +<div class="rtl-text lr-block test"></div> +<div class="rtl-text rl-block test"></div> +<p style="clear:both" id="result"></p> +</body> +</html> +
diff --git a/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution.html b/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution.html index 48d1570..2257b34 100644 --- a/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution.html +++ b/third_party/WebKit/LayoutTests/fast/css/logical-property-resolution.html
@@ -22,20 +22,20 @@ } .test { - -webkit-margin-before: 1px; - -webkit-margin-end: 2px; - -webkit-margin-after: 3px; - -webkit-margin-start: 4px; - -webkit-padding-before:4px; - -webkit-padding-end:3px; - -webkit-padding-after:2px; - -webkit-padding-start:1px; - -webkit-logical-width:100px; - -webkit-logical-height:50px; - -webkit-border-before: 1px solid black; - -webkit-border-end: 2px dotted green; - -webkit-border-after: 3px dashed yellow; - -webkit-border-start: 4px double purple; + margin-block-start: 1px; + margin-inline-end: 2px; + margin-block-end: 3px; + margin-inline-start: 4px; + padding-block-start:4px; + padding-inline-end:3px; + padding-block-end:2px; + padding-inline-start:1px; + inline-size:100px; + block-size:50px; + border-block-start: 1px solid black; + border-inline-end: 2px dotted green; + border-block-end: 3px dashed yellow; + border-inline-start: 4px double purple; float:left; } </style>
diff --git a/third_party/WebKit/LayoutTests/fast/css/margin-start-end-expected.txt b/third_party/WebKit/LayoutTests/fast/css/margin-start-end-expected.txt index 121c5c33..def03d1f 100644 --- a/third_party/WebKit/LayoutTests/fast/css/margin-start-end-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/margin-start-end-expected.txt
@@ -3,18 +3,18 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS test("ltr", "-webkit-margin-start", "10px", "width") is "90px" -PASS test("ltr", "-webkit-margin-end", "20px", "width") is "80px" -PASS test("ltr", "-webkit-margin-start", "10px", "margin-left") is "10px" -PASS test("ltr", "-webkit-margin-end", "20px", "margin-right") is "20px" -PASS test("ltr", "margin-left", "10px", "-webkit-margin-start") is "10px" -PASS test("ltr", "margin-right", "20px", "-webkit-margin-end") is "20px" -PASS test("rtl", "-webkit-margin-start", "10px", "width") is "90px" -PASS test("rtl", "-webkit-margin-end", "20px", "width") is "80px" -PASS test("rtl", "-webkit-margin-start", "10px", "margin-right") is "10px" -PASS test("rtl", "-webkit-margin-end", "20px", "margin-left") is "20px" -PASS test("rtl", "margin-right", "10px", "-webkit-margin-start") is "10px" -PASS test("rtl", "margin-left", "20px", "-webkit-margin-end") is "20px" +PASS test("ltr", "margin-inline-start", "10px", "width") is "90px" +PASS test("ltr", "margin-inline-end", "20px", "width") is "80px" +PASS test("ltr", "margin-inline-start", "10px", "margin-left") is "10px" +PASS test("ltr", "margin-inline-end", "20px", "margin-right") is "20px" +PASS test("ltr", "margin-left", "10px", "margin-inline-start") is "10px" +PASS test("ltr", "margin-right", "20px", "margin-inline-end") is "20px" +PASS test("rtl", "margin-inline-start", "10px", "width") is "90px" +PASS test("rtl", "margin-inline-end", "20px", "width") is "80px" +PASS test("rtl", "margin-inline-start", "10px", "margin-right") is "10px" +PASS test("rtl", "margin-inline-end", "20px", "margin-left") is "20px" +PASS test("rtl", "margin-right", "10px", "margin-inline-start") is "10px" +PASS test("rtl", "margin-left", "20px", "margin-inline-end") is "20px" PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/css/padding-start-end-expected.txt b/third_party/WebKit/LayoutTests/fast/css/padding-start-end-expected.txt index 8dce0c4..f80303c 100644 --- a/third_party/WebKit/LayoutTests/fast/css/padding-start-end-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/padding-start-end-expected.txt
@@ -3,18 +3,18 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS testWidth("ltr", "-webkit-padding-start", "10px") is 110 -PASS testWidth("ltr", "-webkit-padding-end", "20px") is 120 -PASS test("ltr", "-webkit-padding-start", "10px", "padding-left") is "10px" -PASS test("ltr", "-webkit-padding-end", "20px", "padding-right") is "20px" -PASS test("ltr", "padding-left", "10px", "-webkit-padding-start") is "10px" -PASS test("ltr", "padding-right", "20px", "-webkit-padding-end") is "20px" -PASS testWidth("rtl", "-webkit-padding-start", "10px") is 110 -PASS testWidth("rtl", "-webkit-padding-end", "20px") is 120 -PASS test("rtl", "-webkit-padding-start", "10px", "padding-right") is "10px" -PASS test("rtl", "-webkit-padding-end", "20px", "padding-left") is "20px" -PASS test("rtl", "padding-right", "10px", "-webkit-padding-start") is "10px" -PASS test("rtl", "padding-left", "20px", "-webkit-padding-end") is "20px" +PASS testWidth("ltr", "padding-inline-start", "10px") is 110 +PASS testWidth("ltr", "padding-inline-end", "20px") is 120 +PASS test("ltr", "padding-inline-start", "10px", "padding-left") is "10px" +PASS test("ltr", "padding-inline-end", "20px", "padding-right") is "20px" +PASS test("ltr", "padding-left", "10px", "padding-inline-start") is "10px" +PASS test("ltr", "padding-right", "20px", "padding-inline-end") is "20px" +PASS testWidth("rtl", "padding-inline-start", "10px") is 110 +PASS testWidth("rtl", "padding-inline-end", "20px") is 120 +PASS test("rtl", "padding-inline-start", "10px", "padding-right") is "10px" +PASS test("rtl", "padding-inline-end", "20px", "padding-left") is "20px" +PASS test("rtl", "padding-right", "10px", "padding-inline-start") is "10px" +PASS test("rtl", "padding-left", "20px", "padding-inline-end") is "20px" PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/css/parsing-color-quirk-expected.txt b/third_party/WebKit/LayoutTests/fast/css/parsing-color-quirk-expected.txt index 63567ae3..c33ec5bb 100644 --- a/third_party/WebKit/LayoutTests/fast/css/parsing-color-quirk-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/parsing-color-quirk-expected.txt
@@ -13,10 +13,10 @@ PASS No hashless color quirk for text-shadow color PASS No hashless color quirk for box-shadow color PASS No hashless color quirk for linear-gradient colors -PASS No hashless color quirk for -webkit-border-start-color property -PASS No hashless color quirk for -webkit-border-end-color property -PASS No hashless color quirk for -webkit-border-before-property -PASS No hashless color quirk for -webkit-border-after-color property +PASS No hashless color quirk for border-inline-start-color property +PASS No hashless color quirk for border-inline-end-color property +PASS No hashless color quirk for border-block-start-property +PASS No hashless color quirk for border-block-end-color property PASS No hashless color quirk for -webkit-column-rule-color property PASS No hashless color quirk for -webkit-text-emphasis-color property PASS No hashless color quirk for -webkit-text-fill-color property
diff --git a/third_party/WebKit/LayoutTests/fast/css/parsing-color-quirk.html b/third_party/WebKit/LayoutTests/fast/css/parsing-color-quirk.html index a77f9438..c0efa1e 100644 --- a/third_party/WebKit/LayoutTests/fast/css/parsing-color-quirk.html +++ b/third_party/WebKit/LayoutTests/fast/css/parsing-color-quirk.html
@@ -14,10 +14,10 @@ #t10 { box-shadow: 1px 1px ff0000 } #t11 { background-image: linear-gradient(ff0000, blue); } -#t12 { -webkit-border-start-color: ff0000 } -#t13 { -webkit-border-end-color: ff0000 } -#t14 { -webkit-border-before-color: ff0000 } -#t15 { -webkit-border-after-color: ff0000 } +#t12 { border-inline-start-color: ff0000 } +#t13 { border-inline-end-color: ff0000 } +#t14 { border-block-start-color: ff0000 } +#t15 { border-block-end-color: ff0000 } #t16 { -webkit-column-rule-color: ff0000 } @@ -113,20 +113,20 @@ }, "No hashless color quirk for linear-gradient colors"); test(function(){ - assert_equals(sheet.cssRules[11].style.WebkitBorderStartColor, ""); -}, "No hashless color quirk for -webkit-border-start-color property"); + assert_equals(sheet.cssRules[11].style.borderInlineStartColor, ""); +}, "No hashless color quirk for border-inline-start-color property"); test(function(){ - assert_equals(sheet.cssRules[12].style.WebkitBorderEndColor, ""); -}, "No hashless color quirk for -webkit-border-end-color property"); + assert_equals(sheet.cssRules[12].style.borderInlineEndColor, ""); +}, "No hashless color quirk for border-inline-end-color property"); test(function(){ - assert_equals(sheet.cssRules[13].style.WebkitBorderBeforeColor, ""); -}, "No hashless color quirk for -webkit-border-before-property"); + assert_equals(sheet.cssRules[13].style.borderBlockStartColor, ""); +}, "No hashless color quirk for border-block-start-property"); test(function(){ - assert_equals(sheet.cssRules[14].style.WebkitBorderAfterColor, ""); -}, "No hashless color quirk for -webkit-border-after-color property"); + assert_equals(sheet.cssRules[14].style.borderBlockEndColor, ""); +}, "No hashless color quirk for border-block-end-color property"); test(function(){ assert_equals(sheet.cssRules[15].style.WebkitColumnRuleColor, "");
diff --git a/third_party/WebKit/LayoutTests/fast/css/script-tests/border-start-end.js b/third_party/WebKit/LayoutTests/fast/css/script-tests/border-start-end.js index 0ed26443..ddc6d672 100644 --- a/third_party/WebKit/LayoutTests/fast/css/script-tests/border-start-end.js +++ b/third_party/WebKit/LayoutTests/fast/css/script-tests/border-start-end.js
@@ -30,43 +30,43 @@ return result; } -shouldBe('testWidth("ltr", "-webkit-border-start-width: 10px; -webkit-border-start-style: solid")', '110'); -shouldBe('testWidth("ltr", "-webkit-border-end-width: 20px; -webkit-border-end-style: solid")', '120'); -shouldBe('testWidth("rtl", "-webkit-border-start-width: 10px; -webkit-border-start-style: solid")', '110'); -shouldBe('testWidth("rtl", "-webkit-border-end-width: 20px; -webkit-border-end-style: solid")', '120'); +shouldBe('testWidth("ltr", "border-inline-start-width: 10px; border-inline-start-style: solid")', '110'); +shouldBe('testWidth("ltr", "border-inline-end-width: 20px; border-inline-end-style: solid")', '120'); +shouldBe('testWidth("rtl", "border-inline-start-width: 10px; border-inline-start-style: solid")', '110'); +shouldBe('testWidth("rtl", "border-inline-end-width: 20px; border-inline-end-style: solid")', '120'); -testSame('ltr', '-webkit-border-start-color', 'border-left-color', 'rgb(255, 0, 0)'); -testSame('ltr', '-webkit-border-end-color', 'border-right-color', 'rgb(255, 0, 0)'); -testSame('rtl', '-webkit-border-start-color', 'border-right-color', 'rgb(255, 0, 0)'); -testSame('rtl', '-webkit-border-end-color', 'border-left-color', 'rgb(255, 0, 0)'); +testSame('ltr', 'border-inline-start-color', 'border-left-color', 'rgb(255, 0, 0)'); +testSame('ltr', 'border-inline-end-color', 'border-right-color', 'rgb(255, 0, 0)'); +testSame('rtl', 'border-inline-start-color', 'border-right-color', 'rgb(255, 0, 0)'); +testSame('rtl', 'border-inline-end-color', 'border-left-color', 'rgb(255, 0, 0)'); -testSame('ltr', '-webkit-border-start-style', 'border-left-style', 'dotted'); -testSame('ltr', '-webkit-border-end-style', 'border-right-style', 'dotted'); -testSame('rtl', '-webkit-border-start-style', 'border-right-style', 'dotted'); -testSame('rtl', '-webkit-border-end-style', 'border-left-style', 'dotted'); +testSame('ltr', 'border-inline-start-style', 'border-left-style', 'dotted'); +testSame('ltr', 'border-inline-end-style', 'border-right-style', 'dotted'); +testSame('rtl', 'border-inline-start-style', 'border-right-style', 'dotted'); +testSame('rtl', 'border-inline-end-style', 'border-left-style', 'dotted'); -shouldBeEqualToString('test("ltr", "-webkit-border-start-width: 10px; -webkit-border-start-style: solid", "border-left-width")', '10px'); -shouldBeEqualToString('test("ltr", "-webkit-border-end-width: 10px; -webkit-border-end-style: solid", "border-right-width")', '10px'); -shouldBeEqualToString('test("rtl", "-webkit-border-start-width: 10px; -webkit-border-start-style: solid", "border-right-width")', '10px'); -shouldBeEqualToString('test("rtl", "-webkit-border-end-width: 10px; -webkit-border-end-style: solid", "border-left-width")', '10px'); +shouldBeEqualToString('test("ltr", "border-inline-start-width: 10px; border-inline-start-style: solid", "border-left-width")', '10px'); +shouldBeEqualToString('test("ltr", "border-inline-end-width: 10px; border-inline-end-style: solid", "border-right-width")', '10px'); +shouldBeEqualToString('test("rtl", "border-inline-start-width: 10px; border-inline-start-style: solid", "border-right-width")', '10px'); +shouldBeEqualToString('test("rtl", "border-inline-end-width: 10px; border-inline-end-style: solid", "border-left-width")', '10px'); -shouldBeEqualToString('test("ltr", "border-left: 10px solid", "-webkit-border-start-width")', '10px'); -shouldBeEqualToString('test("ltr", "border-right: 10px solid", "-webkit-border-end-width")', '10px'); -shouldBeEqualToString('test("rtl", "border-left: 10px solid", "-webkit-border-end-width")', '10px'); -shouldBeEqualToString('test("rtl", "border-right: 10px solid", "-webkit-border-start-width")', '10px'); +shouldBeEqualToString('test("ltr", "border-left: 10px solid", "border-inline-start-width")', '10px'); +shouldBeEqualToString('test("ltr", "border-right: 10px solid", "border-inline-end-width")', '10px'); +shouldBeEqualToString('test("rtl", "border-left: 10px solid", "border-inline-end-width")', '10px'); +shouldBeEqualToString('test("rtl", "border-right: 10px solid", "border-inline-start-width")', '10px'); -shouldBeEqualToString('test("ltr", "-webkit-border-start: 10px solid red", "border-left-color")', 'rgb(255, 0, 0)'); -shouldBeEqualToString('test("ltr", "-webkit-border-start: 10px solid red", "border-left-style")', 'solid'); -shouldBeEqualToString('test("ltr", "-webkit-border-start: 10px solid red", "border-left-width")', '10px'); +shouldBeEqualToString('test("ltr", "border-inline-start: 10px solid red", "border-left-color")', 'rgb(255, 0, 0)'); +shouldBeEqualToString('test("ltr", "border-inline-start: 10px solid red", "border-left-style")', 'solid'); +shouldBeEqualToString('test("ltr", "border-inline-start: 10px solid red", "border-left-width")', '10px'); -shouldBeEqualToString('test("rtl", "-webkit-border-start: 10px solid red", "border-right-color")', 'rgb(255, 0, 0)'); -shouldBeEqualToString('test("rtl", "-webkit-border-start: 10px solid red", "border-right-style")', 'solid'); -shouldBeEqualToString('test("rtl", "-webkit-border-start: 10px solid red", "border-right-width")', '10px'); +shouldBeEqualToString('test("rtl", "border-inline-start: 10px solid red", "border-right-color")', 'rgb(255, 0, 0)'); +shouldBeEqualToString('test("rtl", "border-inline-start: 10px solid red", "border-right-style")', 'solid'); +shouldBeEqualToString('test("rtl", "border-inline-start: 10px solid red", "border-right-width")', '10px'); -shouldBeEqualToString('test("ltr", "-webkit-border-end: 10px solid red", "border-right-color")', 'rgb(255, 0, 0)'); -shouldBeEqualToString('test("ltr", "-webkit-border-end: 10px solid red", "border-right-style")', 'solid'); -shouldBeEqualToString('test("ltr", "-webkit-border-end: 10px solid red", "border-right-width")', '10px'); +shouldBeEqualToString('test("ltr", "border-inline-end: 10px solid red", "border-right-color")', 'rgb(255, 0, 0)'); +shouldBeEqualToString('test("ltr", "border-inline-end: 10px solid red", "border-right-style")', 'solid'); +shouldBeEqualToString('test("ltr", "border-inline-end: 10px solid red", "border-right-width")', '10px'); -shouldBeEqualToString('test("rtl", "-webkit-border-end: 10px solid red", "border-left-color")', 'rgb(255, 0, 0)'); -shouldBeEqualToString('test("rtl", "-webkit-border-end: 10px solid red", "border-left-style")', 'solid'); -shouldBeEqualToString('test("rtl", "-webkit-border-end: 10px solid red", "border-left-width")', '10px'); +shouldBeEqualToString('test("rtl", "border-inline-end: 10px solid red", "border-left-color")', 'rgb(255, 0, 0)'); +shouldBeEqualToString('test("rtl", "border-inline-end: 10px solid red", "border-left-style")', 'solid'); +shouldBeEqualToString('test("rtl", "border-inline-end: 10px solid red", "border-left-width")', '10px');
diff --git a/third_party/WebKit/LayoutTests/fast/css/script-tests/margin-start-end.js b/third_party/WebKit/LayoutTests/fast/css/script-tests/margin-start-end.js index 970f1ef..df26c3c 100644 --- a/third_party/WebKit/LayoutTests/fast/css/script-tests/margin-start-end.js +++ b/third_party/WebKit/LayoutTests/fast/css/script-tests/margin-start-end.js
@@ -17,16 +17,16 @@ return result; } -shouldBeEqualToString('test("ltr", "-webkit-margin-start", "10px", "width")', '90px'); -shouldBeEqualToString('test("ltr", "-webkit-margin-end", "20px", "width")', '80px'); -shouldBeEqualToString('test("ltr", "-webkit-margin-start", "10px", "margin-left")', '10px'); -shouldBeEqualToString('test("ltr", "-webkit-margin-end", "20px", "margin-right")', '20px'); -shouldBeEqualToString('test("ltr", "margin-left", "10px", "-webkit-margin-start")', '10px'); -shouldBeEqualToString('test("ltr", "margin-right", "20px", "-webkit-margin-end")', '20px'); +shouldBeEqualToString('test("ltr", "margin-inline-start", "10px", "width")', '90px'); +shouldBeEqualToString('test("ltr", "margin-inline-end", "20px", "width")', '80px'); +shouldBeEqualToString('test("ltr", "margin-inline-start", "10px", "margin-left")', '10px'); +shouldBeEqualToString('test("ltr", "margin-inline-end", "20px", "margin-right")', '20px'); +shouldBeEqualToString('test("ltr", "margin-left", "10px", "margin-inline-start")', '10px'); +shouldBeEqualToString('test("ltr", "margin-right", "20px", "margin-inline-end")', '20px'); -shouldBeEqualToString('test("rtl", "-webkit-margin-start", "10px", "width")', '90px'); -shouldBeEqualToString('test("rtl", "-webkit-margin-end", "20px", "width")', '80px'); -shouldBeEqualToString('test("rtl", "-webkit-margin-start", "10px", "margin-right")', '10px'); -shouldBeEqualToString('test("rtl", "-webkit-margin-end", "20px", "margin-left")', '20px'); -shouldBeEqualToString('test("rtl", "margin-right", "10px", "-webkit-margin-start")', '10px'); -shouldBeEqualToString('test("rtl", "margin-left", "20px", "-webkit-margin-end")', '20px'); +shouldBeEqualToString('test("rtl", "margin-inline-start", "10px", "width")', '90px'); +shouldBeEqualToString('test("rtl", "margin-inline-end", "20px", "width")', '80px'); +shouldBeEqualToString('test("rtl", "margin-inline-start", "10px", "margin-right")', '10px'); +shouldBeEqualToString('test("rtl", "margin-inline-end", "20px", "margin-left")', '20px'); +shouldBeEqualToString('test("rtl", "margin-right", "10px", "margin-inline-start")', '10px'); +shouldBeEqualToString('test("rtl", "margin-left", "20px", "margin-inline-end")', '20px');
diff --git a/third_party/WebKit/LayoutTests/fast/css/script-tests/padding-start-end.js b/third_party/WebKit/LayoutTests/fast/css/script-tests/padding-start-end.js index 91c07b3..0e2bd0e4 100644 --- a/third_party/WebKit/LayoutTests/fast/css/script-tests/padding-start-end.js +++ b/third_party/WebKit/LayoutTests/fast/css/script-tests/padding-start-end.js
@@ -24,16 +24,16 @@ return result; } -shouldBe('testWidth("ltr", "-webkit-padding-start", "10px")', '110'); -shouldBe('testWidth("ltr", "-webkit-padding-end", "20px")', '120'); -shouldBeEqualToString('test("ltr", "-webkit-padding-start", "10px", "padding-left")', '10px'); -shouldBeEqualToString('test("ltr", "-webkit-padding-end", "20px", "padding-right")', '20px'); -shouldBeEqualToString('test("ltr", "padding-left", "10px", "-webkit-padding-start")', '10px'); -shouldBeEqualToString('test("ltr", "padding-right", "20px", "-webkit-padding-end")', '20px'); +shouldBe('testWidth("ltr", "padding-inline-start", "10px")', '110'); +shouldBe('testWidth("ltr", "padding-inline-end", "20px")', '120'); +shouldBeEqualToString('test("ltr", "padding-inline-start", "10px", "padding-left")', '10px'); +shouldBeEqualToString('test("ltr", "padding-inline-end", "20px", "padding-right")', '20px'); +shouldBeEqualToString('test("ltr", "padding-left", "10px", "padding-inline-start")', '10px'); +shouldBeEqualToString('test("ltr", "padding-right", "20px", "padding-inline-end")', '20px'); -shouldBe('testWidth("rtl", "-webkit-padding-start", "10px")', '110'); -shouldBe('testWidth("rtl", "-webkit-padding-end", "20px")', '120'); -shouldBeEqualToString('test("rtl", "-webkit-padding-start", "10px", "padding-right")', '10px'); -shouldBeEqualToString('test("rtl", "-webkit-padding-end", "20px", "padding-left")', '20px'); -shouldBeEqualToString('test("rtl", "padding-right", "10px", "-webkit-padding-start")', '10px'); -shouldBeEqualToString('test("rtl", "padding-left", "20px", "-webkit-padding-end")', '20px'); +shouldBe('testWidth("rtl", "padding-inline-start", "10px")', '110'); +shouldBe('testWidth("rtl", "padding-inline-end", "20px")', '120'); +shouldBeEqualToString('test("rtl", "padding-inline-start", "10px", "padding-right")', '10px'); +shouldBeEqualToString('test("rtl", "padding-inline-end", "20px", "padding-left")', '20px'); +shouldBeEqualToString('test("rtl", "padding-right", "10px", "padding-inline-start")', '10px'); +shouldBeEqualToString('test("rtl", "padding-left", "20px", "padding-inline-end")', '20px');
diff --git a/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-1.html b/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-1.html index 94fcfd38..70eaf2e 100644 --- a/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-1.html +++ b/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-1.html
@@ -22,21 +22,21 @@ <p>This test the style is not copied from the wrong source when the direction is defined.</p> <!-- The inline style strings must be strictly equal. Each tested div must also match the exact same set of rules. --> <div class="ltr"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> <div class="rtl"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> <div class="default"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-2.html b/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-2.html index fa774d49..6d7db5d 100644 --- a/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-2.html +++ b/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-2.html
@@ -22,21 +22,21 @@ <p>This test the style is not copied from the wrong source when the direction is defined.</p> <!-- The inline style strings must be strictly equal. Each tested div must also match the exact same set of rules. --> <div class="rtl"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> <div class="ltr"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> <div class="default"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-3.html b/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-3.html index 121316e..3a0dd3ed 100644 --- a/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-3.html +++ b/third_party/WebKit/LayoutTests/fast/css/style-resolver-cache-direction-3.html
@@ -22,21 +22,21 @@ <p>This test the style is not copied from the wrong source when the direction is defined.</p> <!-- The inline style strings must be strictly equal. Each tested div must also match the exact same set of rules. --> <div class="default"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> <div class="ltr"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> <div class="rtl"> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> <div> - <div style="height: 25px; width: 50px; background-color: red; -webkit-margin-start: 200px; -moz-margin-start: 200px;"></div> + <div style="height: 25px; width: 50px; background-color: red; margin-inline-start: 200px; -moz-margin-start: 200px;"></div> </div> </div> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/css/window-internals-isCSSPropertyUseCounted.html b/third_party/WebKit/LayoutTests/fast/css/window-internals-isCSSPropertyUseCounted.html index 65356b6..a47559cb 100644 --- a/third_party/WebKit/LayoutTests/fast/css/window-internals-isCSSPropertyUseCounted.html +++ b/third_party/WebKit/LayoutTests/fast/css/window-internals-isCSSPropertyUseCounted.html
@@ -11,7 +11,7 @@ opacity: invalid value; border: black solid 5px; border-left: thick dashed lightgreen; - -webkit-border-end-color: pink; + border-inline-end-color: pink; } #target2 { -webkit-align-content: space-between; @@ -28,7 +28,7 @@ assert_true(internals.isCSSPropertyUseCounted(document, "background-color")); assert_true(internals.isCSSPropertyUseCounted(document, "padding-bottom")); assert_true(internals.isCSSPropertyUseCounted(document, "padding-left")); - assert_true(internals.isCSSPropertyUseCounted(document, "-webkit-border-end-color")); + assert_true(internals.isCSSPropertyUseCounted(document, "border-inline-end-color")); }, "Test setting and reading css properties"); test(function() {
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-before-text-node.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-before-text-node.html index 81630fba..4ef84a0 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-before-text-node.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-before-text-node.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testDiv {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testDiv {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-child-node.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-child-node.html index 3b20976..65d5c43 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-child-node.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-child-node.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testDiv {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testDiv {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-text-form-control.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-text-form-control.html index 65586c9..9838e1c 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-text-form-control.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-text-form-control.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testElement {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testElement {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-text.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-text.html index 05729e1..a7e1d2c 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-text.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-change-text.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testDiv {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testDiv {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-children.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-children.html index 9017f02..b66a6ba3 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-children.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-children.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testDiv {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testDiv {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-remove-add-children.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-remove-add-children.html index 757c2d4..5fa80e17 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-remove-add-children.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-remove-add-children.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testDiv {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testDiv {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-text-form-control-child.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-text-form-control-child.html index 5d7f9c8..6a1f22b 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-text-form-control-child.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-text-form-control-child.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testElement {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testElement {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-text-form-control.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-text-form-control.html index 429174e1f..0d08bd8 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-text-form-control.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto-text-form-control.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testElement {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testElement {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto.html index 1c419af..3a3de45 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-auto.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testDiv {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testDiv {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-value-change.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-value-change.html index 10a12b1..8df849a 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-value-change.html +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/attr-dir-value-change.html
@@ -4,7 +4,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../../../resources/js-test.js"></script> <style> -.testDiv {-webkit-border-start: 5px solid green; -webkit-border-end: 5px solid red; } +.testDiv {border-inline-start: 5px solid green; border-inline-end: 5px solid red; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/attr-dir-inherit.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/attr-dir-inherit.html index 608067b..477d17a 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/attr-dir-inherit.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/attr-dir-inherit.html
@@ -115,8 +115,8 @@ }, "dir=auto the first character in the distributed content with multiple levels of shadow roots"); function assert_direction(description, elementToTest) { - elementToTest.style.webkitBorderStart = "5px solid green"; - elementToTest.style.webkitBorderEnd = "5px solid red"; + elementToTest.style.borderInlineStart = "5px solid green"; + elementToTest.style.borderInlineEnd = "5px solid red"; var actualColor = document.defaultView.getComputedStyle(elementToTest).getPropertyValue("border-right-color"); var dirExpected = elementToTest.dataset.dirExpected; switch (dirExpected) {
diff --git a/third_party/WebKit/LayoutTests/fast/dynamic/crash-paint-no-documentElement-renderer-expected.txt b/third_party/WebKit/LayoutTests/fast/dynamic/crash-paint-no-documentElement-renderer-expected.txt index ff24d7c..24ab3b4 100644 --- a/third_party/WebKit/LayoutTests/fast/dynamic/crash-paint-no-documentElement-renderer-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dynamic/crash-paint-no-documentElement-renderer-expected.txt
@@ -1 +1 @@ -*{-webkit-border-before-style:groove} +*{border-block-start-style:groove}
diff --git a/third_party/WebKit/LayoutTests/fast/dynamic/crash-paint-no-documentElement-renderer.html-disabled b/third_party/WebKit/LayoutTests/fast/dynamic/crash-paint-no-documentElement-renderer.html-disabled index 080e4c4..37c8660 100644 --- a/third_party/WebKit/LayoutTests/fast/dynamic/crash-paint-no-documentElement-renderer.html-disabled +++ b/third_party/WebKit/LayoutTests/fast/dynamic/crash-paint-no-documentElement-renderer.html-disabled
@@ -11,7 +11,7 @@ document.open(); var oUElement = document.createElement("U"); oUElement.hidden=true; - oUElement.innerHTML="<style>*{-webkit-border-before-style:groove}"; + oUElement.innerHTML="<style>*{border-block-start-style:groove}"; document.appendChild(oUElement); document.close(); }
diff --git a/third_party/WebKit/LayoutTests/fast/html/layout-runs-and-floats-crash.html b/third_party/WebKit/LayoutTests/fast/html/layout-runs-and-floats-crash.html index 9d35e5a..6ab355e 100644 --- a/third_party/WebKit/LayoutTests/fast/html/layout-runs-and-floats-crash.html +++ b/third_party/WebKit/LayoutTests/fast/html/layout-runs-and-floats-crash.html
@@ -1,7 +1,7 @@ <style> * { -webkit-columns: 10ex; - -webkit-margin-after: 60; + margin-block-end: 60; } </style> <main></main>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height.html b/third_party/WebKit/LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height.html index aaec74f5a..49b6f63 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height.html
@@ -6,8 +6,8 @@ columns: 2; column-gap: 0; column-fill: auto; - -webkit-logical-width: 400px; - -webkit-logical-height: 80px; + inline-size: 400px; + block-size: 80px; font: 20px Ahem; line-height: 2; ">Lorem ipsum dolor sit amet</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-lr-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-lr-expected.html index 3c360e6..b9253cc 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-lr-expected.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-lr-expected.html
@@ -7,9 +7,9 @@ <p>The word PASS should be seen below.</p> <div style="position:relative; width:30em; background:black;"> <div style="width:20em; height:20em; -webkit-writing-mode:vertical-lr;"> - <div style="-webkit-logical-height:6em; line-height:2em; background:cyan;"> + <div style="block-size:6em; line-height:2em; background:cyan;"> <br> - <span style="-webkit-margin-start:5em;"> PASS</span> + <span style="margin-inline-start:5em;"> PASS</span> </div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-lr.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-lr.html index 62cf792..dc0c86e 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-lr.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-lr.html
@@ -22,7 +22,7 @@ <div style="position:relative; width:30em; background:black;"> <div id="hider" style="position:absolute; z-index:1; top:5.1em; left:2em; width:3em; height:3em; background:red;"></div> <div style="width:20em; height:20em; -webkit-writing-mode:vertical-lr;"> - <div style="-webkit-columns:4; -webkit-column-gap:0; columns:4; column-fill:auto; column-gap:0; orphans:1; widows:1; -webkit-logical-height:6em; line-height:2em; background:cyan;"> + <div style="-webkit-columns:4; -webkit-column-gap:0; columns:4; column-fill:auto; column-gap:0; orphans:1; widows:1; block-size:6em; line-height:2em; background:cyan;"> <br> <br> <br>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-rl-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-rl-expected.html index 4f86922..76e7190 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-rl-expected.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-rl-expected.html
@@ -7,9 +7,9 @@ <p>The word PASS should be seen below.</p> <div style="position:relative; width:30em; background:black;"> <div style="width:20em; height:20em; -webkit-writing-mode:vertical-rl;"> - <div style="-webkit-logical-height:6em; line-height:2em; background:cyan;"> + <div style="block-size:6em; line-height:2em; background:cyan;"> <br> - <span style="-webkit-margin-start:5em;"> PASS</span> + <span style="margin-inline-start:5em;"> PASS</span> </div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-rl.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-rl.html index f1b96d8..950c20af 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-rl.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/hide-box-vertical-rl.html
@@ -22,7 +22,7 @@ <div style="position:relative; width:30em; background:black;"> <div id="hider" style="position:absolute; z-index:1; top:5.1em; right:12em; width:3em; height:3em; background:red;"></div> <div style="width:20em; height:20em; -webkit-writing-mode:vertical-rl;"> - <div style="-webkit-columns:4; -webkit-column-gap:0; columns:4; column-fill:auto; column-gap:0; orphans:1; widows:1; -webkit-logical-height:6em; line-height:2em; background:cyan;"> + <div style="-webkit-columns:4; -webkit-column-gap:0; columns:4; column-fill:auto; column-gap:0; orphans:1; widows:1; block-size:6em; line-height:2em; background:cyan;"> <br> <br> <br>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/overflow-content-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/overflow-content-expected.html index 1fb1979e..11ce40d 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/overflow-content-expected.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/overflow-content-expected.html
@@ -1,8 +1,8 @@ <style> div.test { - -webkit-logical-width: 100px; - -webkit-border-before: 5px solid; - -webkit-border-after: 15px solid; + inline-size: 100px; + border-block-start: 5px solid; + border-block-end: 15px solid; -webkit-column-count: 2; -webkit-column-gap: 0; column-count: 2; @@ -11,17 +11,17 @@ background-color: lightblue; } div.container { - -webkit-logical-height: 120px; + block-size: 120px; background-color: red; - -webkit-logical-width: 100px; - -webkit-margin-after: 8px; + inline-size: 100px; + margin-block-end: 8px; } </style> <div> <div class="container"> - <div class="test" style="-webkit-logical-height: 100px;"> + <div class="test" style="block-size: 100px;"> <div> - <div style="-webkit-logical-height: 300px; background-color: yellow;"></div> + <div style="block-size: 300px; background-color: yellow;"></div> </div> </div> </div> @@ -29,16 +29,16 @@ <div class="container"> <div class="test"> <div> - <div style="-webkit-logical-height: 200px; background-color: yellow;"></div> + <div style="block-size: 200px; background-color: yellow;"></div> </div> </div> </div> <div class="container"> <div class="test"> - <div style="-webkit-logical-height: 10px;"></div> + <div style="block-size: 10px;"></div> <div style="-webkit-column-break-before: always;"> - <div style="-webkit-logical-height: 100px; background-color: yellow;"></div> + <div style="block-size: 100px; background-color: yellow;"></div> </div> <div></div> </div> @@ -46,9 +46,9 @@ </div> <div style="-webkit-writing-mode: vertical-rl;"> <div class="container"> - <div class="test" style="-webkit-logical-height: 100px;"> + <div class="test" style="block-size: 100px;"> <div> - <div style="-webkit-logical-height: 300px; background-color: yellow;"></div> + <div style="block-size: 300px; background-color: yellow;"></div> </div> </div> </div> @@ -56,16 +56,16 @@ <div class="container"> <div class="test"> <div> - <div style="-webkit-logical-height: 200px; background-color: yellow;"></div> + <div style="block-size: 200px; background-color: yellow;"></div> </div> </div> </div> <div class="container"> <div class="test"> - <div style="-webkit-logical-height: 10px;"></div> + <div style="block-size: 10px;"></div> <div style="-webkit-column-break-before: always;"> - <div style="-webkit-logical-height: 100px; background-color: yellow;"></div> + <div style="block-size: 100px; background-color: yellow;"></div> </div> <div></div> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/overflow-content.html b/third_party/WebKit/LayoutTests/fast/multicol/overflow-content.html index fc5de7b..65d090d 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/overflow-content.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/overflow-content.html
@@ -1,8 +1,8 @@ <style> div.test { - -webkit-logical-width: 100px; - -webkit-border-before: 5px solid; - -webkit-border-after: 15px solid; + inline-size: 100px; + border-block-start: 5px solid; + border-block-end: 15px solid; -webkit-column-count: 2; -webkit-column-gap: 0; column-count: 2; @@ -11,63 +11,63 @@ background-color: lightblue; } div.container { - -webkit-logical-height: 120px; + block-size: 120px; background-color: red; - -webkit-logical-width: 100px; - -webkit-margin-after: 8px; + inline-size: 100px; + margin-block-end: 8px; } </style> <div> <div class="container"> - <div class="test" style="-webkit-logical-height: 100px;"> - <div style="-webkit-logical-height: 20px;"> - <div style="-webkit-logical-height: 300px; background-color: yellow;"></div> + <div class="test" style="block-size: 100px;"> + <div style="block-size: 20px;"> + <div style="block-size: 300px; background-color: yellow;"></div> </div> </div> </div> <div class="container"> <div class="test"> - <div style="-webkit-logical-height: 20px;"> - <div style="-webkit-logical-height: 200px; background-color: yellow;"></div> + <div style="block-size: 20px;"> + <div style="block-size: 200px; background-color: yellow;"></div> </div> </div> </div> <div class="container"> <div class="test"> - <div style="-webkit-logical-height: 10px;"></div> - <div style="-webkit-column-break-before: always; -webkit-logical-height: 10px;"> - <div style="-webkit-logical-height: 100px; background-color: yellow;"></div> + <div style="block-size: 10px;"></div> + <div style="-webkit-column-break-before: always; block-size: 10px;"> + <div style="block-size: 100px; background-color: yellow;"></div> </div> - <div style="-webkit-logical-height: 20px;"></div> + <div style="block-size: 20px;"></div> </div> </div> </div> <div style="-webkit-writing-mode: vertical-rl;"> <div class="container"> - <div class="test" style="-webkit-logical-height: 100px;"> - <div style="-webkit-logical-height: 20px;"> - <div style="-webkit-logical-height: 300px; background-color: yellow;"></div> + <div class="test" style="block-size: 100px;"> + <div style="block-size: 20px;"> + <div style="block-size: 300px; background-color: yellow;"></div> </div> </div> </div> <div class="container"> <div class="test"> - <div style="-webkit-logical-height: 20px;"> - <div style="-webkit-logical-height: 200px; background-color: yellow;"></div> + <div style="block-size: 20px;"> + <div style="block-size: 200px; background-color: yellow;"></div> </div> </div> </div> <div class="container"> <div class="test"> - <div style="-webkit-logical-height: 10px;"></div> - <div style="-webkit-column-break-before: always; -webkit-logical-height: 10px;"> - <div style="-webkit-logical-height: 100px; background-color: yellow;"></div> + <div style="block-size: 10px;"></div> + <div style="-webkit-column-break-before: always; block-size: 10px;"> + <div style="block-size: 100px; background-color: yellow;"></div> </div> - <div style="-webkit-logical-height: 20px;"></div> + <div style="block-size: 20px;"></div> </div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/pageLogicalOffset-vertical.html b/third_party/WebKit/LayoutTests/fast/multicol/pageLogicalOffset-vertical.html index c3fe08b..2c53bfbb3 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/pageLogicalOffset-vertical.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/pageLogicalOffset-vertical.html
@@ -12,7 +12,7 @@ } .margin-before { - -webkit-margin-before: 30px; + margin-block-start: 30px; width: 60px; }
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/vertical-lr/float-truncation.html b/third_party/WebKit/LayoutTests/fast/multicol/vertical-lr/float-truncation.html index 6e96866..20f1643 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/vertical-lr/float-truncation.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/vertical-lr/float-truncation.html
@@ -19,7 +19,7 @@ div.float { float: left; height: 51px; - -webkit-margin-before: 5px; + margin-block-start: 5px; color: silver; } </style>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/vertical-lr/rules-with-border-before.html b/third_party/WebKit/LayoutTests/fast/multicol/vertical-lr/rules-with-border-before.html index 9a364acf..9421a96 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/vertical-lr/rules-with-border-before.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/vertical-lr/rules-with-border-before.html
@@ -9,8 +9,8 @@ -webkit-column-gap: 50px; } - .before { -webkit-border-before: 50px solid blue; } - .after { -webkit-border-after: 50px solid blue; } + .before { border-block-start: 50px solid blue; } + .after { border-block-end: 50px solid blue; } .test div { width: 200px; } </style>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/vertical-rl/float-truncation.html b/third_party/WebKit/LayoutTests/fast/multicol/vertical-rl/float-truncation.html index 4ac1f46..f82e8759 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/vertical-rl/float-truncation.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/vertical-rl/float-truncation.html
@@ -20,7 +20,7 @@ div.float { float: left; height: 51px; - -webkit-margin-before: 5px; + margin-block-start: 5px; color: silver; } </style>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/vertical-rl/rules-with-border-before.html b/third_party/WebKit/LayoutTests/fast/multicol/vertical-rl/rules-with-border-before.html index e5b536d..900714f 100644 --- a/third_party/WebKit/LayoutTests/fast/multicol/vertical-rl/rules-with-border-before.html +++ b/third_party/WebKit/LayoutTests/fast/multicol/vertical-rl/rules-with-border-before.html
@@ -9,8 +9,8 @@ -webkit-column-gap: 50px; } - .before { -webkit-border-before: 50px solid blue; } - .after { -webkit-border-after: 50px solid blue; } + .before { border-block-start: 50px solid blue; } + .after { border-block-end: 50px solid blue; } .test div { width: 200px; } </style>
diff --git a/third_party/WebKit/LayoutTests/fast/ruby/position-after.html b/third_party/WebKit/LayoutTests/fast/ruby/position-after.html index 5b32ff0..df6e570f 100644 --- a/third_party/WebKit/LayoutTests/fast/ruby/position-after.html +++ b/third_party/WebKit/LayoutTests/fast/ruby/position-after.html
@@ -1,7 +1,7 @@ <script src="../../resources/ahem.js"></script> <style> div.container { - -webkit-logical-width: 8em; + inline-size: 8em; font: 20px Ahem; -webkit-font-smoothing: none; outline: thin dashed lightblue;
diff --git a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/001-vertical.html b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/001-vertical.html index 2f655b0..e094f83 100644 --- a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/001-vertical.html +++ b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/001-vertical.html
@@ -10,6 +10,6 @@ </div> -<div style="border:1px solid green; -webkit-margin-before:10em;"> +<div style="border:1px solid green; margin-block-start:10em;"> <table style="border-collapse:collapse;"><tr><td style="border:2px solid black">Test</td></tr></table> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/border-collapsing-head-foot-vertical.html b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/border-collapsing-head-foot-vertical.html index a14d63a5..fb2454c1 100644 --- a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/border-collapsing-head-foot-vertical.html +++ b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/border-collapsing-head-foot-vertical.html
@@ -7,12 +7,12 @@ .test table { border-collapse: collapse; margin: 10px; } .test td, th { border: 1px lightgray solid; } - .example1 tfoot { -webkit-border-before: 2px solid blue; - -webkit-border-after: 2px solid green; + .example1 tfoot { border-block-start: 2px solid blue; + border-block-end: 2px solid green; } - .example2 thead { -webkit-border-before: 2px solid blue; - -webkit-border-after: 2px solid green; + .example2 thead { border-block-start: 2px solid blue; + border-block-end: 2px solid green; } table table { -webkit-writing-mode: vertical-rl; }
diff --git a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/equal-precedence-resolution-vertical.html b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/equal-precedence-resolution-vertical.html index a3ba34d..32963794 100644 --- a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/equal-precedence-resolution-vertical.html +++ b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/equal-precedence-resolution-vertical.html
@@ -5,50 +5,50 @@ </style> <div style="-webkit-writing-mode: vertical-rl; height: 200px; border: solid;"> <table> - <colgroup span="2"><colgroup span="1" style="-webkit-border-end: 5px solid rgba(0, 127, 0, 0.5);"><colgroup span="1" style="-webkit-border-start: 5px solid red"> + <colgroup span="2"><colgroup span="1" style="border-inline-end: 5px solid rgba(0, 127, 0, 0.5);"><colgroup span="1" style="border-inline-start: 5px solid red"> <tr> - <td style="-webkit-border-end: 5px solid rgba(0, 127, 0, 0.5); -webkit-border-after: 5px solid rgba(0, 127, 0, 0.5);"></td> - <td style="-webkit-border-start: 5px solid red;"></td> + <td style="border-inline-end: 5px solid rgba(0, 127, 0, 0.5); border-block-end: 5px solid rgba(0, 127, 0, 0.5);"></td> + <td style="border-inline-start: 5px solid red;"></td> <td></td> <td></td> </tr> <tr> - <td style="-webkit-border-before: 5px solid red;"></td> + <td style="border-block-start: 5px solid red;"></td> <td></td> <td></td> <td></td> </tr> </table> <table style="direction: rtl;"> - <colgroup span="2"><colgroup span="1" style="-webkit-border-end: 5px solid rgba(0, 127, 0, 0.5);"><colgroup span="1" style="-webkit-border-start: 5px solid red"> + <colgroup span="2"><colgroup span="1" style="border-inline-end: 5px solid rgba(0, 127, 0, 0.5);"><colgroup span="1" style="border-inline-start: 5px solid red"> <tr> - <td style="-webkit-border-end: 5px solid rgba(0, 127, 0, 0.5); -webkit-border-after: 5px solid rgba(0, 127, 0, 0.5);"></td> - <td style="-webkit-border-start: 5px solid red;"></td> + <td style="border-inline-end: 5px solid rgba(0, 127, 0, 0.5); border-block-end: 5px solid rgba(0, 127, 0, 0.5);"></td> + <td style="border-inline-start: 5px solid red;"></td> <td></td> <td></td> </tr> <tr> - <td style="-webkit-border-before: 5px solid red;"></td> + <td style="border-block-start: 5px solid red;"></td> <td></td> <td></td> <td></td> </tr> </table> <table> - <tr style="-webkit-border-after: 5px solid rgba(0, 127, 0, 0.5);"> + <tr style="border-block-end: 5px solid rgba(0, 127, 0, 0.5);"> <td></td> </tr> - <tr style="-webkit-border-before: 5px solid red;"> + <tr style="border-block-start: 5px solid red;"> <td></td> </tr> </table> <table> - <tbody style="-webkit-border-after: 5px solid rgba(0, 127, 0, 0.5);"> + <tbody style="border-block-end: 5px solid rgba(0, 127, 0, 0.5);"> <tr> <td></td> </tr> </tbody> - <tbody style="-webkit-border-before: 5px solid red;"> + <tbody style="border-block-start: 5px solid red;"> <tr> <td></td> </tr> @@ -57,50 +57,50 @@ </div> <div style="-webkit-writing-mode: vertical-lr; height: 200px; border: solid;"> <table> - <colgroup span="2"><colgroup span="1" style="-webkit-border-end: 5px solid rgba(0, 127, 0, 0.5);"><colgroup span="1" style="-webkit-border-start: 5px solid red"> + <colgroup span="2"><colgroup span="1" style="border-inline-end: 5px solid rgba(0, 127, 0, 0.5);"><colgroup span="1" style="border-inline-start: 5px solid red"> <tr> - <td style="-webkit-border-end: 5px solid rgba(0, 127, 0, 0.5); -webkit-border-after: 5px solid rgba(0, 127, 0, 0.5);"></td> - <td style="-webkit-border-start: 5px solid red;"></td> + <td style="border-inline-end: 5px solid rgba(0, 127, 0, 0.5); border-block-end: 5px solid rgba(0, 127, 0, 0.5);"></td> + <td style="border-inline-start: 5px solid red;"></td> <td></td> <td></td> </tr> <tr> - <td style="-webkit-border-before: 5px solid red;"></td> + <td style="border-block-start: 5px solid red;"></td> <td></td> <td></td> <td></td> </tr> </table> <table style="direction: rtl;"> - <colgroup span="2"><colgroup span="1" style="-webkit-border-end: 5px solid rgba(0, 127, 0, 0.5);"><colgroup span="1" style="-webkit-border-start: 5px solid red"> + <colgroup span="2"><colgroup span="1" style="border-inline-end: 5px solid rgba(0, 127, 0, 0.5);"><colgroup span="1" style="border-inline-start: 5px solid red"> <tr> - <td style="-webkit-border-end: 5px solid rgba(0, 127, 0, 0.5); -webkit-border-after: 5px solid rgba(0, 127, 0, 0.5);"></td> - <td style="-webkit-border-start: 5px solid red;"></td> + <td style="border-inline-end: 5px solid rgba(0, 127, 0, 0.5); border-block-end: 5px solid rgba(0, 127, 0, 0.5);"></td> + <td style="border-inline-start: 5px solid red;"></td> <td></td> <td></td> </tr> <tr> - <td style="-webkit-border-before: 5px solid red;"></td> + <td style="border-block-start: 5px solid red;"></td> <td></td> <td></td> <td></td> </tr> </table> <table> - <tr style="-webkit-border-after: 5px solid rgba(0, 127, 0, 0.5);"> + <tr style="border-block-end: 5px solid rgba(0, 127, 0, 0.5);"> <td></td> </tr> - <tr style="-webkit-border-before: 5px solid red;"> + <tr style="border-block-start: 5px solid red;"> <td></td> </tr> </table> <table> - <tbody style="-webkit-border-after: 5px solid rgba(0, 127, 0, 0.5);"> + <tbody style="border-block-end: 5px solid rgba(0, 127, 0, 0.5);"> <tr> <td></td> </tr> </tbody> - <tbody style="-webkit-border-before: 5px solid red;"> + <tbody style="border-block-start: 5px solid red;"> <tr> <td></td> </tr>
diff --git a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/rtl-border-collapsing-vertical.html b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/rtl-border-collapsing-vertical.html index 101790f..819235fa 100644 --- a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/rtl-border-collapsing-vertical.html +++ b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/rtl-border-collapsing-vertical.html
@@ -9,15 +9,15 @@ <hr> <table cellpadding="4" cellspacing="0" style="text-align: center; -webkit-writing-mode: vertical-rl;"> <tr> -<td style="-webkit-border-end: 1px solid black;">RTL</td> +<td style="border-inline-end: 1px solid black;">RTL</td> <td>LTR</td> </tr> <tr> -<td style="-webkit-border-end: 1px solid black;"> - <table style="direction:rtl; border-collapse: collapse; -webkit-border-start: 2px solid red; -webkit-border-end: 2px solid blue;"> +<td style="border-inline-end: 1px solid black;"> + <table style="direction:rtl; border-collapse: collapse; border-inline-start: 2px solid red; border-inline-end: 2px solid blue;"> <col> <col> - <col style="background: yellow; -webkit-border-end: 2px green dotted; -webkit-border-start: solid 1px;"> + <col style="background: yellow; border-inline-end: 2px green dotted; border-inline-start: solid 1px;"> <col style="background: silver;"> <tr> <td> </td> @@ -26,7 +26,7 @@ <td> </td> </tr> <tr> - <td style="-webkit-border-end: 4px solid maroon;"> </td> + <td style="border-inline-end: 4px solid maroon;"> </td> <td> </td> <td> </td> <td> </td> @@ -35,10 +35,10 @@ </table> </td> <td> - <table style="direction:ltr; border-collapse: collapse; -webkit-border-start: 2px solid red; -webkit-border-end: 2px solid blue;"> + <table style="direction:ltr; border-collapse: collapse; border-inline-start: 2px solid red; border-inline-end: 2px solid blue;"> <col> <col> - <col style="background: yellow; -webkit-border-end: 2px green dotted; -webkit-border-start: solid 1px;"> + <col style="background: yellow; border-inline-end: 2px green dotted; border-inline-start: solid 1px;"> <col style="background: silver;"> <tr> <td> </td> @@ -47,7 +47,7 @@ <td> </td> </tr> <tr> - <td style="-webkit-border-end: 4px solid maroon;"> </td> + <td style="border-inline-end: 4px solid maroon;"> </td> <td> </td> <td> </td> <td> </td>
diff --git a/third_party/WebKit/LayoutTests/fast/table/fixed-with-auto-with-colspan-vertical.html b/third_party/WebKit/LayoutTests/fast/table/fixed-with-auto-with-colspan-vertical.html index be67a15..d4ee2746 100644 --- a/third_party/WebKit/LayoutTests/fast/table/fixed-with-auto-with-colspan-vertical.html +++ b/third_party/WebKit/LayoutTests/fast/table/fixed-with-auto-with-colspan-vertical.html
@@ -1,5 +1,5 @@ <style> - table { border-spacing: 5px 0; table-layout: fixed; height: 445px; -webkit-margin-before: 5px; } + table { border-spacing: 5px 0; table-layout: fixed; height: 445px; margin-block-start: 5px; } td { width: 50px; } #ref td { background-color: red; } #test td { background-color: green; }
diff --git a/third_party/WebKit/LayoutTests/fast/text/decorations-with-text-combine.html b/third_party/WebKit/LayoutTests/fast/text/decorations-with-text-combine.html index 0dc1e6dce..732033a 100644 --- a/third_party/WebKit/LayoutTests/fast/text/decorations-with-text-combine.html +++ b/third_party/WebKit/LayoutTests/fast/text/decorations-with-text-combine.html
@@ -7,7 +7,7 @@ } div { - -webkit-margin-after: 10px; + margin-block-end: 10px; } .combine {
diff --git a/third_party/WebKit/LayoutTests/fast/text/dirty-inline-textbox-crash.html b/third_party/WebKit/LayoutTests/fast/text/dirty-inline-textbox-crash.html index 6a861a9..0ea9cfe 100644 --- a/third_party/WebKit/LayoutTests/fast/text/dirty-inline-textbox-crash.html +++ b/third_party/WebKit/LayoutTests/fast/text/dirty-inline-textbox-crash.html
@@ -4,7 +4,7 @@ .box { display: run-in; - -webkit-padding-start: 10000; + padding-inline-start: 10000; } </style> </head>
diff --git a/third_party/WebKit/LayoutTests/fast/text/justify-vertical-expected.html b/third_party/WebKit/LayoutTests/fast/text/justify-vertical-expected.html index b87fa976..a8c8f710 100644 --- a/third_party/WebKit/LayoutTests/fast/text/justify-vertical-expected.html +++ b/third_party/WebKit/LayoutTests/fast/text/justify-vertical-expected.html
@@ -16,20 +16,20 @@ </style> <dl> <dt>Ideographic, Kana, CJK symbols</dt> -<dd style="-webkit-logical-width:9em;">国 国 あ ! 国<br>国WWWWWWWW</dd> -<dd style="-webkit-logical-width:9em;">国 国 あ ! 国<br>WWWWWWWWW</dd> -<dd style="-webkit-logical-width:9em;">国 国 あ ! 国<br>WWWWWWWWW</dd> -<dd style="-webkit-logical-width:9em;">国 国 あ ! W<br>WWWWWWWWW</dd> -<dd style="-webkit-logical-width:9em;">𠮟 𠮟 𠮟 𠮟 𠮟<br>𠮟WWWWWWWW</dd> +<dd style="inline-size:9em;">国 国 あ ! 国<br>国WWWWWWWW</dd> +<dd style="inline-size:9em;">国 国 あ ! 国<br>WWWWWWWWW</dd> +<dd style="inline-size:9em;">国 国 あ ! 国<br>WWWWWWWWW</dd> +<dd style="inline-size:9em;">国 国 あ ! W<br>WWWWWWWWW</dd> +<dd style="inline-size:9em;">𠮟 𠮟 𠮟 𠮟 𠮟<br>𠮟WWWWWWWW</dd> <dt>Ideographic, Kana, CJK symbols with spans</dt> -<dd style="-webkit-logical-width:9em;">国 国 あ ! 国<br>国WWWWWWWW</dd> +<dd style="inline-size:9em;">国 国 あ ! 国<br>国WWWWWWWW</dd> <dt>Ideographic, Latin, and spaces</dt> -<dd style="-webkit-logical-width:8em;">WW 国 W 国<br>国WWWWWWW</dd> -<dd style="-webkit-logical-width:11em;">WW 国 W 国<br>国WWWWWWWWWW</dd> -<dd style="-webkit-logical-width:11em;">WW 国 W 国<br>WWWWWWWWWWW</dd> -<dd style="-webkit-logical-width:11em;">WW 国 W 国<br>WWWWWWWWWWW</dd> -<dd style="-webkit-logical-width:8em;">WW 国 W<br>国WWWWWWW</dd> -<dd style="-webkit-logical-width:11em;">W. W. W 国<br>WWWWWWWWWWW</dd> +<dd style="inline-size:8em;">WW 国 W 国<br>国WWWWWWW</dd> +<dd style="inline-size:11em;">WW 国 W 国<br>国WWWWWWWWWW</dd> +<dd style="inline-size:11em;">WW 国 W 国<br>WWWWWWWWWWW</dd> +<dd style="inline-size:11em;">WW 国 W 国<br>WWWWWWWWWWW</dd> +<dd style="inline-size:8em;">WW 国 W<br>国WWWWWWW</dd> +<dd style="inline-size:11em;">W. W. W 国<br>WWWWWWWWWWW</dd> </dl> <script> if (window.testRunner) {
diff --git a/third_party/WebKit/LayoutTests/fast/text/justify-vertical.html b/third_party/WebKit/LayoutTests/fast/text/justify-vertical.html index e229385..15e7380a 100644 --- a/third_party/WebKit/LayoutTests/fast/text/justify-vertical.html +++ b/third_party/WebKit/LayoutTests/fast/text/justify-vertical.html
@@ -16,24 +16,24 @@ </style> <dl> <dt>Ideographic, Kana, CJK symbols</dt> -<dd style="-webkit-logical-width:9em;">国国あ!国国WWWWWWWW</dd> -<dd style="-webkit-logical-width:9em;">国国あ!国WWWWWWWWW</dd> -<dd style="-webkit-logical-width:9em;">国国あ!国 WWWWWWWWW</dd> -<dd style="-webkit-logical-width:9em;">国国あ!W WWWWWWWWW</dd> -<dd style="-webkit-logical-width:9em;">𠮟𠮟𠮟𠮟𠮟𠮟WWWWWWWW</dd> +<dd style="inline-size:9em;">国国あ!国国WWWWWWWW</dd> +<dd style="inline-size:9em;">国国あ!国WWWWWWWWW</dd> +<dd style="inline-size:9em;">国国あ!国 WWWWWWWWW</dd> +<dd style="inline-size:9em;">国国あ!W WWWWWWWWW</dd> +<dd style="inline-size:9em;">𠮟𠮟𠮟𠮟𠮟𠮟WWWWWWWW</dd> <dt>Ideographic, Kana, CJK symbols with spans</dt> -<dd style="-webkit-logical-width:9em;">国<span>国</span>あ!国国WWWWWWWW</dd> +<dd style="inline-size:9em;">国<span>国</span>あ!国国WWWWWWWW</dd> <dt>Ideographic, Latin, and spaces</dt> -<dd style="-webkit-logical-width:8em;">WW国W国国WWWWWWW</dd> -<dd style="-webkit-logical-width:11em;">WW国 W 国国WWWWWWWWWW</dd> -<dd style="-webkit-logical-width:11em;">WW国 W 国WWWWWWWWWWW</dd> -<dd style="-webkit-logical-width:11em;">WW国 W 国 WWWWWWWWWWW</dd> -<dd style="-webkit-logical-width:8em;">WW国 W 国WWWWWWW</dd> -<dd style="-webkit-logical-width:11em;">W. W. <span>W</span>国WWWWWWWWWWW</dd> +<dd style="inline-size:8em;">WW国W国国WWWWWWW</dd> +<dd style="inline-size:11em;">WW国 W 国国WWWWWWWWWW</dd> +<dd style="inline-size:11em;">WW国 W 国WWWWWWWWWWW</dd> +<dd style="inline-size:11em;">WW国 W 国 WWWWWWWWWWW</dd> +<dd style="inline-size:8em;">WW国 W 国WWWWWWW</dd> +<dd style="inline-size:11em;">W. W. <span>W</span>国WWWWWWWWWWW</dd> <!-- These are not supported yet <dt>Combining and IVS</dt> -<dd style="-webkit-logical-width:5em;">ががががWWWW</dd> -<dd style="-webkit-logical-width:5em;">辺󠄂辺󠄂辺󠄂辺WWWW</dd> +<dd style="inline-size:5em;">ががががWWWW</dd> +<dd style="inline-size:5em;">辺󠄂辺󠄂辺󠄂辺WWWW</dd> --> </dl> <script>
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/Kusa-Makura-background-canvas.html b/third_party/WebKit/LayoutTests/fast/writing-mode/Kusa-Makura-background-canvas.html index 58ffed1..2093b45 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/Kusa-Makura-background-canvas.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/Kusa-Makura-background-canvas.html
@@ -14,7 +14,7 @@ /*body { font-family: HiraMinProN-W3;} to test the font vs fallback. */ #div, h1, h2 { line-height: 150%; } /* this line should make no difference for the line height as the default is 150 for the Japanese fonts. */ -.jisage_2 { -webkit-margin-start: 2em;} +.jisage_2 { margin-inline-start: 2em;} body { margin: 8% 10%;} #ruby { line-height: 100%; } /* hack to keep lines in conssitent positions. Should not be necessary. */ #rt { line-height: 50%; } /* hack to keep lines in conssitent positions. Should not be necessary. */
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/block-level-images.html b/third_party/WebKit/LayoutTests/fast/writing-mode/block-level-images.html index 0722944..5e994ba9 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/block-level-images.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/block-level-images.html
@@ -1,14 +1,14 @@ <!doctype html> <div style="margin:2px; float:left; height:300px;border:2px solid black;-webkit-writing-mode:vertical-lr"> <div style="width:25px;background-color:green"></div> -<img style="display:block;height:50%; -webkit-border-before:2px solid maroon; -webkit-border-after:2px solid maroon; -webkit-border-start: 1px solid purple; -webkit-border-end:5px dashed grey" src="resources/circle.svg"> -<img style="-webkit-margin-start: 40px; display:block;height:50px" src="resources/oval.png"> +<img style="display:block;height:50%; border-block-start:2px solid maroon; border-block-end:2px solid maroon; border-inline-start: 1px solid purple; border-inline-end:5px dashed grey" src="resources/circle.svg"> +<img style="margin-inline-start: 40px; display:block;height:50px" src="resources/oval.png"> <div style="width:25px;background-color:green"></div> </div> <div style="margin:2px; float:left; height:300px;border:2px solid black;-webkit-writing-mode:vertical-lr; direction:rtl"> <div style="width:25px;background-color:green"></div> -<img style="display:block;height:50%; -webkit-border-before:2px solid maroon; -webkit-border-after:2px solid maroon; -webkit-border-start: 1px solid purple; -webkit-border-end:5px dashed grey" src="resources/circle.svg"> -<img style="-webkit-margin-start: 40px; display:block;height:50px" src="resources/oval.png"> +<img style="display:block;height:50%; border-block-start:2px solid maroon; border-block-end:2px solid maroon; border-inline-start: 1px solid purple; border-inline-end:5px dashed grey" src="resources/circle.svg"> +<img style="margin-inline-start: 40px; display:block;height:50px" src="resources/oval.png"> <div style="width:25px;background-color:green"></div> </div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/border-radius-clipping-vertical-lr.html b/third_party/WebKit/LayoutTests/fast/writing-mode/border-radius-clipping-vertical-lr.html index 702bb42..23185bd 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/border-radius-clipping-vertical-lr.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/border-radius-clipping-vertical-lr.html
@@ -1,9 +1,9 @@ <html style="-webkit-writing-mode: vertical-lr"> <body> -<div style="-webkit-logical-width: 600px; -webkit-margin-after:50px"> - <span style="-webkit-padding-start: 15px; -webkit-padding-end:15px; -webkit-padding-before:5px; -webkit-padding-after: 5px; font-size: 48px; background-color:blue"> +<div style="inline-size: 600px; margin-block-end:50px"> + <span style="padding-inline-start: 15px; padding-inline-end:15px; padding-block-start:5px; padding-block-end: 5px; font-size: 48px; background-color:blue"> <span style=" - -webkit-padding-start: 15px; -webkit-padding-end:15px; + padding-inline-start: 15px; padding-inline-end:15px; font-size: 48px; background-color: lightyellow; -webkit-border-radius: 10px;
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/border-styles-vertical-lr.html b/third_party/WebKit/LayoutTests/fast/writing-mode/border-styles-vertical-lr.html index cba3c29e..7c18a76 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/border-styles-vertical-lr.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/border-styles-vertical-lr.html
@@ -9,7 +9,7 @@ display: inline-block; } span { - -webkit-padding-start: 15px; -webkit-padding-end:15px; + padding-inline-start: 15px; padding-inline-end:15px; font-size: 48pt; background-color: #DDD; line-height: 2em;
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/border-styles-vertical-rl.html b/third_party/WebKit/LayoutTests/fast/writing-mode/border-styles-vertical-rl.html index 85af6c5..f2b3ddb5 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/border-styles-vertical-rl.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/border-styles-vertical-rl.html
@@ -9,7 +9,7 @@ display: inline-block; } span { - -webkit-padding-start: 15px; -webkit-padding-end:15px; + padding-inline-start: 15px; padding-inline-end:15px; font-size: 48pt; background-color: #DDD; line-height: 2em;
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/fieldsets.html b/third_party/WebKit/LayoutTests/fast/writing-mode/fieldsets.html index 83762bb..0ade129 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/fieldsets.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/fieldsets.html
@@ -3,16 +3,16 @@ <style> fieldset { - -webkit-logical-width:200px; - -webkit-logical-height:100px; + inline-size:200px; + block-size:100px; margin:1em; display:inline-block; } div { - -webkit-logical-width:100px; - -webkit-logical-height:25px; + inline-size:100px; + block-size:25px; background-color:orange; }
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container.html b/third_party/WebKit/LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container.html index ea0686b..216a4927 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container.html
@@ -1,5 +1,5 @@ <meta name=viewport content="width=device-width"> -<div style="border: solid; writing-mode: vertical-rl; -webkit-logical-width: 200px; -webkit-logical-height: 400px; +<div style="border: solid; writing-mode: vertical-rl; inline-size: 200px; block-size: 400px; font-size: 36px; line-height: 2; "> Lorem ipsum dolor <span id="target">sit</span> amet consectetur adipiscing elit.
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/logical-height-after-clear-expected.html b/third_party/WebKit/LayoutTests/fast/writing-mode/logical-height-after-clear-expected.html index 36518494..004d56e 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/logical-height-after-clear-expected.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/logical-height-after-clear-expected.html
@@ -1,13 +1,13 @@ <style> div.test { - -webkit-logical-width: 50px; - -webkit-logical-height: 100px; + inline-size: 50px; + block-size: 100px; background-color: green; } div.green { background-color: blue; - -webkit-logical-height: 50px; + block-size: 50px; } div.lr {
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/logical-height-after-clear.html b/third_party/WebKit/LayoutTests/fast/writing-mode/logical-height-after-clear.html index 30a187e..020d552 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/logical-height-after-clear.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/logical-height-after-clear.html
@@ -1,14 +1,14 @@ <style> div.test { - -webkit-logical-width: 50px; - -webkit-logical-height: 100px; + inline-size: 50px; + block-size: 100px; background-color: red; } div.float { float: left; - -webkit-logical-height: 50px; - -webkit-logical-width: 50px; + block-size: 50px; + inline-size: 50px; background-color: blue; } @@ -18,7 +18,7 @@ div.green { background-color: green; - -webkit-logical-height: 25px; + block-size: 25px; } div.lr {
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/orthogonal-inline-block.html b/third_party/WebKit/LayoutTests/fast/writing-mode/orthogonal-inline-block.html index b823218..392b5c7 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/orthogonal-inline-block.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/orthogonal-inline-block.html
@@ -46,46 +46,46 @@ generate('margin-top: 1em', top); generate('margin-right: 1em', right); generate('margin-bottom: 1em', bottom); - generate('-webkit-margin-before: 1em', right); - generate('-webkit-margin-after: 1em', left); - generate('-webkit-margin-start: 1em', top); - generate('-webkit-margin-end: 1em', bottom); + generate('margin-block-start: 1em', right); + generate('margin-block-end: 1em', left); + generate('margin-inline-start: 1em', top); + generate('margin-inline-end: 1em', bottom); generate('border-left: 1em transparent solid', left); generate('border-top: 1em transparent solid', top); generate('border-right: 1em transparent solid', right); generate('border-bottom: 1em transparent solid', bottom); - generate('-webkit-border-before: 1em transparent solid', right); - generate('-webkit-border-after: 1em transparent solid', left); - generate('-webkit-border-start: 1em transparent solid', top); - generate('-webkit-border-end: 1em transparent solid', bottom); + generate('border-block-start: 1em transparent solid', right); + generate('border-block-end: 1em transparent solid', left); + generate('border-inline-start: 1em transparent solid', top); + generate('border-inline-end: 1em transparent solid', bottom); generate('padding-left: 1em', left); generate('padding-top: 1em', top); generate('padding-right: 1em', right); generate('padding-bottom: 1em', bottom); - generate('-webkit-padding-before: 1em', right); - generate('-webkit-padding-after: 1em', left); - generate('-webkit-padding-start: 1em', top); - generate('-webkit-padding-end: 1em', bottom); + generate('padding-block-start: 1em', right); + generate('padding-block-end: 1em', left); + generate('padding-inline-start: 1em', top); + generate('padding-inline-end: 1em', bottom); generate('margin-left: 20%', left); generate('margin-top: 20%', top); generate('margin-right: 20%', right); generate('margin-bottom: 20%', bottom); - generate('-webkit-margin-before: 20%', right); - generate('-webkit-margin-after: 20%', left); - generate('-webkit-margin-start: 20%', top); - generate('-webkit-margin-end: 20%', bottom); + generate('margin-block-start: 20%', right); + generate('margin-block-end: 20%', left); + generate('margin-inline-start: 20%', top); + generate('margin-inline-end: 20%', bottom); generate('padding-left: 20%', left); generate('padding-top: 20%', top); generate('padding-right: 20%', right); generate('padding-bottom: 20%', bottom); - generate('-webkit-padding-before: 20%', right); - generate('-webkit-padding-after: 20%', left); - generate('-webkit-padding-start: 20%', top); - generate('-webkit-padding-end: 20%', bottom); + generate('padding-block-start: 20%', right); + generate('padding-block-end: 20%', left); + generate('padding-inline-start: 20%', top); + generate('padding-inline-end: 20%', bottom); } function generate(inline_block_style, expected_direction) {
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/root-lr-basic.html b/third_party/WebKit/LayoutTests/fast/writing-mode/root-lr-basic.html index 85d14ec..45c08e10 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/root-lr-basic.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/root-lr-basic.html
@@ -1,2 +1,2 @@ <!doctype html> -<html style="overflow:hidden; -webkit-writing-mode:vertical-lr; -webkit-logical-height:100px; border:2px solid black"></html> +<html style="overflow:hidden; -webkit-writing-mode:vertical-lr; block-size:100px; border:2px solid black"></html>
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/vertical-lr-replaced-selection.html b/third_party/WebKit/LayoutTests/fast/writing-mode/vertical-lr-replaced-selection.html index 16b7395..7a9b3e6 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/vertical-lr-replaced-selection.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/vertical-lr-replaced-selection.html
@@ -15,4 +15,4 @@ </head> <body onload="selectStuff()" style="font-size:36px; -webkit-writing-mode:vertical-lr;-webkit-text-orientation:sideways-right;text-rendering:optimizeLegibility;">This is the first line of text.<br> -<img style="-webkit-logical-width:20px;-webkit-logical-height:50px;background-color:green"> This is the second line of <img style="-webkit-logical-width:20px;-webkit-logical-height:100px;background-color:purple"> text. \ No newline at end of file +<img style="inline-size:20px;block-size:50px;background-color:green"> This is the second line of <img style="inline-size:20px;block-size:100px;background-color:purple"> text. \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/vertical-rl-replaced-selection.html b/third_party/WebKit/LayoutTests/fast/writing-mode/vertical-rl-replaced-selection.html index 32d6428..0b640140 100644 --- a/third_party/WebKit/LayoutTests/fast/writing-mode/vertical-rl-replaced-selection.html +++ b/third_party/WebKit/LayoutTests/fast/writing-mode/vertical-rl-replaced-selection.html
@@ -16,4 +16,4 @@ </head> <body onload="selectStuff()" style="font-size:36px; -webkit-writing-mode:vertical-rl;-webkit-text-orientation:sideways-right;text-rendering:optimizeLegibility">This is the first line of text.<br> -<img style="-webkit-logical-width:20px;-webkit-logical-height:50px;background-color:green"> This is the second line of <img style="-webkit-logical-width:20px;-webkit-logical-height:100px;background-color:purple"> text. \ No newline at end of file +<img style="inline-size:20px;block-size:50px;background-color:green"> This is the second line of <img style="inline-size:20px;block-size:100px;background-color:purple"> text. \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/invalidation-background-image.html b/third_party/WebKit/LayoutTests/http/tests/csspaint/invalidation-background-image.html index 86143c8b..6b3e32a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/csspaint/invalidation-background-image.html +++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/invalidation-background-image.html
@@ -46,6 +46,6 @@ { property: '-webkit-border-radius', invalidationProperty: 'border-radius', prevValue: '', value: '25px' }, { property: 'border-radius', invalidationProperty: '-webkit-border-radius', prevValue: '25px', value: '' }, { property: '-webkit-border-radius', prevValue: '100px', value: 'calc(50px + 50px)', noInvalidation: true }, - { property: '-webkit-margin-start', invalidationProperty: 'margin-left', prevValue: 'calc(50px + 50px)', value: '100px', noInvalidation: true }, + { property: 'margin-inline-start', invalidationProperty: 'margin-left', prevValue: 'calc(50px + 50px)', value: '100px', noInvalidation: true }, ]); </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/resources/test-runner-invalidation-logging.js b/third_party/WebKit/LayoutTests/http/tests/csspaint/resources/test-runner-invalidation-logging.js index f8ae42d7..cea64138 100644 --- a/third_party/WebKit/LayoutTests/http/tests/csspaint/resources/test-runner-invalidation-logging.js +++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/resources/test-runner-invalidation-logging.js
@@ -10,7 +10,7 @@ // testRunnerInvalidationLogging('background-image', [ // { property: 'max-height', value: '100px' }, // { property: 'color', prevValue: '#00F', value: 'blue', noInvalidation: true }, -// { property: '-webkit-margin-start', invalidationProperty: 'margin-left', prevValue: 'calc(50px + 50px)', value: '100px', noInvalidation: true } +// { property: 'margin-inline-start', invalidationProperty: 'margin-left', prevValue: 'calc(50px + 50px)', value: '100px', noInvalidation: true } // ]); function testRunnerInvalidationLogging(imageType, tests) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/test-helpers.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/test-helpers.js index ecc94b7..240db09 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/test-helpers.js +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/test-helpers.js
@@ -210,3 +210,15 @@ 'password2' + suffix, 'cookie2'); }); } + +function wait_for_port_message(port, handler) { + return new Promise((resolve, reject) => { + port.onmessage = (e) => { + try { + resolve(handler(e)); + } catch (e) { + reject(e); + } + }; + }); +}
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/update-no-controllee-worker.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/update-no-controllee-worker.js new file mode 100644 index 0000000..0eeb286 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/update-no-controllee-worker.js
@@ -0,0 +1,32 @@ +const rejectAfter = (timeout) => { + return new Promise((resolve, reject) => { + setTimeout(() => reject(), timeout); + }); +} + +const startUpdate = () => { + let p = []; + for (let i = 0; i < 10; i++) { + p.push(self.registration.update()); + } + return Promise.all(p); +}; + +const update = () => { + // update() rejects in one of these cases: + // 1. at least one update() rejects, or + // 2. at least one update() does not resolve after 15 seconds. + return Promise.race([startUpdate(), rejectAfter(150000)]); +}; + +self.addEventListener('message', (e) => { + const port = e.data; + + port.onmessage = (e) => { + update().then(() => { + port.postMessage('success'); + }).catch((e) => { + port.postMessage('failure'); + }); + }; +});
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/update-no-controllee.https-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/update-no-controllee.https-expected.txt new file mode 100644 index 0000000..3e0ec4b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/update-no-controllee.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Verify multiple updates from service workers without controllees do not resolve immediately assert_equals: update should not have succeeded expected "failure" but got "success" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/update-no-controllee.https.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/update-no-controllee.https.html new file mode 100644 index 0000000..40740c6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/update-no-controllee.https.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<!-- This is not a WPT test because it tests non-specified Chrome-specific behavior. It tests that self-updating service workers eventually fail to update. --> +<title>Service Worker: update no controllee</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/test-helpers.js"></script> +<body> +<script> +promise_test(async (t) => { + // Set up ServiceWorker and wait until it's |activated|. + const url = 'resources/update-no-controllee-worker.js'; + const scope = 'resources/blank.html'; + const registration = await service_worker_unregister_and_register(t, url, scope); + await wait_for_state(t, registration.installing, 'activated'); + + const frame = await with_iframe(scope); + + const w = frame.contentWindow; + const sw = w.navigator.serviceWorker; + assert_true(sw.controller instanceof w.ServiceWorker, + 'controller should be a ServiceWorker object'); + + const channel = new MessageChannel(); + sw.controller.postMessage(channel.port1, [channel.port1]); + + // Remove frame so our worker has no controller. + frame.remove(); + assert_equals( + sw.controller, null, 'disconnected frame should not be controlled'); + + // Send a message to the worker to start updating and wait for its response. + // We expect at least one of the updates, and therefore the complete proccess, + // to fail immediately because the delay is too long. + const result = wait_for_port_message(channel.port2, (e) => { + assert_equals(e.data, 'failure', 'update should not have succeeded'); + }); + channel.port2.postMessage(''); + await result; + + // Cleanup. + await registration.unregister(); +}, 'Verify multiple updates from service workers without controllees ' + + 'do not resolve immediately'); +</script> +</body>
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 68c12d00..759ccea 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
@@ -64,11 +64,6 @@ attribute @@toStringTag method constructor method updateUI -interface BackgroundFetchedEvent : BackgroundFetchEvent - attribute @@toStringTag - getter fetches - method constructor - method updateUI interface BarcodeDetector attribute @@toStringTag method constructor
diff --git a/third_party/WebKit/LayoutTests/http/tests/wasm_streaming/regression860637.html b/third_party/WebKit/LayoutTests/http/tests/wasm_streaming/regression860637.html new file mode 100644 index 0000000..b0c9722b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/wasm_streaming/regression860637.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="wasm_response_apis.js"></script> +<script src="../wasm/resources/wasm-constants.js"></script> +<script src="../wasm/resources/wasm-module-builder.js"></script> +<script> + promise_test(TestRegression837417, "Regression test"); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/wasm_streaming/wasm_response_apis.js b/third_party/WebKit/LayoutTests/http/tests/wasm_streaming/wasm_response_apis.js index 4ee7579..316f37e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/wasm_streaming/wasm_response_apis.js +++ b/third_party/WebKit/LayoutTests/http/tests/wasm_streaming/wasm_response_apis.js
@@ -255,3 +255,12 @@ worker.addEventListener('message', e => resolve(e.data)); return promise.then(exists => assert_true(exists)); } + +function TestRegression837417() { + let old_then = WebAssembly.Module.prototype.then; + WebAssembly.Module.prototype.then = resolve => resolve(String.fromCharCode( + null, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41)); + + return WebAssembly.instantiateStreaming(fetch(incrementer_url)) + .then(pair => assert_equals(5, pair.instance.exports.increment(4))); +}
diff --git a/third_party/WebKit/LayoutTests/images/mask-box-image-crash.html b/third_party/WebKit/LayoutTests/images/mask-box-image-crash.html index 35ced77..b491549 100644 --- a/third_party/WebKit/LayoutTests/images/mask-box-image-crash.html +++ b/third_party/WebKit/LayoutTests/images/mask-box-image-crash.html
@@ -2,7 +2,7 @@ if (window.testRunner) testRunner.dumpAsTextWithPixelResults(); </script> -<fieldset style="-webkit-margin-end: 99999px; +<fieldset style="margin-inline-end: 99999px; -webkit-mask-box-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE\ IAAABCAQAAAADLLz1FAAAACXZwQWcAAABCAAAAQgCVDTvpAAAAFElEQVQoz2P4DwUHGEZZo6xBwQI\ ANWY/j0PofaAAAAAASUVORK5CYII=') 10000% 10000 9999999999%;">
diff --git a/third_party/WebKit/LayoutTests/paint/transparency/compositing-alpha-fold-crash.html b/third_party/WebKit/LayoutTests/paint/transparency/compositing-alpha-fold-crash.html index 7aae271..479e8e5 100644 --- a/third_party/WebKit/LayoutTests/paint/transparency/compositing-alpha-fold-crash.html +++ b/third_party/WebKit/LayoutTests/paint/transparency/compositing-alpha-fold-crash.html
@@ -3,6 +3,6 @@ <body style="opacity:0.5"> <div style=" -webkit-mask-box-image-source: url();" > </div> -<div style="box-shadow: 1px 1px black; -webkit-padding-before: 1px; isolation: isolate"> +<div style="box-shadow: 1px 1px black; padding-block-start: 1px; isolation: isolate"> <div style="isolation: isolate"></div> </body>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/scrollbar-part-created-with-no-parent-crash.html b/third_party/WebKit/LayoutTests/scrollbars/scrollbar-part-created-with-no-parent-crash.html index 8ba9295d..8b34409 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/scrollbar-part-created-with-no-parent-crash.html +++ b/third_party/WebKit/LayoutTests/scrollbars/scrollbar-part-created-with-no-parent-crash.html
@@ -6,7 +6,7 @@ margin: 0; } ::-webkit-scrollbar { - -webkit-logical-height: 65536; + block-size: 65536; -webkit-border-image: url(does_not_exist) 0 2 0 2; }
diff --git a/third_party/WebKit/LayoutTests/scrollbars/scrollbar-percent-padding-crash.html b/third_party/WebKit/LayoutTests/scrollbars/scrollbar-percent-padding-crash.html index 808b25be..ef2c2789 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/scrollbar-percent-padding-crash.html +++ b/third_party/WebKit/LayoutTests/scrollbars/scrollbar-percent-padding-crash.html
@@ -3,7 +3,7 @@ <head> <style> ::-webkit-scrollbar { - -webkit-padding-start: 1%; background: #666 -webkit-gradient(linear, left top, right top, from(rgba(255,255,255,0.5)), color-stop(0.5, rgba(255,255,255,0.1)), color-stop(0.5, rgba(0,0,0,0)), to(rgba(0,0,0,0.01))); + padding-inline-start: 1%; background: #666 -webkit-gradient(linear, left top, right top, from(rgba(255,255,255,0.5)), color-stop(0.5, rgba(255,255,255,0.1)), color-stop(0.5, rgba(0,0,0,0)), to(rgba(0,0,0,0.01))); } </style> <script>
diff --git a/third_party/WebKit/LayoutTests/svg/as-image/svg-intrinsic-size-rectangular-vertical-expected.html b/third_party/WebKit/LayoutTests/svg/as-image/svg-intrinsic-size-rectangular-vertical-expected.html index adde32e..39f6897 100644 --- a/third_party/WebKit/LayoutTests/svg/as-image/svg-intrinsic-size-rectangular-vertical-expected.html +++ b/third_party/WebKit/LayoutTests/svg/as-image/svg-intrinsic-size-rectangular-vertical-expected.html
@@ -2,8 +2,8 @@ <style> div.container { -webkit-writing-mode: vertical-rl; - -webkit-logical-width: 80px; - -webkit-logical-height: 200px; + inline-size: 80px; + block-size: 200px; outline: solid blue; } </style>
diff --git a/third_party/WebKit/LayoutTests/svg/as-image/svg-intrinsic-size-rectangular-vertical.html b/third_party/WebKit/LayoutTests/svg/as-image/svg-intrinsic-size-rectangular-vertical.html index 77205ec..fa52028a 100644 --- a/third_party/WebKit/LayoutTests/svg/as-image/svg-intrinsic-size-rectangular-vertical.html +++ b/third_party/WebKit/LayoutTests/svg/as-image/svg-intrinsic-size-rectangular-vertical.html
@@ -2,8 +2,8 @@ <style> div.container { -webkit-writing-mode: vertical-rl; - -webkit-logical-width: 80px; - -webkit-logical-height: 200px; + inline-size: 80px; + block-size: 200px; outline: solid blue; }
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/image-cull-rect-transform-change-expected.html b/third_party/WebKit/LayoutTests/svg/transforms/image-cull-rect-transform-change-expected.html new file mode 100644 index 0000000..cfc2657 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/transforms/image-cull-rect-transform-change-expected.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<svg style="width: 400px; height: 400px"> + <image xlink:href="../custom/resources/green-rect.svg" width="100" height="100" style="transform: translate(1px, 1px);"></image> +</svg>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/image-cull-rect-transform-change.html b/third_party/WebKit/LayoutTests/svg/transforms/image-cull-rect-transform-change.html new file mode 100644 index 0000000..83eb337 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/transforms/image-cull-rect-transform-change.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<svg style="width: 400px; height: 400px"> + <image id="image" xlink:href="../custom/resources/green-rect.svg" width="100" height="100"></image> +</svg> +<script> +image.style.transform = "translate(-300px, -300px)"; +if (window.testRunner) + testRunner.waitUntilDone(); +onload = function() { + runAfterLayoutAndPaint(() => { + image.style.transform = "translate(1px, 1px)"; + window.testRunner.notifyDone(); + }); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/rect-cull-rect-transform-change-expected.html b/third_party/WebKit/LayoutTests/svg/transforms/rect-cull-rect-transform-change-expected.html new file mode 100644 index 0000000..397ddf7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/transforms/rect-cull-rect-transform-change-expected.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<svg style="width: 400px; height: 400px"> + <rect width="100" height="100" fill="green" style="transform: translate(1px, 1px);"></rect> +</svg>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/rect-cull-rect-transform-change.html b/third_party/WebKit/LayoutTests/svg/transforms/rect-cull-rect-transform-change.html new file mode 100644 index 0000000..0b2eb79 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/transforms/rect-cull-rect-transform-change.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<svg style="width: 400px; height: 400px"> + <rect id="rect" width="100" height="100" fill="green"></rect> +</svg> +<script> +rect.style.transform = "translate(-300px, -300px)"; +if (window.testRunner) + testRunner.waitUntilDone(); +runAfterLayoutAndPaint(() => { + rect.style.transform = "translate(1px, 1px)"; + window.testRunner.notifyDone(); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/touchadjustment/small-target-test.html b/third_party/WebKit/LayoutTests/touchadjustment/small-target-test.html index 77ae0f8..2b96b28d 100644 --- a/third_party/WebKit/LayoutTests/touchadjustment/small-target-test.html +++ b/third_party/WebKit/LayoutTests/touchadjustment/small-target-test.html
@@ -7,7 +7,7 @@ <style> body { - -webkit-margin-start: 20px; + margin-inline-start: 20px; margin-top: 20px; } .control-pair {
diff --git a/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js b/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js index 88b5719d..22058646 100644 --- a/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js +++ b/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js
@@ -296,7 +296,13 @@ this.displayClient_ = new device.mojom.VRDisplayClientPtr(); this.displayInfo_ = displayInfo; this.service_ = service; - this.presentation_provider_ = new MockVRPresentationProvider(); + this.presentation_provider_ = new MockXRPresentationProvider(); + + this.pose_ = null; + this.next_frame_id_ = 0; + + this.input_sources_ = []; + this.next_input_source_index_ = 1; if (service.client_) { this.notifyClientOfDisplay(); @@ -306,28 +312,39 @@ requestSession(sessionOptions, was_activation) { return this.supportsSession(sessionOptions).then((result) => { // The JavaScript bindings convert c_style_names to camelCase names. - var options = new device.mojom.VRDisplayFrameTransportOptions(); + var options = new device.mojom.XRPresentationTransportOptions(); options.transportMethod = - device.mojom.VRDisplayFrameTransportMethod.SUBMIT_AS_MAILBOX_HOLDER; + device.mojom.XRPresentationTransportMethod.SUBMIT_AS_MAILBOX_HOLDER; options.waitForTransferNotification = true; options.waitForRenderNotification = true; - let connection; + let submit_frame_sink; if (result.supportsSession) { - connection = { + submit_frame_sink = { clientRequest: this.presentation_provider_.getClientRequest(), provider: this.presentation_provider_.bindProvider(sessionOptions), transportOptions: options }; - let magicWindowPtr = new device.mojom.VRMagicWindowProviderPtr(); - let magicWindowRequest = mojo.makeRequest(magicWindowPtr); - let magicWindowBinding = new mojo.Binding( - device.mojom.VRMagicWindowProvider, this, magicWindowRequest); + + let dataProviderPtr = new device.mojom.XRFrameDataProviderPtr(); + let dataProviderRequest = mojo.makeRequest(dataProviderPtr); + let dataProviderBinding = new mojo.Binding( + device.mojom.XRFrameDataProvider, this, dataProviderRequest); + + let enviromentProviderPtr = + new device.mojom.XREnviromentIntegrationProviderPtr(); + let enviromentProviderRequest = mojo.makeRequest(enviromentProviderPtr); + let enviromentProviderBinding = new mojo.Binding( + device.mojom.XREnviromentIntegrationProvider, this, + enviromentProviderRequest); return Promise.resolve({ - session: - {connection: connection, magicWindowProvider: magicWindowPtr} + session: { + submitFrameSink: submit_frame_sink, + dataProvider: dataProviderPtr, + enviromentProvider: enviromentProviderPtr + } }); } else { return Promise.resolve({session: null}); @@ -344,10 +361,10 @@ setPose(pose) { if (pose == null) { - this.presentation_provider_.pose_ = null; + this.pose_ = null; } else { - this.presentation_provider_.initPose(); - this.presentation_provider_.fillPose(pose); + this.initPose(); + this.fillPose(pose); } } @@ -370,16 +387,33 @@ } getFrameData() { + if (this.pose_) { + this.pose_.poseIndex++; + + let input_states = []; + for (let i = 0; i < this.input_sources_.length; ++i) { + input_states.push(this.input_sources_[i].getInputSourceState()); + } + + this.pose_.inputState = input_states; + } + + // Convert current document time to monotonic time. + var now = window.performance.now() / 1000.0; + var diff = now - internals.monotonicTimeToZeroBasedDocumentTime(now); + now += diff; + now *= 1000000; + return Promise.resolve({ frameData: { - pose: this.presentation_provider_.pose_, + pose: this.pose_, bufferHolder: null, bufferSize: {}, - timeDelta: [], - projectionMatrix: [1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1] + timeDelta: { + microseconds: now, + }, + frameId: this.next_frame_id_++, + projectionMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] } }); } @@ -425,95 +459,6 @@ displayPtr, clientRequest, this.displayInfo_); } - addInputSource(input_source) { - this.presentation_provider_.OnInputSourceAdded(input_source); - } - - removeInputSource(input_source) { - this.presentation_provider_.OnInputSourceRemoved(input_source); - } -} - -class MockVRPresentationProvider { - constructor() { - this.binding_ = - new mojo.Binding(device.mojom.VRPresentationProviderPtr, this); - this.pose_ = null; - this.next_frame_id_ = 0; - this.submit_frame_count_ = 0; - this.missing_frame_count_ = 0; - - this.input_sources_ = []; - this.next_input_source_index_ = 1; - } - - bindProvider(request) { - let providerPtr = new device.mojom.VRPresentationProviderPtr(); - let providerRequest = mojo.makeRequest(providerPtr); - - this.binding_.close(); - - this.binding_ = new mojo.Binding( - device.mojom.VRPresentationProvider, this, providerRequest); - - return providerPtr; - } - - getClientRequest() { - this.submitFrameClient_ = new device.mojom.VRSubmitFrameClientPtr(); - return mojo.makeRequest(this.submitFrameClient_); - } - - - submitFrameMissing(frameId, mailboxHolder, timeWaited) { - this.missing_frame_count_++; - } - - submitFrame(frameId, mailboxHolder, timeWaited) { - this.submit_frame_count_++; - - // Trigger the submit completion callbacks here. WARNING: The - // Javascript-based mojo mocks are *not* re-entrant. It's OK to - // wait for these notifications on the next frame, but waiting - // within the current frame would never finish since the incoming - // calls would be queued until the current execution context finishes. - this.submitFrameClient_.onSubmitFrameTransferred(true); - this.submitFrameClient_.onSubmitFrameRendered(); - } - - getFrameData() { - if (this.pose_) { - this.pose_.poseIndex++; - - let input_states = []; - for (let i = 0; i < this.input_sources_.length; ++i) { - input_states.push(this.input_sources_[i].getInputSourceState()); - } - - this.pose_.inputState = input_states; - } - - // Convert current document time to monotonic time. - var now = window.performance.now() / 1000.0; - var diff = now - internals.monotonicTimeToZeroBasedDocumentTime(now); - now += diff; - now *= 1000000; - - return Promise.resolve({ - frameData: { - pose: this.pose_, - timeDelta: { - microseconds: now, - }, - frameId: this.next_frame_id_++, - projectionMatrix : [1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1] - } - }); - } - initPose() { this.pose_ = { orientation: null, @@ -536,14 +481,14 @@ } } - OnInputSourceAdded(input_source) { + addInputSource(input_source) { let index = this.next_input_source_index_; input_source.source_id_ = index; this.next_input_source_index_++; this.input_sources_.push(input_source); } - OnInputSourceRemoved(input_source) { + removeInputSource(input_source) { for (let i = 0; i < this.input_sources_.length; ++i) { if (input_source.source_id_ == this.input_sources_[i].source_id_) { this.input_sources_.splice(i, 1); @@ -553,6 +498,49 @@ } } +class MockXRPresentationProvider { + constructor() { + this.binding_ = + new mojo.Binding(device.mojom.XRPresentationProviderPtr, this); + this.submit_frame_count_ = 0; + this.missing_frame_count_ = 0; + } + + bindProvider(request) { + let providerPtr = new device.mojom.XRPresentationProviderPtr(); + let providerRequest = mojo.makeRequest(providerPtr); + + this.binding_.close(); + + this.binding_ = new mojo.Binding( + device.mojom.XRPresentationProvider, this, providerRequest); + + return providerPtr; + } + + getClientRequest() { + this.submitFrameClient_ = new device.mojom.XRPresentationClientPtr(); + return mojo.makeRequest(this.submitFrameClient_); + } + + + submitFrameMissing(frameId, mailboxHolder, timeWaited) { + this.missing_frame_count_++; + } + + submitFrame(frameId, mailboxHolder, timeWaited) { + this.submit_frame_count_++; + + // Trigger the submit completion callbacks here. WARNING: The + // Javascript-based mojo mocks are *not* re-entrant. It's OK to + // wait for these notifications on the next frame, but waiting + // within the current frame would never finish since the incoming + // calls would be queued until the current execution context finishes. + this.submitFrameClient_.onSubmitFrameTransferred(true); + this.submitFrameClient_.onSubmitFrameRendered(); + } +} + class MockVRService { constructor() { this.bindingSet_ = new mojo.BindingSet(device.mojom.VRService);
diff --git a/third_party/abseil-cpp/BUILD.gn b/third_party/abseil-cpp/BUILD.gn index 6005148..4d9f46c4 100644 --- a/third_party/abseil-cpp/BUILD.gn +++ b/third_party/abseil-cpp/BUILD.gn
@@ -19,28 +19,7 @@ } config("absl_include_config") { - # Using -isystem (with clang and GCC) and -imsvc (with clang-cl) instead of - # include_dirs (-I), so we don't need to suppress warnings coming from - # Abseil. Doing so would mask warnings in our own code. - if (is_win) { - if (is_clang) { - # clang-cl: - cflags = [ - "-imsvc", - rebase_path(".", root_build_dir), - ] - } else { - # MSVC doesn't have -isystem, in that case we fallback to include_dirs and - # we use the warning suppression flags defined in :absl_default_cflags_cc. - include_dirs = [ "." ] - } - } else { - # GCC or clang: - cflags = [ - "-isystem", - rebase_path(".", root_build_dir), - ] - } + include_dirs = [ "." ] } config("absl_define_config") {
diff --git a/third_party/abseil-cpp/absl/time/BUILD.gn b/third_party/abseil-cpp/absl/time/BUILD.gn index 7f412bcc..24de31c 100644 --- a/third_party/abseil-cpp/absl/time/BUILD.gn +++ b/third_party/abseil-cpp/absl/time/BUILD.gn
@@ -14,11 +14,21 @@ visibility = [ "*" ] } +config("suppress_unguarded_availability") { + # TODO(bugs.webrtc.org/9557): Remove -Wno-unguarded-availability when + # abseil will support Xcode 9.0+ (it currently supports Xcode 7.3.1+ + # which doesn't have -Wunguarded-availability and __builtin_available). + cflags = [ + "-Wno-unguarded-availability", + ] +} + source_set("time") { configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code", "//third_party/abseil-cpp:absl_default_cflags_cc", + ":suppress_unguarded_availability", ] public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] sources = [
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index c6c030a0..4ae8004 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -319,7 +319,6 @@ "platform/web_native_scroll_behavior.h", "platform/web_network_state_notifier.h", "platform/web_platform_event_listener.h", - "platform/web_platform_event_type.h", "platform/web_point.h", "platform/web_pointer_event.h", "platform/web_pointer_properties.h",
diff --git a/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom b/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom index af3a5239..fb00f88 100644 --- a/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom +++ b/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom
@@ -73,7 +73,8 @@ UpdateUI(int64 service_worker_registration_id, string developer_id, string unique_id, - string title) + string? title, + skia.mojom.Bitmap? icon) => (BackgroundFetchError error); // Aborts the Background Fetch registration identified by |unique_id| and
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index ff0d114..3c22845 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -55,7 +55,6 @@ #include "third_party/blink/public/platform/web_gamepad_listener.h" #include "third_party/blink/public/platform/web_gesture_device.h" #include "third_party/blink/public/platform/web_localized_string.h" -#include "third_party/blink/public/platform/web_platform_event_type.h" #include "third_party/blink/public/platform/web_rtc_api_name.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/public/platform/web_speech_synthesizer.h"
diff --git a/third_party/blink/public/platform/web_platform_event_type.h b/third_party/blink/public/platform/web_platform_event_type.h deleted file mode 100644 index 91c1e2f5..0000000 --- a/third_party/blink/public/platform/web_platform_event_type.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_PLATFORM_EVENT_TYPE_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_PLATFORM_EVENT_TYPE_H_ - -namespace blink { - -enum WebPlatformEventType { - kWebPlatformEventTypeDeviceMotion, - kWebPlatformEventTypeDeviceOrientation, - kWebPlatformEventTypeDeviceOrientationAbsolute, - kWebPlatformEventTypeGamepad, -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_PLATFORM_EVENT_TYPE_H_
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 895bd6cb..ea32357e 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -191,6 +191,7 @@ BLINK_PLATFORM_EXPORT static void EnableV8ContextSnapshot(bool); BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool); BLINK_PLATFORM_EXPORT static void EnableWorkStealingInScriptRunner(bool); + BLINK_PLATFORM_EXPORT static void EnableScheduledScriptStreaming(bool); BLINK_PLATFORM_EXPORT static void EnableStopInBackground(bool); BLINK_PLATFORM_EXPORT static void EnableStopNonTimersInBackground(bool); BLINK_PLATFORM_EXPORT static void EnablePWAFullCodeCache(bool);
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc index 70f3cbd..9e56a7092 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -13,12 +13,15 @@ #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" +#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/script/classic_pending_script.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" #include "third_party/blink/renderer/platform/loader/fetch/resource.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/deque.h" @@ -392,6 +395,19 @@ streaming_suppressed_ = true; } +static void RunScriptStreamingTask( + std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task, + ScriptStreamer* streamer) { + TRACE_EVENT1( + "v8,devtools.timeline", "v8.parseOnBackground", "data", + InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(), + streamer->ScriptURLString())); + // Running the task can and will block: SourceStream::GetSomeData will get + // called and it will block and wait for data from the network. + task->Run(); + streamer->StreamingCompleteOnBackgroundThread(); +} + void ScriptStreamer::NotifyAppendData(ScriptResource* resource) { DCHECK(IsMainThread()); if (streaming_suppressed_) @@ -436,11 +452,12 @@ } } - if (ScriptStreamerThread::Shared()->IsRunningTask()) { - // At the moment we only have one thread for running the tasks. A - // new task shouldn't be queued before the running task completes, - // because the running task can block and wait for data from the - // network. + if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() && + ScriptStreamerThread::Shared()->IsRunningTask()) { + // If scheduled script streaming is disabled, we only have one thread for + // running the tasks. A new task shouldn't be queued before the running + // task completes, because the running task can block and wait for data + // from the network. SuppressStreaming(); RecordNotStreamingReasonHistogram(script_type_, kThreadBusy); RecordStartedStreamingHistogram(script_type_, 0); @@ -476,10 +493,24 @@ return; } - ScriptStreamerThread::Shared()->PostTask( - CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask, - WTF::Passed(std::move(script_streaming_task)), - WrapCrossThreadPersistent(this))); + if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) { + // Script streaming tasks are high priority, as they can block the + // parser, and they can (and probably will) block during their own + // execution as they wait for more input. + // + // TODO(leszeks): Decrease the priority of these tasks where possible. + BackgroundScheduler::PostOnBackgroundThreadWithTraits( + FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()}, + CrossThreadBind(RunScriptStreamingTask, + WTF::Passed(std::move(script_streaming_task)), + WrapCrossThreadPersistent(this))); + } else { + ScriptStreamerThread::Shared()->PostTask( + CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask, + WTF::Passed(std::move(script_streaming_task)), + WrapCrossThreadPersistent(this))); + } + RecordStartedStreamingHistogram(script_type_, 1); } if (stream_)
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc index 0ea5e53..6111fec 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
@@ -108,8 +108,10 @@ } void ProcessTasksUntilStreamingComplete() { - while (ScriptStreamerThread::Shared()->IsRunningTask()) { - test::RunPendingTasks(); + if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) { + while (ScriptStreamerThread::Shared()->IsRunningTask()) { + test::RunPendingTasks(); + } } // Once more, because the "streaming complete" notification might only // now be in the task queue.
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc index a197c9d..9051edde 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
@@ -11,6 +11,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_streamer.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/web_task_runner.h" namespace blink { @@ -22,19 +23,24 @@ static Mutex* g_mutex = nullptr; void ScriptStreamerThread::Init() { - DCHECK(!g_shared_thread); - DCHECK(IsMainThread()); - // This is called in the main thread before any tasks are created, so no - // locking is needed. - g_mutex = new Mutex(); - g_shared_thread = new ScriptStreamerThread(); + // Only enabled when ScheduledScriptStreaming is disabled. + if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) { + DCHECK(!g_shared_thread); + DCHECK(IsMainThread()); + // This is called in the main thread before any tasks are created, so no + // locking is needed. + g_mutex = new Mutex(); + g_shared_thread = new ScriptStreamerThread(); + } } ScriptStreamerThread* ScriptStreamerThread::Shared() { + DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()); return g_shared_thread; } void ScriptStreamerThread::PostTask(CrossThreadClosure task) { + DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()); DCHECK(IsMainThread()); MutexLocker locker(mutex_); DCHECK(!running_task_); @@ -60,6 +66,7 @@ void ScriptStreamerThread::RunScriptStreamingTask( std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task, ScriptStreamer* streamer) { + DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()); TRACE_EVENT1( "v8,devtools.timeline", "v8.parseOnBackground", "data", InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(),
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc index 292660ef..ec89538 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
@@ -581,8 +581,8 @@ size_t size, size_t* actual_size) { *actual_size = WTF::Partitions::BufferActualSize(size); - return WTF::Partitions::BufferRealloc(old_buffer, *actual_size, - "SerializedScriptValue buffer"); + return WTF::Partitions::BufferTryRealloc(old_buffer, *actual_size, + "SerializedScriptValue buffer"); } void V8ScriptValueSerializer::FreeBufferMemory(void* buffer) {
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h index 7d74e07..7d8031f 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h
@@ -93,6 +93,9 @@ v8::Maybe<uint32_t> GetWasmModuleTransferId( v8::Isolate*, v8::Local<v8::WasmCompiledModule>) override; + // Reallocates memory at |ptr| to the new size and returns the new pointer or + // nullptr on failure. |actual_size| will hold the actual size of allocation + // requested. void* ReallocateBufferMemory(void* old_buffer, size_t, size_t* actual_size) override;
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc b/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc index 26154ed..fd56d312 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc
@@ -20,6 +20,103 @@ namespace { +// The |FetchDataLoader| for streaming compilation of WebAssembly code. The +// received bytes get forwarded to the V8 API class |WasmStreaming|. +class FetchDataLoaderForWasmStreaming final : public FetchDataLoader, + public BytesConsumer::Client { + USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderForWasmStreaming); + + public: + FetchDataLoaderForWasmStreaming(ScriptState* script_state, + std::shared_ptr<v8::WasmStreaming> streaming) + : streaming_(std::move(streaming)), script_state_(script_state) {} + + void Start(BytesConsumer* consumer, + FetchDataLoader::Client* client) override { + DCHECK(!consumer_); + DCHECK(!client_); + client_ = client; + consumer_ = consumer; + consumer_->SetClient(this); + OnStateChange(); + } + + void OnStateChange() override { + while (true) { + // |buffer| is owned by |consumer_|. + const char* buffer = nullptr; + size_t available = 0; + BytesConsumer::Result result = consumer_->BeginRead(&buffer, &available); + + if (result == BytesConsumer::Result::kShouldWait) + return; + if (result == BytesConsumer::Result::kOk) { + if (available > 0) { + DCHECK_NE(buffer, nullptr); + streaming_->OnBytesReceived(reinterpret_cast<const uint8_t*>(buffer), + available); + } + result = consumer_->EndRead(available); + } + switch (result) { + case BytesConsumer::Result::kShouldWait: + NOTREACHED(); + return; + case BytesConsumer::Result::kOk: { + break; + } + case BytesConsumer::Result::kDone: { + streaming_->Finish(); + client_->DidFetchDataLoadedCustomFormat(); + return; + } + case BytesConsumer::Result::kError: { + return AbortCompilation(); + } + } + } + } + + String DebugName() const override { return "FetchDataLoaderForWasmModule"; } + + void Cancel() override { + consumer_->Cancel(); + return AbortCompilation(); + } + + void Trace(blink::Visitor* visitor) override { + visitor->Trace(consumer_); + visitor->Trace(client_); + visitor->Trace(script_state_); + FetchDataLoader::Trace(visitor); + BytesConsumer::Client::Trace(visitor); + } + + private: + // TODO(ahaas): replace with spec-ed error types, once spec clarifies + // what they are. + void AbortCompilation() { + if (script_state_->ContextIsValid()) { + ScriptState::Scope scope(script_state_); + streaming_->Abort(V8ThrowException::CreateTypeError( + script_state_->GetIsolate(), "Could not download wasm module")); + } else { + // We are not allowed to execute a script, which indicates that we should + // not reject the promise of the streaming compilation. By passing no + // abort reason, we indicate the V8 side that the promise should not get + // rejected. + streaming_->Abort(v8::Local<v8::Value>()); + } + } + Member<BytesConsumer> consumer_; + Member<FetchDataLoader::Client> client_; + std::shared_ptr<v8::WasmStreaming> streaming_; + const Member<ScriptState> script_state_; +}; + +// TODO(ahaas): Remove |FetchDataLoaderAsWasmModule| once the +// |SetWasmCompileStreamingCallback| API is successfully replaced by the +// |SetWasmStreamingCallback| API. class FetchDataLoaderAsWasmModule final : public FetchDataLoader, public BytesConsumer::Client { USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsWasmModule); @@ -42,7 +139,7 @@ void OnStateChange() override { while (true) { - // {buffer} is owned by {m_consumer}. + // |buffer| is owned by |consumer_|. const char* buffer = nullptr; size_t available = 0; BytesConsumer::Result result = consumer_->BeginRead(&buffer, &available); @@ -96,8 +193,8 @@ // TODO(mtrofin): replace with spec-ed error types, once spec clarifies // what they are. void AbortCompilation() { - ScriptState::Scope scope(script_state_); - if (!ExecutionContext::From(script_state_)->IsContextDestroyed()) { + if (script_state_->ContextIsValid()) { + ScriptState::Scope scope(script_state_); builder_.Abort(V8ThrowException::CreateTypeError( script_state_->GetIsolate(), "Could not download wasm module")); } else { @@ -135,6 +232,97 @@ } }; +// ExceptionToAbortStreamingScope converts a possible exception to an abort +// message for WasmStreaming instead of throwing the exception. +// +// All exceptions which happen in the setup of WebAssembly streaming compilation +// have to be passed as an abort message to V8 so that V8 can reject the promise +// associated to the streaming compilation. +class ExceptionToAbortStreamingScope { + STACK_ALLOCATED(); + WTF_MAKE_NONCOPYABLE(ExceptionToAbortStreamingScope); + + public: + ExceptionToAbortStreamingScope(std::shared_ptr<v8::WasmStreaming> streaming, + ExceptionState& exception_state) + : streaming_(streaming), exception_state_(exception_state) {} + + ~ExceptionToAbortStreamingScope() { + if (!exception_state_.HadException()) + return; + + streaming_->Abort(exception_state_.GetException()); + exception_state_.ClearException(); + } + + private: + std::shared_ptr<v8::WasmStreaming> streaming_; + ExceptionState& exception_state_; +}; + +void StreamFromResponseCallback( + const v8::FunctionCallbackInfo<v8::Value>& args) { + ExceptionState exception_state(args.GetIsolate(), + ExceptionState::kExecutionContext, + "WebAssembly", "compile"); + std::shared_ptr<v8::WasmStreaming> streaming = + v8::WasmStreaming::Unpack(args.GetIsolate(), args.Data()); + ExceptionToAbortStreamingScope exception_scope(streaming, exception_state); + + ScriptState* script_state = ScriptState::ForCurrentRealm(args); + if (!script_state->ContextIsValid()) { + // We do not have an execution context, we just abort streaming compilation + // immediately without error. + streaming->Abort(v8::Local<v8::Value>()); + return; + } + + Response* response = + V8Response::ToImplWithTypeCheck(args.GetIsolate(), args[0]); + if (!response) { + exception_state.ThrowTypeError( + "An argument must be provided, which must be a " + "Response or Promise<Response> object"); + return; + } + + if (!response->ok()) { + exception_state.ThrowTypeError("HTTP status code is not ok"); + return; + } + + if (response->MimeType() != "application/wasm") { + exception_state.ThrowTypeError( + "Incorrect response MIME type. Expected 'application/wasm'."); + return; + } + + Body::BodyLocked body_locked = response->IsBodyLocked(exception_state); + if (body_locked == Body::BodyLocked::kBroken) + return; + + if (body_locked == Body::BodyLocked::kLocked || + response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) { + DCHECK(!exception_state.HadException()); + exception_state.ThrowTypeError( + "Cannot compile WebAssembly.Module from an already read Response"); + return; + } + + if (exception_state.HadException()) + return; + + if (!response->BodyBuffer()) { + exception_state.ThrowTypeError("Response object has a null body."); + return; + } + + FetchDataLoaderForWasmStreaming* loader = + new FetchDataLoaderForWasmStreaming(script_state, streaming); + response->BodyBuffer()->StartLoading(loader, new WasmDataLoaderClient(), + exception_state); +} + // This callback may be entered as a promise is resolved, or directly // from the overload callback. // See @@ -147,7 +335,7 @@ ExceptionToRejectPromiseScope reject_promise_scope(args, exception_state); ScriptState* script_state = ScriptState::ForCurrentRealm(args); - if (!ExecutionContext::From(script_state)) { + if (!script_state->ContextIsValid()) { V8SetReturnValue(args, ScriptPromise().V8Value()); return; } @@ -172,13 +360,18 @@ return; } - if (response->IsBodyLocked(exception_state) == Body::BodyLocked::kLocked || + Body::BodyLocked body_locked = response->IsBodyLocked(exception_state); + if (body_locked == Body::BodyLocked::kBroken) + return; + + if (body_locked == Body::BodyLocked::kLocked || response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) { DCHECK(!exception_state.HadException()); exception_state.ThrowTypeError( "Cannot compile WebAssembly.Module from an already read Response"); return; } + if (exception_state.HadException()) return; @@ -234,6 +427,7 @@ void WasmResponseExtensions::Initialize(v8::Isolate* isolate) { if (RuntimeEnabledFeatures::WebAssemblyStreamingEnabled()) { isolate->SetWasmCompileStreamingCallback(WasmCompileStreamingImpl); + isolate->SetWasmStreamingCallback(StreamFromResponseCallback); } }
diff --git a/third_party/blink/renderer/bindings/modules/BUILD.gn b/third_party/blink/renderer/bindings/modules/BUILD.gn index 1fe835b..01b6956d 100644 --- a/third_party/blink/renderer/bindings/modules/BUILD.gn +++ b/third_party/blink/renderer/bindings/modules/BUILD.gn
@@ -22,7 +22,6 @@ "//third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.idl", "//third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl", "//third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.idl", - "//third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl", "//third_party/blink/renderer/modules/background_sync/sync_event.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl", "//third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl",
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index 71b6440..4f46e9bf 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -415,9 +415,13 @@ if (!LowLatencyEnabled()) canvas2d_bridge_->FinalizeFrame(); + } - if (LowLatencyEnabled() && !dirty_rect_.IsEmpty() && - GetOrCreateCanvasResourceProvider(kPreferAcceleration)) { + if (LowLatencyEnabled() && !dirty_rect_.IsEmpty()) { + AccelerationHint hint = + Is2d() ? kPreferNoAcceleration : kPreferAcceleration; + if (GetOrCreateCanvasResourceProvider(hint)) { + ResourceProvider()->TryEnableSingleBuffering(); // Push a frame base::TimeTicks start_time = WTF::CurrentTimeTicks(); scoped_refptr<CanvasResource> canvas_resource = @@ -1138,9 +1142,8 @@ scoped_refptr<Image> HTMLCanvasElement::CopiedImage( SourceDrawingBuffer source_buffer, AccelerationHint hint) { - if (SurfaceLayerBridge()) { + if (PlaceholderFrame()) return PlaceholderFrame()->Bitmap(); - } if (!IsPaintable()) return nullptr;
diff --git a/third_party/blink/renderer/core/paint/BUILD.gn b/third_party/blink/renderer/core/paint/BUILD.gn index f4738106..b7663d0d 100644 --- a/third_party/blink/renderer/core/paint/BUILD.gn +++ b/third_party/blink/renderer/core/paint/BUILD.gn
@@ -216,6 +216,8 @@ "svg_inline_text_box_painter.h", "svg_mask_painter.cc", "svg_mask_painter.h", + "svg_model_object_painter.cc", + "svg_model_object_painter.h", "svg_paint_context.cc", "svg_paint_context.h", "svg_root_inline_box_painter.cc",
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc index 8760ba53..dcf00696 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -817,9 +817,12 @@ PaintLayerFlags paint_flags, const PaintLayerFragment& fragment, const LayoutSize& subpixel_accumulation) { - // Now do a paint with the root layer shifted to be us. The cull rect - // is infinite to simplify invalidation of clip property node changes across - // transform boundaries. + // Now do a paint with the root layer shifted to be us. + + // We do not apply cull rect optimizations across transforms for two reasons: + // 1) Performance: We can optimize transform changes by not repainting. + // 2) Complexity: Difficulty updating clips when ancestor transforms change. + // For these reasons, we use an infinite dirty rect here. PaintLayerPaintingInfo new_paint_info( &paint_layer_, LayoutRect(LayoutRect::InfiniteIntRect()), painting_info.GetGlobalPaintFlags(), subpixel_accumulation);
diff --git a/third_party/blink/renderer/core/paint/svg_container_painter.cc b/third_party/blink/renderer/core/paint/svg_container_painter.cc index 13e54af..58e7b810 100644 --- a/third_party/blink/renderer/core/paint/svg_container_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_container_painter.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/paint/object_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/paint/svg_foreign_object_painter.h" +#include "third_party/blink/renderer/core/paint/svg_model_object_painter.h" #include "third_party/blink/renderer/core/paint/svg_paint_context.h" #include "third_party/blink/renderer/core/svg/svg_svg_element.h" @@ -24,11 +25,6 @@ !layout_svg_container_.SelfWillPaint()) return; - FloatRect bounding_box = - layout_svg_container_.VisualRectInLocalSVGCoordinates(); - // LayoutSVGHiddenContainer's visual rect is always empty but we need to - // paint its descendants. - // Spec: An empty viewBox on the <svg> element disables rendering. DCHECK(layout_svg_container_.GetElement()); if (IsSVGSVGElement(*layout_svg_container_.GetElement()) && @@ -37,17 +33,19 @@ PaintInfo paint_info_before_filtering(paint_info); - // Content underneath transforms applies an infinite cull rect. This is - // to simplify invalidation of clip property node changes across transform - // boundaries. + if (SVGModelObjectPainter(layout_svg_container_) + .CullRectSkipsPainting(paint_info_before_filtering)) { + return; + } + + // We do not apply cull rect optimizations across transforms for two reasons: + // 1) Performance: We can optimize transform changes by not repainting. + // 2) Complexity: Difficulty updating clips when ancestor transforms change. + // This is why we use an infinite cull rect if there is a transform. Non-svg + // content, does this in PaintLayerPainter::PaintSingleFragment. if (layout_svg_container_.StyleRef().HasTransform()) { paint_info_before_filtering.ApplyInfiniteCullRect(); } else { - if (!layout_svg_container_.IsSVGHiddenContainer() && - !paint_info.GetCullRect().IntersectsCullRect( - layout_svg_container_.LocalToSVGParentTransform(), bounding_box)) - return; - paint_info_before_filtering.UpdateCullRect( layout_svg_container_.LocalToSVGParentTransform()); } @@ -94,20 +92,14 @@ } } - if (paint_info_before_filtering.phase != PaintPhase::kForeground) - return; + SVGModelObjectPainter(layout_svg_container_) + .PaintOutline(paint_info_before_filtering); - if (layout_svg_container_.Style()->OutlineWidth() && - layout_svg_container_.Style()->Visibility() == EVisibility::kVisible) { - PaintInfo outline_paint_info(paint_info_before_filtering); - outline_paint_info.phase = PaintPhase::kSelfOutlineOnly; - ObjectPainter(layout_svg_container_) - .PaintOutline(outline_paint_info, LayoutPoint(bounding_box.Location())); - } - - if (paint_info_before_filtering.IsPrinting()) + if (paint_info_before_filtering.IsPrinting() && + paint_info_before_filtering.phase == PaintPhase::kForeground) { ObjectPainter(layout_svg_container_) .AddPDFURLRectIfNeeded(paint_info_before_filtering, LayoutPoint()); + } } } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/svg_image_painter.cc b/third_party/blink/renderer/core/paint/svg_image_painter.cc index 977d09f..93d3611f 100644 --- a/third_party/blink/renderer/core/paint/svg_image_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_image_painter.cc
@@ -4,20 +4,15 @@ #include "third_party/blink/renderer/core/paint/svg_image_painter.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/layout/layout_image_resource.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h" -#include "third_party/blink/renderer/core/page/chrome_client.h" -#include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/paint/object_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h" +#include "third_party/blink/renderer/core/paint/svg_model_object_painter.h" #include "third_party/blink/renderer/core/paint/svg_paint_context.h" #include "third_party/blink/renderer/core/svg/graphics/svg_image.h" #include "third_party/blink/renderer/core/svg/svg_image_element.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h" #include "third_party/blink/renderer/platform/graphics/scoped_interpolation_quality.h" namespace blink { @@ -28,13 +23,14 @@ !layout_svg_image_.ImageResource()->HasImage()) return; - FloatRect bounding_box = layout_svg_image_.VisualRectInLocalSVGCoordinates(); - if (!paint_info.GetCullRect().IntersectsCullRect( - layout_svg_image_.LocalToSVGParentTransform(), bounding_box)) - return; - PaintInfo paint_info_before_filtering(paint_info); - // Images cannot have children so do not call updateCullRect. + + if (SVGModelObjectPainter(layout_svg_image_) + .CullRectSkipsPainting(paint_info_before_filtering)) { + return; + } + // Images cannot have children so do not call UpdateCullRect. + SVGTransformContext transform_context( paint_info_before_filtering, layout_svg_image_, layout_svg_image_.LocalToSVGParentTransform()); @@ -52,12 +48,8 @@ } } - if (layout_svg_image_.Style()->OutlineWidth()) { - PaintInfo outline_paint_info(paint_info_before_filtering); - outline_paint_info.phase = PaintPhase::kSelfOutlineOnly; - ObjectPainter(layout_svg_image_) - .PaintOutline(outline_paint_info, LayoutPoint(bounding_box.Location())); - } + SVGModelObjectPainter(layout_svg_image_) + .PaintOutline(paint_info_before_filtering); } void SVGImagePainter::PaintForeground(const PaintInfo& paint_info) {
diff --git a/third_party/blink/renderer/core/paint/svg_model_object_painter.cc b/third_party/blink/renderer/core/paint/svg_model_object_painter.cc new file mode 100644 index 0000000..956f01c --- /dev/null +++ b/third_party/blink/renderer/core/paint/svg_model_object_painter.cc
@@ -0,0 +1,46 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/paint/svg_model_object_painter.h" + +#include "third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h" +#include "third_party/blink/renderer/core/paint/object_painter.h" +#include "third_party/blink/renderer/core/paint/paint_info.h" + +namespace blink { + +bool SVGModelObjectPainter::CullRectSkipsPainting(const PaintInfo& paint_info) { + // We do not apply cull rect optimizations across transforms for two reasons: + // 1) Performance: We can optimize transform changes by not repainting. + // 2) Complexity: Difficulty updating clips when ancestor transforms change. + // For these reasons, we do not cull painting if there is a transform. + if (layout_svg_model_object_.StyleRef().HasTransform()) + return false; + + // LayoutSVGHiddenContainer's visual rect is always empty but we need to + // paint its descendants so we cannot skip painting. + if (layout_svg_model_object_.IsSVGHiddenContainer()) + return false; + + return !paint_info.GetCullRect().IntersectsCullRect( + layout_svg_model_object_.LocalToSVGParentTransform(), + layout_svg_model_object_.VisualRectInLocalSVGCoordinates()); +} + +void SVGModelObjectPainter::PaintOutline(const PaintInfo& paint_info) { + if (paint_info.phase != PaintPhase::kForeground) + return; + if (layout_svg_model_object_.Style()->Visibility() != EVisibility::kVisible) + return; + if (!layout_svg_model_object_.Style()->OutlineWidth()) + return; + + PaintInfo outline_paint_info(paint_info); + outline_paint_info.phase = PaintPhase::kSelfOutlineOnly; + auto visual_rect = layout_svg_model_object_.VisualRectInLocalSVGCoordinates(); + ObjectPainter(layout_svg_model_object_) + .PaintOutline(outline_paint_info, LayoutPoint(visual_rect.Location())); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/svg_model_object_painter.h b/third_party/blink/renderer/core/paint/svg_model_object_painter.h new file mode 100644 index 0000000..6f3df6d --- /dev/null +++ b/third_party/blink/renderer/core/paint/svg_model_object_painter.h
@@ -0,0 +1,35 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SVG_MODEL_OBJECT_PAINTER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SVG_MODEL_OBJECT_PAINTER_H_ + +#include "third_party/blink/renderer/platform/wtf/allocator.h" + +namespace blink { + +struct PaintInfo; +class LayoutSVGModelObject; + +class SVGModelObjectPainter { + STACK_ALLOCATED(); + + public: + SVGModelObjectPainter(const LayoutSVGModelObject& layout_svg_model_object) + : layout_svg_model_object_(layout_svg_model_object) {} + + // If the object is outside the cull rect, painting can be skipped in most + // cases. An important exception is when there is a transform style: see the + // comment in the implementation. + bool CullRectSkipsPainting(const PaintInfo&); + + void PaintOutline(const PaintInfo&); + + private: + const LayoutSVGModelObject& layout_svg_model_object_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SVG_MODEL_OBJECT_PAINTER_H_
diff --git a/third_party/blink/renderer/core/paint/svg_shape_painter.cc b/third_party/blink/renderer/core/paint/svg_shape_painter.cc index ea42ac8b..2c8ed98 100644 --- a/third_party/blink/renderer/core/paint/svg_shape_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_shape_painter.cc
@@ -11,9 +11,9 @@ #include "third_party/blink/renderer/core/layout/svg/svg_marker_data.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h" -#include "third_party/blink/renderer/core/paint/object_painter.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/paint/svg_container_painter.h" +#include "third_party/blink/renderer/core/paint/svg_model_object_painter.h" #include "third_party/blink/renderer/core/paint/svg_paint_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" @@ -46,13 +46,14 @@ layout_svg_shape_.IsShapeEmpty()) return; - FloatRect bounding_box = layout_svg_shape_.VisualRectInLocalSVGCoordinates(); - if (!paint_info.GetCullRect().IntersectsCullRect( - layout_svg_shape_.LocalSVGTransform(), bounding_box)) - return; - PaintInfo paint_info_before_filtering(paint_info); - // Shapes cannot have children so do not call updateCullRect. + + if (SVGModelObjectPainter(layout_svg_shape_) + .CullRectSkipsPainting(paint_info_before_filtering)) { + return; + } + // Shapes cannot have children so do not call UpdateCullRect. + SVGTransformContext transform_context(paint_info_before_filtering, layout_svg_shape_, layout_svg_shape_.LocalSVGTransform()); @@ -124,7 +125,8 @@ } break; case PT_MARKERS: - PaintMarkers(paint_context.GetPaintInfo(), bounding_box); + PaintMarkers(paint_context.GetPaintInfo(), + layout_svg_shape_.VisualRectInLocalSVGCoordinates()); break; default: NOTREACHED(); @@ -134,12 +136,8 @@ } } - if (layout_svg_shape_.Style()->OutlineWidth()) { - PaintInfo outline_paint_info(paint_info_before_filtering); - outline_paint_info.phase = PaintPhase::kSelfOutlineOnly; - ObjectPainter(layout_svg_shape_) - .PaintOutline(outline_paint_info, LayoutPoint(bounding_box.Location())); - } + SVGModelObjectPainter(layout_svg_shape_) + .PaintOutline(paint_info_before_filtering); } class PathWithTemporaryWindingRule {
diff --git a/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js b/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js index 57bf5fb7..b020a21 100644 --- a/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js +++ b/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js
@@ -209,6 +209,9 @@ */ async linkifyObject(snapshotObjectId) { const heapProfilerModel = this._profile.heapProfilerModel(); + // heapProfilerModel is null if snapshot was loaded from file + if (!heapProfilerModel) + return null; const remoteObject = await heapProfilerModel.objectForSnapshotObjectId(String(snapshotObjectId), 'link'); if (!remoteObject || remoteObject.type !== 'function') return null;
diff --git a/third_party/blink/renderer/modules/background_fetch/BUILD.gn b/third_party/blink/renderer/modules/background_fetch/BUILD.gn index 831d97f..0cd04774 100644 --- a/third_party/blink/renderer/modules/background_fetch/BUILD.gn +++ b/third_party/blink/renderer/modules/background_fetch/BUILD.gn
@@ -32,8 +32,6 @@ "background_fetch_type_converters.h", "background_fetch_update_event.cc", "background_fetch_update_event.h", - "background_fetched_event.cc", - "background_fetched_event.h", "service_worker_global_scope_background_fetch.h", "service_worker_registration_background_fetch.cc", "service_worker_registration_background_fetch.h",
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc index 2ed7682..ca9a66d 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc
@@ -69,10 +69,17 @@ void BackgroundFetchBridge::UpdateUI(const String& developer_id, const String& unique_id, const String& title, + const SkBitmap& icon, UpdateUICallback callback) { + if (title.IsNull() && icon.isNull()) { + std::move(callback).Run( + mojom::blink::BackgroundFetchError::INVALID_ARGUMENT); + return; + } + GetService()->UpdateUI( GetSupplementable()->WebRegistration()->RegistrationId(), developer_id, - unique_id, title, std::move(callback)); + unique_id, title, icon, std::move(callback)); } void BackgroundFetchBridge::GetRegistration(const String& developer_id,
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h index 652f8ff..8e48fa0 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
@@ -60,11 +60,12 @@ void GetIconDisplaySize(GetIconDisplaySizeCallback callback); // Updates the user interface for the Background Fetch identified by - // |unique_id| with the updated |title|. Will invoke the |callback| when the - // interface has been requested to update. + // |unique_id| with the updated |title| or |icon|. Will invoke the |callback| + // when the interface has been requested to update. void UpdateUI(const String& developer_id, const String& unique_id, const String& title, + const SkBitmap& icon, UpdateUICallback callback); // Aborts the active Background Fetch for |unique_id|. Will invoke the
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.cc index c1aeb79..8f57469d7 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.cc
@@ -7,11 +7,13 @@ #include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fetch/request.h" #include "third_party/blink/renderer/core/fetch/response.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h" +#include "third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h" -#include "third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.h" +#include "third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_options.h" #include "third_party/blink/renderer/modules/event_modules_names.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" @@ -30,17 +32,20 @@ WaitUntilObserver* observer, ServiceWorkerRegistration* registration) : BackgroundFetchSettledEvent(type, initializer, unique_id, observer), - registration_(registration) {} + registration_(registration), + loader_(new BackgroundFetchIconLoader) {} BackgroundFetchUpdateEvent::~BackgroundFetchUpdateEvent() = default; void BackgroundFetchUpdateEvent::Trace(blink::Visitor* visitor) { visitor->Trace(registration_); + visitor->Trace(loader_); BackgroundFetchSettledEvent::Trace(visitor); } -ScriptPromise BackgroundFetchUpdateEvent::updateUI(ScriptState* script_state, - const String& title) { +ScriptPromise BackgroundFetchUpdateEvent::updateUI( + ScriptState* script_state, + const BackgroundFetchUpdateUIOptions& ui_options) { if (!registration_) { // Return a Promise that will never settle when a developer calls this // method on a BackgroundFetchedEvent instance they created themselves. @@ -48,17 +53,36 @@ } DCHECK(!unique_id_.IsEmpty()); + if (!ui_options.hasTitle() && ui_options.icons().IsEmpty()) { + // Nothing to update, just return a resolved promise. + ScriptPromise::CastUndefined(script_state); + } + ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise promise = resolver->Promise(); - BackgroundFetchBridge::From(registration_) - ->UpdateUI(id(), unique_id_, title, - WTF::Bind(&BackgroundFetchUpdateEvent::DidUpdateUI, - WrapPersistent(this), WrapPersistent(resolver))); + if (ui_options.icons().IsEmpty()) { + DidGetIcon(resolver, ui_options.title(), SkBitmap()); + } else { + loader_->Start( + BackgroundFetchBridge::From(registration_), + ExecutionContext::From(script_state), ui_options.icons(), + WTF::Bind(&BackgroundFetchUpdateEvent::DidGetIcon, WrapPersistent(this), + WrapPersistent(resolver), ui_options.title())); + } return promise; } +void BackgroundFetchUpdateEvent::DidGetIcon(ScriptPromiseResolver* resolver, + const String& title, + const SkBitmap& icon) { + BackgroundFetchBridge::From(registration_) + ->UpdateUI(id(), unique_id_, title, icon, + WTF::Bind(&BackgroundFetchUpdateEvent::DidUpdateUI, + WrapPersistent(this), WrapPersistent(resolver))); +} + void BackgroundFetchUpdateEvent::DidUpdateUI( ScriptPromiseResolver* resolver, mojom::blink::BackgroundFetchError error) {
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h index 5683234..c060dcff 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h
@@ -11,6 +11,9 @@ namespace blink { +class BackgroundFetchIconLoader; +class BackgroundFetchUpdateUIOptions; + // Event for interacting with fetch requests that have completed. class MODULES_EXPORT BackgroundFetchUpdateEvent final : public BackgroundFetchSettledEvent { @@ -37,7 +40,8 @@ ~BackgroundFetchUpdateEvent() override; // Web Exposed method defined in the IDL file. - ScriptPromise updateUI(ScriptState* script_state, const String& title); + ScriptPromise updateUI(ScriptState* script_state, + const BackgroundFetchUpdateUIOptions& ui_options); void Trace(blink::Visitor* visitor) override; @@ -53,10 +57,15 @@ WaitUntilObserver* observer, ServiceWorkerRegistration* registration); + void DidGetIcon(ScriptPromiseResolver* resolver, + const String& title, + const SkBitmap& icon); + void DidUpdateUI(ScriptPromiseResolver* resolver, mojom::blink::BackgroundFetchError error); Member<ServiceWorkerRegistration> registration_; + Member<BackgroundFetchIconLoader> loader_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.idl b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.idl index c9c7948..f4faa5c 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.idl +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.idl
@@ -10,5 +10,5 @@ RuntimeEnabled=BackgroundFetch ] interface BackgroundFetchUpdateEvent : BackgroundFetchSettledEvent { - [CallWith=ScriptState] Promise<void> updateUI(DOMString title); + [CallWith=ScriptState] Promise<void> updateUI(BackgroundFetchUpdateUIOptions title); }; \ No newline at end of file
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_options.idl b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_options.idl new file mode 100644 index 0000000..549c1b70 --- /dev/null +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_options.idl
@@ -0,0 +1,13 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://wicg.github.io/background-fetch/#backgroundfetchupdateevent + +// TODO(crbug.com/865063): Fix names after the standard is updated. +// Spec Bug: https://github.com/WICG/background-fetch/issues/86 + +dictionary BackgroundFetchUpdateUIOptions { + DOMString? title; + sequence<ImageResource> icons = []; +};
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetched_event.cc b/third_party/blink/renderer/modules/background_fetch/background_fetched_event.cc deleted file mode 100644 index 5416bd2..0000000 --- a/third_party/blink/renderer/modules/background_fetch/background_fetched_event.cc +++ /dev/null
@@ -1,107 +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. - -#include "third_party/blink/renderer/modules/background_fetch/background_fetched_event.h" - -#include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/core/fetch/request.h" -#include "third_party/blink/renderer/core/fetch/response.h" -#include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h" -#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h" -#include "third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.h" -#include "third_party/blink/renderer/modules/event_modules_names.h" -#include "third_party/blink/renderer/platform/bindings/script_state.h" - -namespace blink { - -BackgroundFetchedEvent::BackgroundFetchedEvent( - const AtomicString& type, - const BackgroundFetchedEventInit& initializer) - : BackgroundFetchEvent(type, initializer, nullptr /* observer */), - fetches_(initializer.fetches()) {} - -BackgroundFetchedEvent::BackgroundFetchedEvent( - const AtomicString& type, - const BackgroundFetchedEventInit& initializer, - const String& unique_id, - const WebVector<WebBackgroundFetchSettledFetch>& fetches, - ScriptState* script_state, - WaitUntilObserver* observer, - ServiceWorkerRegistration* registration) - : BackgroundFetchEvent(type, initializer, observer), - unique_id_(unique_id), - registration_(registration) { - fetches_.ReserveInitialCapacity(fetches.size()); - for (const WebBackgroundFetchSettledFetch& fetch : fetches) { - auto* settled_fetch = BackgroundFetchSettledFetch::Create( - Request::Create(script_state, fetch.request), - Response::Create(script_state, fetch.response)); - - fetches_.push_back(settled_fetch); - } -} - -BackgroundFetchedEvent::~BackgroundFetchedEvent() = default; - -HeapVector<Member<BackgroundFetchSettledFetch>> -BackgroundFetchedEvent::fetches() const { - return fetches_; -} - -ScriptPromise BackgroundFetchedEvent::updateUI(ScriptState* script_state, - const String& title) { - if (!registration_) { - // Return a Promise that will never settle when a developer calls this - // method on a BackgroundFetchedEvent instance they created themselves. - return ScriptPromise(); - } - DCHECK(!unique_id_.IsEmpty()); - - ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); - ScriptPromise promise = resolver->Promise(); - - BackgroundFetchBridge::From(registration_) - ->UpdateUI(id(), unique_id_, title, - WTF::Bind(&BackgroundFetchedEvent::DidUpdateUI, - WrapPersistent(this), WrapPersistent(resolver))); - - return promise; -} - -void BackgroundFetchedEvent::DidUpdateUI( - ScriptPromiseResolver* resolver, - mojom::blink::BackgroundFetchError error) { - switch (error) { - case mojom::blink::BackgroundFetchError::NONE: - case mojom::blink::BackgroundFetchError::INVALID_ID: - resolver->Resolve(); - return; - case mojom::blink::BackgroundFetchError::STORAGE_ERROR: - resolver->Reject( - DOMException::Create(DOMExceptionCode::kAbortError, - "Failed to update UI due to I/O error.")); - return; - case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE: - case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID: - case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT: - // Not applicable for this callback. - break; - } - - NOTREACHED(); -} - -const AtomicString& BackgroundFetchedEvent::InterfaceName() const { - return EventNames::BackgroundFetchedEvent; -} - -void BackgroundFetchedEvent::Trace(blink::Visitor* visitor) { - visitor->Trace(fetches_); - visitor->Trace(registration_); - BackgroundFetchEvent::Trace(visitor); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetched_event.h b/third_party/blink/renderer/modules/background_fetch/background_fetched_event.h deleted file mode 100644 index d86e7392..0000000 --- a/third_party/blink/renderer/modules/background_fetch/background_fetched_event.h +++ /dev/null
@@ -1,87 +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 THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCHED_EVENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCHED_EVENT_H_ - -#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-blink.h" -#include "third_party/blink/public/platform/web_vector.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" -#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.h" -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" - -namespace blink { - -class BackgroundFetchSettledFetch; -class BackgroundFetchedEventInit; -class ScriptPromiseResolver; -class ScriptState; -class ServiceWorkerRegistration; -struct WebBackgroundFetchSettledFetch; - -class MODULES_EXPORT BackgroundFetchedEvent final - : public BackgroundFetchEvent { - DEFINE_WRAPPERTYPEINFO(); - - public: - static BackgroundFetchedEvent* Create( - const AtomicString& type, - const BackgroundFetchedEventInit& initializer) { - return new BackgroundFetchedEvent(type, initializer); - } - - static BackgroundFetchedEvent* Create( - const AtomicString& type, - const BackgroundFetchedEventInit& initializer, - const String& unique_id, - const WebVector<WebBackgroundFetchSettledFetch>& fetches, - ScriptState* script_state, - WaitUntilObserver* observer, - ServiceWorkerRegistration* registration) { - return new BackgroundFetchedEvent(type, initializer, unique_id, fetches, - script_state, observer, registration); - } - - ~BackgroundFetchedEvent() override; - - // Web Exposed attribute defined in the IDL file. - HeapVector<Member<BackgroundFetchSettledFetch>> fetches() const; - - // Web Exposed method defined in the IDL file. - ScriptPromise updateUI(ScriptState* script_state, const String& title); - - // ExtendableEvent interface. - const AtomicString& InterfaceName() const override; - - void Trace(blink::Visitor* visitor) override; - - private: - BackgroundFetchedEvent(const AtomicString& type, - const BackgroundFetchedEventInit& initializer); - BackgroundFetchedEvent( - const AtomicString& type, - const BackgroundFetchedEventInit& initializer, - const String& unique_id, - const WebVector<WebBackgroundFetchSettledFetch>& fetches, - ScriptState* script_state, - WaitUntilObserver* observer, - ServiceWorkerRegistration* registration); - - void DidUpdateUI(ScriptPromiseResolver* resolver, - mojom::blink::BackgroundFetchError error); - - // Globally unique ID for the registration, generated in content/. Used to - // distinguish registrations in case a developer re-uses |developer_id_|s. Not - // exposed to JavaScript. - String unique_id_; - - HeapVector<Member<BackgroundFetchSettledFetch>> fetches_; - Member<ServiceWorkerRegistration> registration_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCHED_EVENT_H_
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl b/third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl deleted file mode 100644 index 2226821..0000000 --- a/third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl +++ /dev/null
@@ -1,15 +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. - -// https://wicg.github.io/background-fetch/#background-fetch-end-event - -[ - Constructor(DOMString type, BackgroundFetchedEventInit init), - Exposed=ServiceWorker, - RuntimeEnabled=BackgroundFetch -] interface BackgroundFetchedEvent : BackgroundFetchEvent { - readonly attribute FrozenArray<BackgroundFetchSettledFetch> fetches; - - [CallWith=ScriptState] Promise<void> updateUI(DOMString title); -};
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.idl b/third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.idl deleted file mode 100644 index 68d6f684..0000000 --- a/third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.idl +++ /dev/null
@@ -1,9 +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. - -// https://wicg.github.io/background-fetch/#background-fetch-end-event - -dictionary BackgroundFetchedEventInit : BackgroundFetchEventInit { - required sequence<BackgroundFetchSettledFetch> fetches; -};
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc index 5c679f9..208ff8c 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -120,16 +120,15 @@ return CanvasElement().GetGPUMemoryUsage(); } void DrawSomething() { - Canvas2DLayerBridge* bridge = CanvasElement().GetCanvas2DLayerBridge(); - bridge->DidDraw(FloatRect(0, 0, 1, 1)); - bridge->FinalizeFrame(); + CanvasElement().DidDraw(); + CanvasElement().FinalizeFrame(); // Grabbing an image forces a flush - bridge->NewImageSnapshot(kPreferAcceleration); + CanvasElement().CopiedImage(kBackBuffer, kPreferAcceleration); } - void CreateContext(OpacityMode, - String color_space = String(), - LinearPixelMathState = kLinearPixelMathDisabled); + enum LatencyMode { kNormalLatency, kLowLatency }; + + void CreateContext(OpacityMode, LatencyMode = kNormalLatency); ScriptState* GetScriptState() { return ToScriptStateForMainWorld(canvas_element_->GetFrame()); } @@ -185,19 +184,12 @@ opaque_bitmap_(IntSize(10, 10), kOpaqueBitmap), alpha_bitmap_(IntSize(10, 10), kTransparentBitmap) {} -void CanvasRenderingContext2DTest::CreateContext( - OpacityMode opacity_mode, - String color_space, - LinearPixelMathState LinearPixelMath_state) { +void CanvasRenderingContext2DTest::CreateContext(OpacityMode opacity_mode, + LatencyMode latency_mode) { String canvas_type("2d"); CanvasContextCreationAttributesCore attributes; attributes.alpha = opacity_mode == kNonOpaque; - if (!color_space.IsEmpty()) { - attributes.color_space = color_space; - if (LinearPixelMath_state == kLinearPixelMathEnabled) { - attributes.pixel_format = "float16"; - } - } + attributes.low_latency = latency_mode == kLowLatency; canvas_element_->GetCanvasRenderingContext(canvas_type, attributes); } @@ -1209,4 +1201,22 @@ EXPECT_FALSE(layer->NeedsCompositingInputsUpdate()); } +TEST_F(CanvasRenderingContext2DTest, LowLatencyIsSingleBuffered) { + CreateContext(kNonOpaque, kLowLatency); + // No need to set-up the layer bridge when testing low latency mode. + DrawSomething(); + auto frame1_resource = + CanvasElement() + .GetOrCreateCanvasResourceProvider(kPreferNoAcceleration) + ->ProduceFrame(); + EXPECT_TRUE(!!frame1_resource); + DrawSomething(); + auto frame2_resource = + CanvasElement() + .GetOrCreateCanvasResourceProvider(kPreferNoAcceleration) + ->ProduceFrame(); + EXPECT_TRUE(!!frame2_resource); + EXPECT_EQ(frame1_resource.get(), frame2_resource.get()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.cc b/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.cc index 8a15c24..01f17d13 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.cc +++ b/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.cc
@@ -88,10 +88,4 @@ return last_device_orientation_data_.Get(); } -WebPlatformEventType DeviceOrientationDispatcher::GetWebPlatformEventType() - const { - return (absolute_) ? kWebPlatformEventTypeDeviceOrientationAbsolute - : kWebPlatformEventTypeDeviceOrientation; -} - } // namespace blink
diff --git a/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h b/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h index 62a9453..b8e25cb0 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h +++ b/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h
@@ -33,7 +33,6 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h" -#include "third_party/blink/public/platform/web_platform_event_type.h" #include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -74,8 +73,6 @@ void StartListening(LocalFrame* frame) override; void StopListening() override; - WebPlatformEventType GetWebPlatformEventType() const; - const bool absolute_; Member<DeviceOrientationData> last_device_orientation_data_; std::unique_ptr<DeviceOrientationEventPump> event_pump_;
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index c5efe86..6ff80c5 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -74,7 +74,6 @@ "background_fetch/background_fetch_settled_fetch.idl", "background_fetch/background_fetch_settled_fetches.idl", "background_fetch/background_fetch_update_event.idl", - "background_fetch/background_fetched_event.idl", "background_sync/sync_event.idl", "background_sync/sync_manager.idl", "battery/battery_manager.idl", @@ -469,7 +468,7 @@ "background_fetch/background_fetch_fail_event_init.idl", "background_fetch/background_fetch_options.idl", "background_fetch/background_fetch_settled_event_init.idl", - "background_fetch/background_fetched_event_init.idl", + "background_fetch/background_fetch_update_ui_options.idl", "background_sync/sync_event_init.idl", "bluetooth/bluetooth_le_scan_filter_init.idl", "bluetooth/request_device_options.idl",
diff --git a/third_party/blink/renderer/modules/vr/vr_display.cc b/third_party/blink/renderer/modules/vr/vr_display.cc index a221211..d49ebfc 100644 --- a/third_party/blink/renderer/modules/vr/vr_display.cc +++ b/third_party/blink/renderer/modules/vr/vr_display.cc
@@ -244,7 +244,7 @@ pending_magic_window_vsync_ = false; pending_presenting_vsync_ = true; - vr_presentation_provider_->GetFrameData( + vr_presentation_data_provider_->GetFrameData( WTF::Bind(&VRDisplay::OnPresentingVSync, WrapWeakPersistent(this))); DVLOG(2) << __FUNCTION__ << " done: pending_presenting_vsync_=" @@ -502,17 +502,26 @@ void VRDisplay::OnRequestSessionReturned( device::mojom::blink::XRSessionPtr session) { pending_present_request_ = false; - if (session && session->connection) { - vr_presentation_provider_.Bind(std::move(session->connection->provider)); + if (session) { + DCHECK(session->submit_frame_sink); + vr_presentation_data_provider_.Bind(std::move(session->data_provider)); + // The presentation provider error handler can trigger if a device is + // disconnected from the system. This can happen if, for example, an HMD is + // unplugged. + vr_presentation_data_provider_.set_connection_error_handler( + WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError, + WrapWeakPersistent(this))); + vr_presentation_provider_.Bind( + std::move(session->submit_frame_sink->provider)); vr_presentation_provider_.set_connection_error_handler( WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError, WrapWeakPersistent(this))); frame_transport_ = new XRFrameTransport(); frame_transport_->BindSubmitFrameClient( - std::move(session->connection->client_request)); + std::move(session->submit_frame_sink->client_request)); frame_transport_->SetTransportOptions( - std::move(session->connection->transport_options)); + std::move(session->submit_frame_sink->transport_options)); this->BeginPresent(); } else { @@ -529,11 +538,11 @@ void VRDisplay::OnMagicWindowRequestReturned( device::mojom::blink::XRSessionPtr session) { - if (!session || !session->magic_window_provider) { - // System does not support any kind of magic window. + if (!session) { + // System does not support any kind of session. return; } - magic_window_provider_.Bind(std::move(session->magic_window_provider)); + magic_window_provider_.Bind(std::move(session->data_provider)); RequestVSync(); } @@ -611,7 +620,7 @@ } is_presenting_ = true; // Call RequestVSync to switch from the (internal) document rAF to the - // VrPresentationProvider GetFrameData rate. + // XRPresentationProvider GetFrameData rate. RequestVSync(); ReportPresentationResult(PresentationResult::kSuccess); @@ -1038,6 +1047,7 @@ << " pending_magic_window_vsync_=" << pending_magic_window_vsync_ << " pending_presenting_vsync_=" << pending_presenting_vsync_; vr_presentation_provider_.reset(); + vr_presentation_data_provider_.reset(); if (is_presenting_) { ForceExitPresent(); }
diff --git a/third_party/blink/renderer/modules/vr/vr_display.h b/third_party/blink/renderer/modules/vr/vr_display.h index bfd14698..4c6da38 100644 --- a/third_party/blink/renderer/modules/vr/vr_display.h +++ b/third_party/blink/renderer/modules/vr/vr_display.h
@@ -217,14 +217,15 @@ bool did_log_getFrameData_ = false; bool did_log_requestPresent_ = false; - device::mojom::blink::VRMagicWindowProviderPtr magic_window_provider_; + device::mojom::blink::XRFrameDataProviderPtr magic_window_provider_; device::mojom::blink::VRDisplayHostPtr display_; bool present_image_needs_copy_ = false; mojo::Binding<device::mojom::blink::VRDisplayClient> display_client_binding_; - device::mojom::blink::VRPresentationProviderPtr vr_presentation_provider_; + device::mojom::blink::XRFrameDataProviderPtr vr_presentation_data_provider_; + device::mojom::blink::XRPresentationProviderPtr vr_presentation_provider_; HeapDeque<Member<ScriptPromiseResolver>> pending_present_resolvers_; };
diff --git a/third_party/blink/renderer/modules/xr/xr_device.cc b/third_party/blink/renderer/modules/xr/xr_device.cc index 7925e02..edd484b 100644 --- a/third_party/blink/renderer/modules/xr/xr_device.cc +++ b/third_party/blink/renderer/modules/xr/xr_device.cc
@@ -199,9 +199,6 @@ return; } - if (session_ptr->magic_window_provider) - magic_window_provider_.Bind(std::move(session_ptr->magic_window_provider)); - XRPresentationContext* output_context = nullptr; if (options.hasOutputContext()) { output_context = options.outputContext(); @@ -218,8 +215,10 @@ sessions_.insert(session); if (options.immersive()) { - frameProvider()->BeginImmersiveSession(session, - std::move(session_ptr->connection)); + frameProvider()->BeginImmersiveSession(session, std::move(session_ptr)); + } else { + magic_window_provider_.Bind(std::move(session_ptr->data_provider)); + enviroment_provider_.Bind(std::move(session_ptr->enviroment_provider)); } resolver->Resolve(session);
diff --git a/third_party/blink/renderer/modules/xr/xr_device.h b/third_party/blink/renderer/modules/xr/xr_device.h index f4db8e21..2e83621 100644 --- a/third_party/blink/renderer/modules/xr/xr_device.h +++ b/third_party/blink/renderer/modules/xr/xr_device.h
@@ -54,10 +54,14 @@ const device::mojom::blink::VRDisplayHostPtr& xrDisplayHostPtr() const { return display_; } - const device::mojom::blink::VRMagicWindowProviderPtr& - xrMagicWindowProviderPtr() const { + const device::mojom::blink::XRFrameDataProviderPtr& xrMagicWindowProviderPtr() + const { return magic_window_provider_; } + const device::mojom::blink::XREnviromentIntegrationProviderPtr& + xrEnviromentProviderPtr() const { + return enviroment_provider_; + } const device::mojom::blink::VRDisplayInfoPtr& xrDisplayInfoPtr() const { return display_info_; } @@ -107,7 +111,8 @@ // Indicates whether we've already logged a request for an immersive session. bool did_log_request_immersive_session_ = false; - device::mojom::blink::VRMagicWindowProviderPtr magic_window_provider_; + device::mojom::blink::XRFrameDataProviderPtr magic_window_provider_; + device::mojom::blink::XREnviromentIntegrationProviderPtr enviroment_provider_; device::mojom::blink::VRDisplayHostPtr display_; device::mojom::blink::VRDisplayInfoPtr display_info_; unsigned int display_info_id_ = 0;
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc index 8a5a4e9..79b42f7 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -92,25 +92,29 @@ void XRFrameProvider::BeginImmersiveSession( XRSession* session, - device::mojom::blink::XRPresentationConnectionPtr connection) { + device::mojom::blink::XRSessionPtr session_ptr) { // Make sure the session is indeed an immersive one. DCHECK(session && session->immersive()); // Ensure we can only have one immersive session at a time. DCHECK(!immersive_session_); - DCHECK(connection); + DCHECK(session_ptr->data_provider); + DCHECK(session_ptr->submit_frame_sink); immersive_session_ = session; - presentation_provider_.Bind(std::move(connection->provider)); + immersive_data_provider_.Bind(std::move(session_ptr->data_provider)); + + presentation_provider_.Bind( + std::move(session_ptr->submit_frame_sink->provider)); presentation_provider_.set_connection_error_handler( WTF::Bind(&XRFrameProvider::OnPresentationProviderConnectionError, WrapWeakPersistent(this))); frame_transport_->BindSubmitFrameClient( - std::move(connection->client_request)); + std::move(session_ptr->submit_frame_sink->client_request)); frame_transport_->SetTransportOptions( - std::move(connection->transport_options)); + std::move(session_ptr->submit_frame_sink->transport_options)); frame_transport_->PresentChange(); } @@ -131,6 +135,7 @@ void XRFrameProvider::OnPresentationProviderConnectionError() { presentation_provider_.reset(); + immersive_data_provider_.reset(); if (vsync_connection_failed_) return; immersive_session_->ForceEnd(); @@ -147,10 +152,8 @@ immersive_session_ = nullptr; pending_immersive_vsync_ = false; frame_id_ = -1; - - if (presentation_provider_.is_bound()) { - presentation_provider_.reset(); - } + presentation_provider_.reset(); + immersive_data_provider_.reset(); frame_transport_ = new XRFrameTransport(); @@ -200,7 +203,7 @@ pending_immersive_vsync_ = true; - presentation_provider_->GetFrameData(WTF::Bind( + immersive_data_provider_->GetFrameData(WTF::Bind( &XRFrameProvider::OnImmersiveFrameData, WrapWeakPersistent(this))); } @@ -527,6 +530,7 @@ void XRFrameProvider::Dispose() { presentation_provider_.reset(); + immersive_data_provider_.reset(); // TODO(bajones): Do something for outstanding frame requests? }
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.h b/third_party/blink/renderer/modules/xr/xr_frame_provider.h index 159a4d55..c483e03 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_provider.h +++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.h
@@ -27,11 +27,10 @@ explicit XRFrameProvider(XRDevice*); XRSession* immersive_session() const { return immersive_session_; } - device::mojom::blink::VRSubmitFrameClientPtr GetSubmitFrameClient(); + device::mojom::blink::XRPresentationClientPtr GetSubmitFrameClient(); - void BeginImmersiveSession( - XRSession* session, - device::mojom::blink::XRPresentationConnectionPtr connection); + void BeginImmersiveSession(XRSession* session, + device::mojom::blink::XRSessionPtr session_ptr); void OnImmersiveSessionEnded(); void RequestFrame(XRSession*); @@ -66,8 +65,8 @@ // Non-immersive Sessions which have requested a frame update. HeapVector<Member<XRSession>> requesting_sessions_; - device::mojom::blink::VRPresentationProviderPtr presentation_provider_; - device::mojom::blink::VRMagicWindowProviderPtr magic_window_provider_; + device::mojom::blink::XRPresentationProviderPtr presentation_provider_; + device::mojom::blink::XRFrameDataProviderPtr immersive_data_provider_; device::mojom::blink::VRPosePtr frame_pose_; // This frame ID is XR-specific and is used to track when frames arrive at the
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index d838ef8..b3ca9f0 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -312,7 +312,7 @@ // TODO(https://crbug.com/845520): Promise should be rejected if session // is deleted. - device_->xrMagicWindowProviderPtr()->RequestHitTest( + device_->xrEnviromentProviderPtr()->RequestHitTest( std::move(ray), WTF::Bind(&XRSession::OnHitTestResults, WrapWeakPersistent(this), WrapPersistent(resolver))); @@ -550,8 +550,8 @@ DVLOG(2) << __FUNCTION__ << ": got angle=" << output_angle; } - if (device_->xrMagicWindowProviderPtr()) { - device_->xrMagicWindowProviderPtr()->UpdateSessionGeometry( + if (device_->xrEnviromentProviderPtr()) { + device_->xrEnviromentProviderPtr()->UpdateSessionGeometry( IntSize(output_width_, output_height_), display::Display::DegreesToRotation(output_angle)); }
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index e3383f4..a176ed33 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -524,6 +524,10 @@ RuntimeEnabledFeatures::SetWorkStealingInScriptRunnerEnabled(enable); } +void WebRuntimeFeatures::EnableScheduledScriptStreaming(bool enable) { + RuntimeEnabledFeatures::SetScheduledScriptStreamingEnabled(enable); +} + void WebRuntimeFeatures::EnableStopInBackground(bool enable) { RuntimeEnabledFeatures::SetStopInBackgroundEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index 4685fcd2..8d951cd 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -152,6 +152,7 @@ ~CanvasResourceProviderTextureGpuMemoryBuffer() override = default; bool SupportsDirectCompositing() const override { return true; } + bool SupportsSingleBuffering() const override { return true; } private: scoped_refptr<CanvasResource> CreateResource() final { @@ -263,6 +264,7 @@ ~CanvasResourceProviderRamGpuMemoryBuffer() override = default; bool SupportsDirectCompositing() const override { return true; } + bool SupportsSingleBuffering() const override { return true; } private: scoped_refptr<CanvasResource> CreateResource() final { @@ -318,6 +320,7 @@ } ~CanvasResourceProviderSharedBitmap() override = default; bool SupportsDirectCompositing() const override { return true; } + bool SupportsSingleBuffering() const override { return true; } private: scoped_refptr<CanvasResource> CreateResource() final { @@ -684,6 +687,7 @@ canvas_image_provider_.reset(); xform_canvas_ = nullptr; surface_ = nullptr; + single_buffer_ = nullptr; } uint32_t CanvasResourceProvider::ContentUniqueID() const { @@ -721,6 +725,11 @@ } scoped_refptr<CanvasResource> CanvasResourceProvider::NewOrRecycledResource() { + if (IsSingleBuffered()) { + if (!single_buffer_) + single_buffer_ = CreateResource(); + return single_buffer_; + } if (recycled_resources_.size()) { scoped_refptr<CanvasResource> resource = std::move(recycled_resources_.back()); @@ -730,4 +739,11 @@ return CreateResource(); } +void CanvasResourceProvider::TryEnableSingleBuffering() { + if (IsSingleBuffered() || !SupportsSingleBuffering()) + return; + SetResourceRecyclingEnabled(false); + is_single_buffered_ = true; +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h index 661aa5d..12866715 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
@@ -100,11 +100,26 @@ virtual bool IsValid() const = 0; virtual bool IsAccelerated() const = 0; virtual bool SupportsDirectCompositing() const = 0; + virtual bool SupportsSingleBuffering() const { return false; } uint32_t ContentUniqueID() const; CanvasResourceDispatcher* ResourceDispatcher() { return resource_dispatcher_.get(); } + // Indicates that the compositing path is single buffered, meaning that + // ProduceFrame() return a reference to the same resource each time, which + // implies that Producing an animation frame may overwrite the resource used + // by the previous frame. This results in graphics updates skipping the + // queue, thus reducing latency, but with the possible side effects of + // tearring (in cases where the resource is scanned out directly) and + // irregular frame rate. + bool IsSingleBuffered() { return is_single_buffered_; } + + // Attempt to enable single buffering mode on this resource provider. May + // fail if the CanvasResourcePRovider subclass does not support this mode of + // operation. + void TryEnableSingleBuffering(); + void RecycleResource(scoped_refptr<CanvasResource>); void SetResourceRecyclingEnabled(bool); void ClearRecycledResources(); @@ -189,6 +204,9 @@ WTF::Vector<scoped_refptr<CanvasResource>> recycled_resources_; bool resource_recycling_enabled_ = true; + bool is_single_buffered_ = false; + scoped_refptr<CanvasResource> single_buffer_; + base::WeakPtrFactory<CanvasResourceProvider> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(CanvasResourceProvider);
diff --git a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc index 2db3ef5..a0ace7b 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
@@ -30,24 +30,24 @@ } void XRFrameTransport::SetTransportOptions( - device::mojom::blink::VRDisplayFrameTransportOptionsPtr transport_options) { + device::mojom::blink::XRPresentationTransportOptionsPtr transport_options) { transport_options_ = std::move(transport_options); } void XRFrameTransport::BindSubmitFrameClient( - device::mojom::blink::VRSubmitFrameClientRequest request) { + device::mojom::blink::XRPresentationClientRequest request) { submit_frame_client_binding_.Close(); submit_frame_client_binding_.Bind(std::move(request)); } bool XRFrameTransport::DrawingIntoSharedBuffer() { switch (transport_options_->transport_method) { - case device::mojom::blink::VRDisplayFrameTransportMethod:: + case device::mojom::blink::XRPresentationTransportMethod:: SUBMIT_AS_TEXTURE_HANDLE: - case device::mojom::blink::VRDisplayFrameTransportMethod:: + case device::mojom::blink::XRPresentationTransportMethod:: SUBMIT_AS_MAILBOX_HOLDER: return false; - case device::mojom::blink::VRDisplayFrameTransportMethod:: + case device::mojom::blink::XRPresentationTransportMethod:: DRAW_INTO_TEXTURE_MAILBOX: return true; default: @@ -85,7 +85,7 @@ } void XRFrameTransport::FrameSubmitMissing( - device::mojom::blink::VRPresentationProvider* vr_presentation_provider, + device::mojom::blink::XRPresentationProvider* vr_presentation_provider, gpu::gles2::GLES2Interface* gl, int16_t vr_frame_id) { TRACE_EVENT0("gpu", __FUNCTION__); @@ -95,7 +95,7 @@ } void XRFrameTransport::FrameSubmit( - device::mojom::blink::VRPresentationProvider* vr_presentation_provider, + device::mojom::blink::XRPresentationProvider* vr_presentation_provider, gpu::gles2::GLES2Interface* gl, DrawingBuffer::Client* drawing_buffer_client, scoped_refptr<Image> image_ref, @@ -105,7 +105,7 @@ DCHECK(transport_options_); if (transport_options_->transport_method == - device::mojom::blink::VRDisplayFrameTransportMethod:: + device::mojom::blink::XRPresentationTransportMethod:: SUBMIT_AS_TEXTURE_HANDLE) { #if defined(OS_WIN) // Currently, we assume that this transport needs a copy. @@ -143,7 +143,7 @@ NOTIMPLEMENTED(); #endif } else if (transport_options_->transport_method == - device::mojom::blink::VRDisplayFrameTransportMethod:: + device::mojom::blink::XRPresentationTransportMethod:: SUBMIT_AS_MAILBOX_HOLDER) { // Currently, this transport assumes we don't need to make a separate copy // of the canvas content. @@ -188,7 +188,7 @@ frame_wait_time_); TRACE_EVENT_END0("gpu", "XRFrameTransport::SubmitFrame"); } else if (transport_options_->transport_method == - device::mojom::blink::VRDisplayFrameTransportMethod:: + device::mojom::blink::XRPresentationTransportMethod:: DRAW_INTO_TEXTURE_MAILBOX) { TRACE_EVENT0("gpu", "XRFrameTransport::SubmitFrameDrawnIntoTexture"); gpu::SyncToken sync_token;
diff --git a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h index 1af00bce..57dc839 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h +++ b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
@@ -30,25 +30,25 @@ class PLATFORM_EXPORT XRFrameTransport final : public GarbageCollectedFinalized<XRFrameTransport>, - public device::mojom::blink::VRSubmitFrameClient { + public device::mojom::blink::XRPresentationClient { public: explicit XRFrameTransport(); ~XRFrameTransport() override; void BindSubmitFrameClient( - device::mojom::blink::VRSubmitFrameClientRequest request); + device::mojom::blink::XRPresentationClientRequest request); void PresentChange(); void SetTransportOptions( - device::mojom::blink::VRDisplayFrameTransportOptionsPtr); + device::mojom::blink::XRPresentationTransportOptionsPtr); bool DrawingIntoSharedBuffer(); // Call before finalizing the frame's image snapshot. void FramePreImage(gpu::gles2::GLES2Interface*); - void FrameSubmit(device::mojom::blink::VRPresentationProvider*, + void FrameSubmit(device::mojom::blink::XRPresentationProvider*, gpu::gles2::GLES2Interface*, DrawingBuffer::Client*, scoped_refptr<Image> image_ref, @@ -56,7 +56,7 @@ int16_t vr_frame_id, bool needs_copy); - void FrameSubmitMissing(device::mojom::blink::VRPresentationProvider*, + void FrameSubmitMissing(device::mojom::blink::XRPresentationProvider*, gpu::gles2::GLES2Interface*, int16_t vr_frame_id); @@ -68,12 +68,12 @@ WTF::TimeDelta WaitForGpuFenceReceived(); void CallPreviousFrameCallback(); - // VRSubmitFrameClient + // XRPresentationClient void OnSubmitFrameTransferred(bool success) override; void OnSubmitFrameRendered() override; void OnSubmitFrameGpuFence(const gfx::GpuFenceHandle&) override; - mojo::Binding<device::mojom::blink::VRSubmitFrameClient> + mojo::Binding<device::mojom::blink::XRPresentationClient> submit_frame_client_binding_; // Used to keep the image alive until the next frame if using @@ -91,7 +91,7 @@ bool waiting_for_previous_frame_fence_ = false; std::unique_ptr<gfx::GpuFence> previous_frame_fence_; - device::mojom::blink::VRDisplayFrameTransportOptionsPtr transport_options_; + device::mojom::blink::XRPresentationTransportOptionsPtr transport_options_; std::unique_ptr<GpuMemoryBufferImageCopy> frame_copier_; };
diff --git a/third_party/blink/renderer/platform/heap/gc_info.cc b/third_party/blink/renderer/platform/heap/gc_info.cc index 1033c65..6c515bc 100644 --- a/third_party/blink/renderer/platform/heap/gc_info.cc +++ b/third_party/blink/renderer/platform/heap/gc_info.cc
@@ -49,7 +49,7 @@ } void GCInfoTable::EnsureGCInfoIndex(const GCInfo* gc_info, - size_t* gc_info_index_slot) { + uint32_t* gc_info_index_slot) { DCHECK(gc_info); DCHECK(gc_info_index_slot); @@ -64,14 +64,13 @@ if (*gc_info_index_slot) return; - int index = ++current_index_; - size_t gc_info_index = static_cast<size_t>(index); + uint32_t gc_info_index = ++current_index_; CHECK(gc_info_index < GCInfoTable::kMaxIndex); if (current_index_ >= limit_) Resize(); table_[gc_info_index] = gc_info; - ReleaseStore(reinterpret_cast<int*>(gc_info_index_slot), index); + ReleaseStore(gc_info_index_slot, gc_info_index); } void GCInfoTable::Resize() {
diff --git a/third_party/blink/renderer/platform/heap/gc_info.h b/third_party/blink/renderer/platform/heap/gc_info.h index b6e7e42..a5c138e 100644 --- a/third_party/blink/renderer/platform/heap/gc_info.h +++ b/third_party/blink/renderer/platform/heap/gc_info.h
@@ -44,7 +44,7 @@ }; #if DCHECK_IS_ON() -PLATFORM_EXPORT void AssertObjectHasGCInfo(const void*, size_t gc_info_index); +PLATFORM_EXPORT void AssertObjectHasGCInfo(const void*, uint32_t gc_info_index); #endif class PLATFORM_EXPORT GCInfoTable { @@ -56,14 +56,14 @@ // of the Oilpan GC Clang plugin, there appear to be at most about 6,000 // types. Thus 14 bits should be more than twice as many bits as we will ever // need. - static constexpr size_t kMaxIndex = 1 << 14; + static constexpr uint32_t kMaxIndex = 1 << 14; // Sets up a singleton table that can be acquired using Get(). static void CreateGlobalTable(); static GCInfoTable& Get() { return *global_table_; } - inline const GCInfo* GCInfoFromIndex(size_t index) { + inline const GCInfo* GCInfoFromIndex(uint32_t index) { DCHECK_GE(index, 1u); DCHECK(index < kMaxIndex); DCHECK(table_); @@ -72,9 +72,9 @@ return info; } - void EnsureGCInfoIndex(const GCInfo*, size_t*); + void EnsureGCInfoIndex(const GCInfo*, uint32_t*); - size_t GcInfoIndex() { return current_index_; } + uint32_t GcInfoIndex() { return current_index_; } private: FRIEND_TEST_ALL_PREFIXES(GCInfoTest, InitialEmpty); @@ -95,10 +95,10 @@ // GCInfo indices start from 1 for heap objects, with 0 being treated // specially as the index for freelist entries and large heap objects. - size_t current_index_ = 0; + uint32_t current_index_ = 0; // The limit (exclusive) of the currently allocated table. - size_t limit_ = 0; + uint32_t limit_ = 0; Mutex table_mutex_; }; @@ -108,14 +108,14 @@ template <typename T> struct GCInfoAtBaseType { STATIC_ONLY(GCInfoAtBaseType); - static size_t Index() { + static uint32_t Index() { static_assert(sizeof(T), "T must be fully defined"); static const GCInfo kGcInfo = { TraceTrait<T>::Trace, FinalizerTrait<T>::Finalize, NameTrait<T>::GetName, FinalizerTrait<T>::kNonTrivialFinalizer, std::is_polymorphic<T>::value, }; - static size_t gc_info_index = 0; + static uint32_t gc_info_index = 0; if (!AcquireLoad(&gc_info_index)) GCInfoTable::Get().EnsureGCInfoIndex(&kGcInfo, &gc_info_index); DCHECK_GE(gc_info_index, 1u); @@ -144,7 +144,7 @@ template <typename T> struct GCInfoTrait { STATIC_ONLY(GCInfoTrait); - static size_t Index() { + static uint32_t Index() { return GCInfoAtBaseType<typename GetGarbageCollectedType<T>::type>::Index(); } };
diff --git a/third_party/blink/renderer/platform/heap/gc_info_test.cc b/third_party/blink/renderer/platform/heap/gc_info_test.cc index d651be0..6447fc31 100644 --- a/third_party/blink/renderer/platform/heap/gc_info_test.cc +++ b/third_party/blink/renderer/platform/heap/gc_info_test.cc
@@ -16,8 +16,8 @@ TEST(GCInfoTest, ResizeToMaxIndex) { GCInfoTable table; GCInfo info = {nullptr, nullptr, nullptr, false, false}; - size_t slot = 0; - for (size_t i = 0; i < (GCInfoTable::kMaxIndex - 1); i++) { + uint32_t slot = 0; + for (uint32_t i = 0; i < (GCInfoTable::kMaxIndex - 1); i++) { slot = 0; table.EnsureGCInfoIndex(&info, &slot); EXPECT_LT(0u, slot);
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc index 7688dfb5..cd4d676 100644 --- a/third_party/blink/renderer/platform/heap/heap.cc +++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -430,8 +430,8 @@ return arena_index_with_min_arena_age; } -BaseArena* ThreadHeap::ExpandedVectorBackingArena(size_t gc_info_index) { - size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask; +BaseArena* ThreadHeap::ExpandedVectorBackingArena(uint32_t gc_info_index) { + uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask; --likely_to_be_promptly_freed_[entry_index]; int arena_index = vector_backing_arena_index_; arena_ages_[arena_index] = ++current_arena_ages_; @@ -448,9 +448,9 @@ } } -void ThreadHeap::PromptlyFreed(size_t gc_info_index) { +void ThreadHeap::PromptlyFreed(uint32_t gc_info_index) { DCHECK(thread_state_->CheckThread()); - size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask; + uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask; // See the comment in vectorBackingArena() for why this is +3. likely_to_be_promptly_freed_[entry_index] += 3; } @@ -550,7 +550,7 @@ size_t total_dead_count = 0; size_t total_live_size = 0; size_t total_dead_size = 0; - for (size_t gc_info_index = 1; + for (uint32_t gc_info_index = 1; gc_info_index <= GCInfoTable::Get().GcInfoIndex(); ++gc_info_index) { total_live_count += info.live_count[gc_info_index]; total_dead_count += info.dead_count[gc_info_index];
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h index 1623c418..8f55a62a 100644 --- a/third_party/blink/renderer/platform/heap/heap.h +++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -280,7 +280,7 @@ Address AllocateOnArenaIndex(ThreadState*, size_t, int arena_index, - size_t gc_info_index, + uint32_t gc_info_index, const char* type_name); template <typename T> static Address Allocate(size_t, bool eagerly_sweep = false); @@ -350,9 +350,9 @@ // (*) More than 33% of the same type of vectors have been promptly // freed since the last GC. // - BaseArena* VectorBackingArena(size_t gc_info_index) { + BaseArena* VectorBackingArena(uint32_t gc_info_index) { DCHECK(thread_state_->CheckThread()); - size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask; + uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask; --likely_to_be_promptly_freed_[entry_index]; int arena_index = vector_backing_arena_index_; // If likely_to_be_promptly_freed_[entryIndex] > 0, that means that @@ -367,14 +367,14 @@ DCHECK(IsVectorArenaIndex(arena_index)); return arenas_[arena_index]; } - BaseArena* ExpandedVectorBackingArena(size_t gc_info_index); + BaseArena* ExpandedVectorBackingArena(uint32_t gc_info_index); static bool IsVectorArenaIndex(int arena_index) { return BlinkGC::kVector1ArenaIndex <= arena_index && arena_index <= BlinkGC::kVector4ArenaIndex; } static bool IsNormalArenaIndex(int); void AllocationPointAdjusted(int arena_index); - void PromptlyFreed(size_t gc_info_index); + void PromptlyFreed(uint32_t gc_info_index); void ClearArenaAges(); int ArenaIndexOfVectorArenaLeastRecentlyExpanded(int begin_arena_index, int end_arena_index); @@ -602,7 +602,7 @@ inline Address ThreadHeap::AllocateOnArenaIndex(ThreadState* state, size_t size, int arena_index, - size_t gc_info_index, + uint32_t gc_info_index, const char* type_name) { DCHECK(state->IsAllocationAllowed()); DCHECK_NE(arena_index, BlinkGC::kLargeObjectArenaIndex); @@ -651,7 +651,7 @@ arena_index = ArenaIndexForObjectSize(size); } - size_t gc_info_index = GCInfoTrait<T>::Index(); + uint32_t gc_info_index = GCInfoTrait<T>::Index(); // TODO(haraken): We don't support reallocate() for finalizable objects. DCHECK(!GCInfoTable::Get() .GCInfoFromIndex(previous_header->GcInfoIndex())
diff --git a/third_party/blink/renderer/platform/heap/heap_allocator.h b/third_party/blink/renderer/platform/heap/heap_allocator.h index ab841704..e69c0df 100644 --- a/third_party/blink/renderer/platform/heap/heap_allocator.h +++ b/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -72,7 +72,7 @@ ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); DCHECK(state->IsAllocationAllowed()); - size_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index(); + uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index(); NormalPageArena* arena = static_cast<NormalPageArena*>( state->Heap().VectorBackingArena(gc_info_index)); return reinterpret_cast<T*>(arena->AllocateObject( @@ -83,7 +83,7 @@ ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); DCHECK(state->IsAllocationAllowed()); - size_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index(); + uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index(); NormalPageArena* arena = static_cast<NormalPageArena*>( state->Heap().ExpandedVectorBackingArena(gc_info_index)); return reinterpret_cast<T*>(arena->AllocateObject( @@ -96,7 +96,7 @@ size_t quantized_shrunk_size); template <typename T> static T* AllocateInlineVectorBacking(size_t size) { - size_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index(); + uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index(); ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(HeapVectorBacking<T>); @@ -112,7 +112,7 @@ template <typename T, typename HashTable> static T* AllocateHashTableBacking(size_t size) { - size_t gc_info_index = + uint32_t gc_info_index = GCInfoTrait<HeapHashTableBacking<HashTable>>::Index(); ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc index 47b4c3d..07ae942 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.cc +++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -1646,14 +1646,14 @@ live_count++; live_size += header->size(); - size_t gc_info_index = header->GcInfoIndex(); + uint32_t gc_info_index = header->GcInfoIndex(); info.live_count[gc_info_index]++; info.live_size[gc_info_index] += header->size(); } else { dead_count++; dead_size += header->size(); - size_t gc_info_index = header->GcInfoIndex(); + uint32_t gc_info_index = header->GcInfoIndex(); info.dead_count[gc_info_index]++; info.dead_size[gc_info_index] += header->size(); } @@ -1730,7 +1730,7 @@ size_t live_count = 0; size_t dead_count = 0; HeapObjectHeader* header = ObjectHeader(); - size_t gc_info_index = header->GcInfoIndex(); + uint32_t gc_info_index = header->GcInfoIndex(); size_t payload_size = header->PayloadSize(); if (header->IsMarked()) { live_count = 1;
diff --git a/third_party/blink/renderer/platform/heap/heap_page.h b/third_party/blink/renderer/platform/heap/heap_page.h index b6977736..2bc6d7c 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.h +++ b/third_party/blink/renderer/platform/heap/heap_page.h
@@ -194,7 +194,7 @@ size_t size() const; - NO_SANITIZE_ADDRESS size_t GcInfoIndex() const { + NO_SANITIZE_ADDRESS uint32_t GcInfoIndex() const { return (encoded_ & kHeaderGCInfoIndexMask) >> kHeaderGCInfoIndexShift; }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 5da92de..5a7e167 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1118,6 +1118,9 @@ name: "RTCUnifiedPlanByDefault", }, { + name: "ScheduledScriptStreaming", + }, + { name: "ScriptedSpeech", status: "stable", },
diff --git a/third_party/blink/renderer/platform/scheduler/DEPS b/third_party/blink/renderer/platform/scheduler/DEPS index c8e9a1cd..749a0a1 100644 --- a/third_party/blink/renderer/platform/scheduler/DEPS +++ b/third_party/blink/renderer/platform/scheduler/DEPS
@@ -39,6 +39,7 @@ "+base/task/sequence_manager/sequence_manager.h", "+base/task/sequence_manager/task_queue.h", "+base/task/sequence_manager/time_domain.h", + "+base/task_scheduler/task_traits.h", "+base/threading/platform_thread.h", "+base/threading/sequenced_task_runner_handle.h", "+base/threading/thread.h",
diff --git a/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc b/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc index 18d898e3..5337518 100644 --- a/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc
@@ -11,8 +11,16 @@ void BackgroundScheduler::PostOnBackgroundThread(const base::Location& location, CrossThreadClosure closure) { - base::PostTaskWithTraits(location, - {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + PostOnBackgroundThreadWithTraits( + location, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + std::move(closure)); +} + +void BackgroundScheduler::PostOnBackgroundThreadWithTraits( + const base::Location& location, + const base::TaskTraits& traits, + CrossThreadClosure closure) { + base::PostTaskWithTraits(location, traits, ConvertToBaseCallback(std::move(closure))); }
diff --git a/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h index ef80a0a..57bffd3 100644 --- a/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h
@@ -6,6 +6,8 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_BACKGROUND_SCHEDULER_H_ #include "base/location.h" +#include "base/sequenced_task_runner.h" +#include "base/task_scheduler/task_traits.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -13,14 +15,22 @@ namespace BackgroundScheduler { -// This is a thin wrapper around base::TaskScheduler to accomodate -// Blink's CrossThreadClosure, which only allows background tasks. +// These are a thin wrapper around base::TaskScheduler to accomodate +// Blink's CrossThreadClosure, which only allows background tasks +// (i.e. tasks which are run off the main thread). // // Non-background tasks should be posted using another scheduler, e.g. // FrameShceduler. PLATFORM_EXPORT void PostOnBackgroundThread(const base::Location&, CrossThreadClosure); +PLATFORM_EXPORT void PostOnBackgroundThreadWithTraits(const base::Location&, + const base::TaskTraits&, + CrossThreadClosure); + +// TODO(altimin): Expose CreateBackgroundTaskRunnerWithTraits when the +// need arises. + } // namespace BackgroundScheduler } // namespace blink
diff --git a/third_party/blink/renderer/platform/wtf/allocator/partitions.h b/third_party/blink/renderer/platform/wtf/allocator/partitions.h index 079afd0..8ee8698e 100644 --- a/third_party/blink/renderer/platform/wtf/allocator/partitions.h +++ b/third_party/blink/renderer/platform/wtf/allocator/partitions.h
@@ -101,6 +101,11 @@ const char* type_name) { return BufferPartition()->Realloc(p, n, type_name); } + ALWAYS_INLINE static void* BufferTryRealloc(void* p, + size_t n, + const char* type_name) { + return BufferPartition()->TryRealloc(p, n, type_name); + } ALWAYS_INLINE static void BufferFree(void* p) { BufferPartition()->Free(p); } ALWAYS_INLINE static size_t BufferActualSize(size_t n) { return BufferPartition()->ActualSize(n);
diff --git a/third_party/blink/tools/audit_non_blink_usage.py b/third_party/blink/tools/audit_non_blink_usage.py index 0b33cd7..aa4e0c1 100755 --- a/third_party/blink/tools/audit_non_blink_usage.py +++ b/third_party/blink/tools/audit_non_blink_usage.py
@@ -118,6 +118,13 @@ # Base atomic utilities 'base::AtomicSequenceNumber', + # Task traits + 'base::TaskTraits', + 'base::MayBlock', + 'base::TaskPriority', + 'base::TaskShutdownBehavior', + 'base::WithBaseSyncPrimitives', + # Byte order 'base::ByteSwap', 'base::NetToHost(16|32|64)',
diff --git a/tools/binary_size/libsupersize/gsutil.py b/tools/binary_size/libsupersize/gsutil.py new file mode 100644 index 0000000..855517b --- /dev/null +++ b/tools/binary_size/libsupersize/gsutil.py
@@ -0,0 +1,67 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Update the Google Cloud Storage bucket hosting the Super Size UI.""" + +import argparse +import os +import subprocess +import uuid + + +GS_BUCKET = 'gs://chrome-supersize' + + +def _SyncStatic(): + """Upload static files from the static directory.""" + static_files = os.path.join(os.path.dirname(__file__), 'static') + subprocess.check_call([ + 'gsutil.py', '-m', 'rsync', '-r', static_files, GS_BUCKET + ]) + + +def _SyncTemplates(): + """Generate and upload the templates/sw.js file.""" + template_file = os.path.join(os.path.dirname(__file__), 'templates', 'sw.js') + cache_hash = uuid.uuid4().hex + + p = subprocess.Popen([ + 'gsutil.py', 'cp', '-p', '-', '%s/sw.js' % GS_BUCKET + ], stdin=subprocess.PIPE) + with open(template_file, 'r') as in_file: + p.communicate(in_file.read().replace('{{cache_hash}}', cache_hash)) + + +def _SetMetaAndPermissions(): + # sw.js has the wrong type due to being created from a stream + subprocess.check_call([ + 'gsutil.py', 'setmeta', '-h', 'Content-Type:application/javascript', + '%s/sw.js' % GS_BUCKET + ]) + subprocess.check_call([ + 'gsutil.py', '-m', 'setmeta', '-h', 'Content-Type:application/x-ndjson', + '%s/milestones/*.ndjson' % GS_BUCKET + ]) + + # All files in the root of the bucket are user readable + subprocess.check_call([ + 'gsutil.py', '-m', 'acl', 'ch', '-u', 'AllUsers:R', '%s/*' % GS_BUCKET + ]) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--sync', action='store_true', required=True, + help='Sync static and template files to GCS.') + + args = parser.parse_args() + + if args.sync: + _SyncStatic() + _SyncTemplates() + _SetMetaAndPermissions() + + +if __name__ == '__main__': + main()
diff --git a/tools/binary_size/libsupersize/static/index.html b/tools/binary_size/libsupersize/static/index.html index eb6187e..9e176e1 100644 --- a/tools/binary_size/libsupersize/static/index.html +++ b/tools/binary_size/libsupersize/static/index.html
@@ -7,9 +7,10 @@ --> <head> - <title>Binary Size Analysis</title> + <title>Super Size Tiger View</title> <script src="start-worker.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="theme-color" content="#4285f4"> <link href="https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,500" rel="stylesheet"> <style> body { @@ -205,17 +206,23 @@ </style> <link rel="stylesheet" href="options.css"> <link rel="icon" href="favicon.ico" sizes="16x16 32x32 256x256" type="image/x-icon"> + <link rel="manifest" href="manifest.json"> <script defer src="shared.js"></script> <script defer src="state.js"></script> <script defer src="infocard-ui.js"></script> <script defer src="tree-ui.js"></script> + <script defer async> + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('sw.js'); + } + </script> </head> <body> <div class="scrim toggle-options" hidden></div> <header class="appbar"> <div class="appbar-inner"> - <h1 class="headline">Binary Size Analysis</h1> + <h1 class="headline">Super Size Tiger View</h1> <input type="file" name="upload" id="upload" accept=".ndjson" > <label for="upload" class="text-button filled-button with-icon"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="#fff">
diff --git a/tools/binary_size/libsupersize/static/manifest.json b/tools/binary_size/libsupersize/static/manifest.json new file mode 100644 index 0000000..355e862 --- /dev/null +++ b/tools/binary_size/libsupersize/static/manifest.json
@@ -0,0 +1,22 @@ +{ + "short_name": "Super Size", + "name": "Super Size Tiger View", + "description": "View interactive size breakdowns from Chrome", + "icons": [ + { + "src": "favicon.ico", + "sizes": "16x16 32x32 256x256" + }, + { + "src": "splash.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "lang": "en", + "start_url": "index.html", + "background_color": "#fff", + "display": "standalone", + "scope": "./", + "theme_color": "#4285f4" +}
diff --git a/tools/binary_size/libsupersize/static/options.css b/tools/binary_size/libsupersize/static/options.css index f627327..2fa0185b 100644 --- a/tools/binary_size/libsupersize/static/options.css +++ b/tools/binary_size/libsupersize/static/options.css
@@ -34,7 +34,7 @@ position: fixed; right: 0; top: 0; - height: 100vh; + bottom: 0; width: 224px; background: #fffffff5; box-shadow: 0 1px 2px #3c40434d, 0 2px 6px 2px #3c404326; @@ -306,15 +306,11 @@ .symbols { padding: 0 16px; } - .appbar-progress { - margin: 0 -16px; - width: calc(100% + 32px); - } - .filled-button { + .text-button.with-icon { padding-right: 6px; } - .filled-button .label-text { + .text-button.with-icon .label-text { display: none; } }
diff --git a/tools/binary_size/libsupersize/static/splash.png b/tools/binary_size/libsupersize/static/splash.png new file mode 100644 index 0000000..db8d5f8 --- /dev/null +++ b/tools/binary_size/libsupersize/static/splash.png Binary files differ
diff --git a/tools/binary_size/libsupersize/templates/sw.js b/tools/binary_size/libsupersize/templates/sw.js new file mode 100644 index 0000000..6807eed --- /dev/null +++ b/tools/binary_size/libsupersize/templates/sw.js
@@ -0,0 +1,51 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// @ts-check +'use strict'; + +const cacheName = '{{cache_hash}}'; +const filesToCache = [ + 'favicon.ico', + 'index.html', + 'infocard-ui.js', + 'infocard.css', + 'manifest.json', + 'options.css', + 'shared.js', + 'start-worker.js', + 'state.js', + 'tree-ui.js', + 'tree-worker.js', +]; + +// On install, cache the items in the `filesToCache` list +self.addEventListener('install', event => { + event.waitUntil( + caches.open(cacheName).then(cache => cache.addAll(filesToCache)) + ); +}); + +// On activate, remove any old caches +self.addEventListener('activate', event => { + async function deleteOldCache(key) { + if (key !== cacheName) { + return caches.delete(key); + } + } + + event.waitUntil( + caches.keys().then(keyList => Promise.all(keyList.map(deleteOldCache))) + ); + return self.clients.claim(); +}); + +// On fetch, return entries from the cache if possible +self.addEventListener('fetch', event => { + event.respondWith( + caches + .match(event.request, {ignoreSearch: true}) + .then(response => response || fetch(event.request)) + ); +});
diff --git a/tools/cygprofile/phased_orderfile.py b/tools/cygprofile/phased_orderfile.py index 73bb234..ac0d27fb 100755 --- a/tools/cygprofile/phased_orderfile.py +++ b/tools/cygprofile/phased_orderfile.py
@@ -13,6 +13,13 @@ orderfile with three parts: the code touched only in startup, the code touched only during interaction, and code common to the two phases. We refer to these parts as the orderfile phases. + +Example invocation, with PROFILE_DIR the location of the profile data pulled +from a device and LIBTYPE either monochrome or chrome as appropriate. +./tools/cygprofile/phased_orderfile.py \ + --profile-directory=PROFILE_DIR \ + --instrumented-build-dir=out-android/Orderfile/ \ + --library-name=libLIBTYPE.so --offset-output-base=PROFILE_DIR/offset """ import argparse @@ -26,7 +33,7 @@ # Files matched when using this script to analyze directly (see main()). -PROFILE_GLOB = 'cygprofile-*.txt_*' +PROFILE_GLOB = 'profile-hitmap-*.txt_*' OrderfilePhaseOffsets = collections.namedtuple( @@ -45,6 +52,9 @@ COMMON_STABILITY_THRESHOLD = 1.75 INTERACTION_STABILITY_THRESHOLD = 2.5 + # The process name of the browser as used in the profile dumps. + BROWSER = 'browser' + def __init__(self, profiles, processor): """Intialize. @@ -54,7 +64,11 @@ """ self._profiles = profiles self._processor = processor + + # These members cache various computed values. self._phase_offsets = None + self._annotated_offsets = None + self._process_list = None def IsStableProfile(self): """Verify that the profiling has been stable. @@ -65,7 +79,7 @@ True if the profile was stable as described above. """ (startup_stability, common_stability, - interaction_stability) = self.ComputeStability() + interaction_stability) = [s[0] for s in self.ComputeStability()] stable = True if startup_stability > self.STARTUP_STABILITY_THRESHOLD: @@ -89,11 +103,46 @@ they cover. Returns: - (float, float, float) A heuristic stability metric for startup, common and - interaction orderfile phases, respectively. + ((float, int), (float, int), (float, int)) A heuristic stability metric + for startup, common and interaction orderfile phases, + respectively. Each metric is a pair of the ratio of symbol sizes as + described above, and the size of the intersection. + """ + (startup_intersection, startup_union, + common_intersection, common_union, + interaction_intersection, interaction_union, + _, _) = self.GetCombinedOffsets() + startup_intersection_size = self._processor.OffsetsPrimarySize( + startup_intersection) + common_intersection_size = self._processor.OffsetsPrimarySize( + common_intersection) + interaction_intersection_size = self._processor.OffsetsPrimarySize( + interaction_intersection) + startup_stability = self._SafeDiv( + self._processor.OffsetsPrimarySize(startup_union), + startup_intersection_size) + common_stability = self._SafeDiv( + self._processor.OffsetsPrimarySize(common_union), + common_intersection_size) + interaction_stability = self._SafeDiv( + self._processor.OffsetsPrimarySize(interaction_union), + interaction_intersection_size) + return ((startup_stability, startup_intersection_size), + (common_stability, common_intersection_size), + (interaction_stability, interaction_intersection_size)) + + def GetCombinedOffsets(self): + """Get offsets for the union and intersection of orderfile phases. + + Returns: + ([int] * 8) For each of startup, common, interaction and all, respectively + the intersection and union offsets, in that order. """ phase_offsets = self._GetOrderfilePhaseOffsets() - assert len(phase_offsets) > 1 # Otherwise the analysis is silly. + assert phase_offsets + if len(phase_offsets) == 1: + logging.error('Only one run set, the combined offset files will all be ' + 'identical') startup_union = set(phase_offsets[0].startup) startup_intersection = set(phase_offsets[0].startup) @@ -108,16 +157,172 @@ common_intersection &= set(offsets.common) interaction_union |= set(offsets.interaction) interaction_intersection &= set(offsets.interaction) - startup_stability = self._SafeDiv( - self._processor.OffsetsPrimarySize(startup_union), - self._processor.OffsetsPrimarySize(startup_intersection)) - common_stability = self._SafeDiv( - self._processor.OffsetsPrimarySize(common_union), - self._processor.OffsetsPrimarySize(common_intersection)) - interaction_stability = self._SafeDiv( - self._processor.OffsetsPrimarySize(interaction_union), - self._processor.OffsetsPrimarySize(interaction_intersection)) - return (startup_stability, common_stability, interaction_stability) + return (startup_intersection, startup_union, + common_intersection, common_union, + interaction_intersection, interaction_union, + (startup_union & common_union & interaction_union), + (startup_union | common_union | interaction_union)) + + def GetOffsetsForMemoryFootprint(self): + """Get offsets organized to minimize the memory footprint. + + The startup, common and interaction offsets are computed for each + process. Any symbols used by one process in startup or interaction that are + used in a different phase by another process are moved to the common + section. This should minimize the memory footprint by keeping startup- or + interaction-only pages clean, at the possibly expense of startup time, as + more of the common section will need to be loaded. To mitigate that effect, + symbols moved from startup are placed at the beginning of the common + section, and those moved from interaction are placed at the end. + + Browser startup symbols are placed at the beginning of the startup section + in the hope of working out with native library prefetching to minimize + startup time. + + Returns: + OrdrerfilePhaseOffsets as described above. + """ + startup = [] + common_head = [] + common = [] + common_tail = [] + interaction = [] + + process_offsets = {p: self._GetCombinedProcessOffsets(p) + for p in self._GetProcessList()} + assert self.BROWSER in process_offsets.keys() + + any_startup = set() + any_interaction = set() + any_common = set() + for offsets in process_offsets.itervalues(): + any_startup |= set(offsets.startup) + any_interaction |= set(offsets.interaction) + any_common |= set(offsets.common) + + already_added = set() + # This helper function splits |offsets|, adding to |alternate| all offsets + # that are in |interfering| or are already known to be common, and otherwise + # adding to |target|. + def add_process_offsets(offsets, interfering, target, alternate): + for o in offsets: + if o in already_added: + continue + if o in interfering or o in any_common: + alternate.append(o) + else: + target.append(o) + already_added.add(o) + + # This helper updates |common| with new members of |offsets|. + def add_common_offsets(offsets): + for o in offsets: + if o not in already_added: + common.append(o) + already_added.add(o) + + add_process_offsets(process_offsets[self.BROWSER].startup, + any_interaction, startup, common_head) + add_process_offsets(process_offsets[self.BROWSER].interaction, + any_startup, interaction, common_tail) + add_common_offsets(process_offsets[self.BROWSER].common) + + for p in process_offsets: + if p == self.BROWSER: + continue + add_process_offsets(process_offsets[p].startup, + any_interaction, startup, common_head) + add_process_offsets(process_offsets[p].interaction, + any_startup, interaction, common_tail) + add_common_offsets(process_offsets[p].common) + + return OrderfilePhaseOffsets( + startup=startup, + common=(common_head + common + common_tail), + interaction=interaction) + + def GetOffsetsForStartup(self): + """Get offsets organized to minimize startup time. + + The startup, common and interaction offsets are computed for each + process. Any symbol used by one process in interaction that appears in a + different phase in another process is moved to common, but any symbol that + appears in startup for *any* process stays in startup. + + This should maximize startup performance at the expense of increasing the + memory footprint, as some startup symbols will not be able to page out. + + The startup symbols in the browser process appear first in the hope of + working out with native library prefetching to minimize startup time. + """ + startup = [] + common = [] + interaction = [] + already_added = set() + + process_offsets = {p: self._GetCombinedProcessOffsets(p) + for p in self._GetProcessList()} + startup.extend(process_offsets[self.BROWSER].startup) + already_added |= set(process_offsets[self.BROWSER].startup) + common.extend(process_offsets[self.BROWSER].common) + already_added |= set(process_offsets[self.BROWSER].common) + interaction.extend(process_offsets[self.BROWSER].interaction) + already_added |= set(process_offsets[self.BROWSER].interaction) + + for process, offsets in process_offsets.iteritems(): + if process == self.BROWSER: + continue + startup.extend(o for o in offsets.startup + if o not in already_added) + already_added |= set(offsets.startup) + common.extend(o for o in offsets.common + if o not in already_added) + already_added |= set(offsets.common) + interaction.extend(o for o in offsets.interaction + if o not in already_added) + already_added |= set(offsets.interaction) + + return OrderfilePhaseOffsets( + startup=startup, common=common, interaction=interaction) + + def _GetCombinedProcessOffsets(self, process): + """Combine offsets across runs for a particular process. + + Args: + process (str) The process to combine. + + Returns: + OrderfilePhaseOffsets, the startup, common and interaction offsets for the + process in question. The offsets are sorted arbitrarily. + """ + (startup, common, interaction) = ([], [], []) + assert self._profiles.GetPhases() == set([0,1]), 'Unexpected phases' + for o in self._GetAnnotatedOffsets(): + startup_count = o.Count(0, process) + interaction_count = o.Count(1, process) + if not startup_count and not interaction_count: + continue + if startup_count and interaction_count: + common.append(o.Offset()) + elif startup_count: + startup.append(o.Offset()) + else: + interaction.append(o.Offset()) + return OrderfilePhaseOffsets( + startup=startup, common=common, interaction=interaction) + + def _GetAnnotatedOffsets(self): + if self._annotated_offsets is None: + self._annotated_offsets = self._profiles.GetAnnotatedOffsets() + self._processor.TranslateAnnotatedSymbolOffsets(self._annotated_offsets) + return self._annotated_offsets + + def _GetProcessList(self): + if self._process_list is None: + self._process_list = set() + for o in self._GetAnnotatedOffsets(): + self._process_list.update(o.Processes()) + return self._process_list def _GetOrderfilePhaseOffsets(self): """Compute the phase offsets for each run. @@ -129,7 +334,8 @@ if self._phase_offsets is not None: return self._phase_offsets - assert self._profiles.GetPhases() == set([0, 1]), 'Unexpected phases' + assert self._profiles.GetPhases() == set([0, 1]), ( + 'Unexpected phases {}'.format(self._profiles.GetPhases())) self._phase_offsets = [] for first, second in zip(self._profiles.GetRunGroupOffsets(phase=0), self._profiles.GetRunGroupOffsets(phase=1)): @@ -175,10 +381,17 @@ help=('Directory containing profile runs. Files ' 'matching {} are used.'.format(PROFILE_GLOB))) parser.add_argument('--instrumented-build-dir', type=str, - help='Path to the instrumented build', required=True) + help='Path to the instrumented build (eg, out/Orderfile)', + required=True) parser.add_argument('--library-name', default='libchrome.so', help=('Chrome shared library name (usually libchrome.so ' 'or libmonochrome.so')) + parser.add_argument('--offset-output-base', default=None, type=str, + help=('If present, a base name to output offsets to. ' + 'No offsets are output if this is missing. The ' + 'base name is suffixed with _for_memory and ' + '_for_startup, corresponding to the two sets of ' + 'offsets produced.')) return parser @@ -186,12 +399,25 @@ logging.basicConfig(level=logging.INFO) parser = _CreateArgumentParser() args = parser.parse_args() - profiles = process_profiles.ProfileManager( - glob.glob(os.path.join(args.profile_directory, PROFILE_GLOB))) + profiles = process_profiles.ProfileManager(itertools.chain.from_iterable( + glob.glob(os.path.join(d, PROFILE_GLOB)) + for d in args.profile_directory.split(','))) processor = process_profiles.SymbolOffsetProcessor(os.path.join( args.instrumented_build_dir, 'lib.unstripped', args.library_name)) phaser = PhasedAnalyzer(profiles, processor) - print 'Stability: {:.2f} {:.2f} {:.2f}'.format(*phaser.ComputeStability()) + stability = phaser.ComputeStability() + print 'Stability: {:.2} {:.2} {:.2}'.format(*[s[0] for s in stability]) + print 'Sizes: {} {} {}'.format(*[s[1] for s in stability]) + if args.offset_output_base is not None: + for name, offsets in zip( + ['_for_memory', '_for_startup'], + [phaser.GetOffsetsForMemoryFootprint(), + phaser.GetOffsetsForStartup()]): + with file(args.offset_output_base + name, 'w') as output: + output.write('\n'.join( + str(i) for i in (offsets.startup + offsets.common + + offsets.interaction))) + output.write('\n') if __name__ == '__main__':
diff --git a/tools/cygprofile/phased_orderfile_unittest.py b/tools/cygprofile/phased_orderfile_unittest.py index f2209bf..6941f7f 100755 --- a/tools/cygprofile/phased_orderfile_unittest.py +++ b/tools/cygprofile/phased_orderfile_unittest.py
@@ -11,20 +11,47 @@ import phased_orderfile import process_profiles -from test_utils import (SimpleTestSymbol, +from test_utils import (ProfileFile, + SimpleTestSymbol, TestSymbolOffsetProcessor, TestProfileManager) -class Mod10Processor(object): +class Mod10Processor(process_profiles.SymbolOffsetProcessor): """A restricted mock for a SymbolOffsetProcessor. - This only implements GetReachedOffsetsFromDump, and works by mapping a dump - offset to offset - (offset % 10). If the dump offset is negative, it is marked - as not found. + This only implements {Translate,Get}ReacheOffsetsFromDump, and works by + mapping a dump offset to offset - (offset % 10). If the dump offset is + negative, it is marked as not found. """ - def GetReachedOffsetsFromDump(self, dump): - return [x - (x % 10) for x in dump if x >= 0] + def __init__(self): + super(Mod10Processor, self).__init__(None) + + def _TranslateReachedOffsetsFromDump(self, items, get, update): + for i in items: + x = get(i) + if x >= 0: + update(i, x - (x % 10)) + else: + update(i, None) + + +class IdentityProcessor(process_profiles.SymbolOffsetProcessor): + """A restricted mock for a SymbolOffsetProcessor. + + This only implements {Translate,Get}ReachedOffsetsFromDump, and maps the dump + offset to itself. If the dump offset is negative, it is marked as not found. + """ + def __init__(self): + super(IdentityProcessor, self).__init__(None) + + def _TranslateReachedOffsetsFromDump(self, items, get, update): + for i in items: + x = get(i) + if x >= 0: + update(i, x) + else: + update(i, None) class PhasedOrderfileTestCase(unittest.TestCase): @@ -32,11 +59,6 @@ def setUp(self): self._file_counter = 0 - def File(self, timestamp_sec, phase): - self._file_counter += 1 - return 'file-{}-{}.txt_{}'.format( - self._file_counter, timestamp_sec * 1000 * 1000 * 1000, phase) - def testProfileStability(self): symbols = [SimpleTestSymbol(str(i), i, 10) for i in xrange(20)] @@ -46,7 +68,8 @@ startup=s, common=c, interaction=i) phaser._phase_offsets = [opo(range(5), range(6, 10), range(11,15)), opo(range(4), range(6, 10), range(18, 20))] - self.assertEquals((1.25, 1, None), phaser.ComputeStability()) + self.assertEquals((1.25, 1, None), + tuple(s[0] for s in phaser.ComputeStability())) def testIsStable(self): symbols = [SimpleTestSymbol(str(i), i, 10) @@ -64,12 +87,12 @@ def testGetOrderfilePhaseOffsets(self): mgr = TestProfileManager({ - self.File(0, 0): [12, 21, -1, 33], - self.File(0, 1): [31, 49, 52], - self.File(100, 0): [113, 128], - self.File(200, 1): [132, 146], - self.File(300, 0): [19, 20, 32], - self.File(300, 1): [24, 39]}) + ProfileFile(0, 0): [12, 21, -1, 33], + ProfileFile(0, 1): [31, 49, 52], + ProfileFile(100, 0): [113, 128], + ProfileFile(200, 1): [132, 146], + ProfileFile(300, 0): [19, 20, 32], + ProfileFile(300, 1): [24, 39]}) phaser = phased_orderfile.PhasedAnalyzer(mgr, Mod10Processor()) opo = lambda s, c, i: phased_orderfile.OrderfilePhaseOffsets( startup=s, common=c, interaction=i) @@ -79,6 +102,47 @@ opo([10], [20, 30], [])], phaser._GetOrderfilePhaseOffsets()) + def testGetCombinedProcessOffsets(self): + mgr = TestProfileManager({ + ProfileFile(40, 0, ''): [1, 2, 3], + ProfileFile(50, 1, ''): [3, 4, 5], + ProfileFile(51, 0, 'renderer'): [2, 3, 6], + ProfileFile(51, 1, 'gpu-process'): [6, 7], + ProfileFile(70, 0, ''): [2, 8, 9], + ProfileFile(70, 1, ''): [9]}) + phaser = phased_orderfile.PhasedAnalyzer(mgr, IdentityProcessor()) + offsets = phaser._GetCombinedProcessOffsets('browser') + self.assertListEqual([1, 2, 8], sorted(offsets.startup)) + self.assertListEqual([4, 5], sorted(offsets.interaction)) + self.assertListEqual([3, 9], sorted(offsets.common)) + + offsets = phaser._GetCombinedProcessOffsets('gpu-process') + self.assertListEqual([], sorted(offsets.startup)) + self.assertListEqual([6, 7], sorted(offsets.interaction)) + self.assertListEqual([], sorted(offsets.common)) + + self.assertListEqual(['browser', 'gpu-process', 'renderer'], + sorted(phaser._GetProcessList())) + + def testGetOffsetVariations(self): + mgr = TestProfileManager({ + ProfileFile(40, 0, ''): [1, 2, 3], + ProfileFile(50, 1, ''): [3, 4, 5], + ProfileFile(51, 0, 'renderer'): [2, 3, 6], + ProfileFile(51, 1, 'gpu-process'): [6, 7], + ProfileFile(70, 0, ''): [2, 6, 8, 9], + ProfileFile(70, 1, ''): [9]}) + phaser = phased_orderfile.PhasedAnalyzer(mgr, IdentityProcessor()) + offsets = phaser.GetOffsetsForMemoryFootprint() + self.assertListEqual([1, 2, 8], offsets.startup) + self.assertListEqual([6, 3, 9], offsets.common) + self.assertListEqual([4, 5, 7], offsets.interaction) + + offsets = phaser.GetOffsetsForStartup() + self.assertListEqual([1, 2, 6, 8], offsets.startup) + self.assertListEqual([3, 9], offsets.common) + self.assertListEqual([4, 5, 7], offsets.interaction) + if __name__ == "__main__": unittest.main()
diff --git a/tools/cygprofile/process_profiles.py b/tools/cygprofile/process_profiles.py index a436ead..916750f6 100755 --- a/tools/cygprofile/process_profiles.py +++ b/tools/cygprofile/process_profiles.py
@@ -56,6 +56,7 @@ self._name_to_symbol = None self._offset_to_primary = None self._offset_to_symbols = None + self._offset_to_symbol_info = None def SymbolInfos(self): """The symbols associated with this processor's binary. @@ -152,24 +153,14 @@ Returns: [int] Reached symbol offsets. """ - dump_offset_to_symbol_info = self._GetDumpOffsetToSymbolInfo() - logging.info('Offset to Symbol size = %d', len(dump_offset_to_symbol_info)) - assert max(dump) / 4 <= len(dump_offset_to_symbol_info) - already_seen = set() reached_offsets = [] - reached_return_addresses_not_found = 0 - for dump_offset in dump: - symbol_info = dump_offset_to_symbol_info[dump_offset / 4] - if symbol_info is None: - reached_return_addresses_not_found += 1 - continue - if symbol_info.offset in already_seen: - continue - reached_offsets.append(symbol_info.offset) - already_seen.add(symbol_info.offset) - if reached_return_addresses_not_found: - logging.warning('%d return addresses don\'t map to any symbol', - reached_return_addresses_not_found) + already_seen = set() + def update(_, symbol_offset): + if symbol_offset is None or symbol_offset in already_seen: + return + reached_offsets.append(symbol_offset) + already_seen.add(symbol_offset) + self._TranslateReachedOffsetsFromDump(dump, lambda x: x, update) return reached_offsets def MatchSymbolNames(self, symbol_names): @@ -185,6 +176,52 @@ matched_names = our_symbol_names.intersection(set(symbol_names)) return [self.NameToSymbolMap()[n] for n in matched_names] + def TranslateAnnotatedSymbolOffsets(self, annotated_offsets): + """Merges offsets across run groups and translates to symbol offsets. + + Like GetReachedOffsetsFromDump, but works with AnnotatedOffsets. + + Args: + annotated_offsets (AnnotatedOffset iterable) List of annotated offsets, + eg from ProfileManager.GetAnnotatedOffsets(). This will be mutated to + translate raw offsets to symbol offsets. + """ + self._TranslateReachedOffsetsFromDump( + annotated_offsets, + lambda o: o.Offset(), + lambda o, symbol_offset: o.SetOffset(symbol_offset)) + + def _TranslateReachedOffsetsFromDump(self, items, get, update): + """Translate raw binary offsets to symbol offsets. + + See GetReachedOffsetsFromDump for details. This version calls + |get(i)| on each element |i| of |items|, then calls + |update(i, symbol_offset)| with the updated offset. If the offset is not + found, update will be called with None. + + Args: + items: (iterable) Items containing offsets. + get: (lambda item) As described above. + update: (lambda item, int) As described above. + """ + dump_offset_to_symbol_info = self._GetDumpOffsetToSymbolInfo() + logging.info('Offset to Symbol size = %d', len(dump_offset_to_symbol_info)) + reached_return_addresses_not_found = 0 + for i in items: + dump_offset = get(i) + idx = dump_offset / 4 + assert idx < len(dump_offset_to_symbol_info), ( + 'Dump offset out of binary range') + symbol_info = dump_offset_to_symbol_info[idx] + if symbol_info is None: + reached_return_addresses_not_found += 1 + update(i, None) + else: + update(i, symbol_info.offset) + if reached_return_addresses_not_found: + logging.warning('%d return addresses don\'t map to any symbol', + reached_return_addresses_not_found) + def _GetDumpOffsetToSymbolInfo(self): """Computes an array mapping each word in .text to a symbol. @@ -192,15 +229,16 @@ [symbol_extractor.SymbolInfo or None] For every 4 bytes of the .text section, maps it to a symbol, or None. """ - min_offset = min(s.offset for s in self.SymbolInfos()) - max_offset = max(s.offset + s.size for s in self.SymbolInfos()) - text_length_words = (max_offset - min_offset) / 4 - offset_to_symbol_info = [None for _ in xrange(text_length_words)] - for s in self.SymbolInfos(): - offset = s.offset - min_offset - for i in range(offset / 4, (offset + s.size) / 4): - offset_to_symbol_info[i] = s - return offset_to_symbol_info + if self._offset_to_symbol_info is None: + min_offset = min(s.offset for s in self.SymbolInfos()) + max_offset = max(s.offset + s.size for s in self.SymbolInfos()) + text_length_words = (max_offset - min_offset) / 4 + self._offset_to_symbol_info = [None for _ in xrange(text_length_words)] + for s in self.SymbolInfos(): + offset = s.offset - min_offset + for i in range(offset / 4, (offset + s.size) / 4): + self._offset_to_symbol_info[i] = s + return self._offset_to_symbol_info class ProfileManager(object): @@ -222,11 +260,11 @@ example the dump for the startup could be phase 0 and then the steady-state would be labeled phase 1. - We assume the files are named like *-TIMESTAMP.SUFFIX_PHASE, where TIMESTAMP - is in nanoseconds, SUFFIX is string without dashes, PHASE is an integer - numbering the phases as 0, 1, 2..., and the only dot is the one between - TIMESTAMP and SUFFIX. Note that the current dump filename also includes a - process id which is currently unused. + We assume the files are named like + profile-hitmap-PROCESS-PID-TIMESTAMP.SUFFIX_PHASE, where PROCESS is a possibly + empty string, PID is the process id, TIMESTAMP is in nanoseconds, SUFFIX is + string without dashes, PHASE is an integer numbering the phases as 0, 1, 2..., + and the only dot is the one between TIMESTAMP and SUFFIX. This manager supports several configurations of dumps. @@ -242,6 +280,44 @@ time. This files can be grouped into run sets that are within 30 seconds of each other. Each run set is then grouped into phases as before. """ + class AnnotatedOffset(object): + """Describes an offset with how it appeared in a profile set. + + Each offset is annotated with the phase and process that it appeared in, and + can report how often it occurred in a specific phase and process. + """ + def __init__(self, offset): + self._offset = offset + self._count = {} + + def __str__(self): + return '{}: {}'.format(self._offset, self._count) + + def __eq__(self, other): + if other is None: + return False + return (self._offset == other._offset and + self._count == other._count) + + def Increment(self, phase, process): + key = (phase, process) + self._count[key] = self._count.setdefault(key, 0) + 1 + + def Count(self, phase, process): + return self._count.get((phase, process), 0) + + def Processes(self): + return set(k[1] for k in self._count.iterkeys()) + + def Phases(self): + return set(k[0] for k in self._count.iterkeys()) + + def Offset(self): + return self._offset + + def SetOffset(self, o): + self._offset = o + class _RunGroup(object): RUN_GROUP_THRESHOLD_NS = 30e9 @@ -295,6 +371,22 @@ return self._GetOffsetsForGroup(f for f in self._filenames if self._Phase(f) == phase) + def GetAnnotatedOffsets(self): + """Merges offsets across run groups and annotates each one. + + Returns: + [AnnotatedOffset] + """ + offset_map = {} # offset int -> AnnotatedOffset + for g in self._GetRunGroups(): + for f in g: + phase = self._Phase(f) + process = self._ProcessName(f) + for offset in self._ReadOffsets(f): + offset_map.setdefault(offset, self.AnnotatedOffset(offset)).Increment( + phase, process) + return offset_map.values() + def GetRunGroupOffsets(self, phase=None): """Merges files from each run group and returns offset list for each. @@ -323,10 +415,20 @@ return [g.Filenames(phase) for g in self._run_groups] @classmethod + def _ProcessName(cls, filename): + # The filename starts with 'profile-hitmap-' and ends with + # '-PID-TIMESTAMP.text_X'. Anything in between is the process name. The + # browser has an empty process name, which is insterted here. + process_name_parts = os.path.basename(filename).split('-')[2:-2] + if not process_name_parts: + return 'browser' + return '-'.join(process_name_parts) + + @classmethod def _Timestamp(cls, filename): - dash_index = filename.rindex('-') - dot_index = filename.rindex('.') - return int(filename[dash_index+1:dot_index]) + dash_index = filename.rindex('-') + dot_index = filename.rindex('.') + return int(filename[dash_index+1:dot_index]) @classmethod def _Phase(cls, filename): @@ -347,6 +449,19 @@ g.Add(f) self._run_groups.append(g) + # Some sanity checks on the run groups. + assert self._run_groups + if len(self._run_groups) < 5: + return # Small runs have too much variance for testing. + sizes = map(lambda g: len(g.Filenames()), self._run_groups) + avg_size = sum(sizes) / len(self._run_groups) + num_outliers = len([s for s in sizes + if s > 1.5 * avg_size or s < 0.75 * avg_size]) + expected_outliers = 0.1 * len(self._run_groups) + assert num_outliers < expected_outliers, ( + 'Saw {} outliers instead of at most {} for average of {}'.format( + num_outliers, expected_outliers, avg_size)) + def GetReachedOffsetsFromDumpFiles(dump_filenames, library_filename): """Produces a list of symbol offsets reached by the dumps.
diff --git a/tools/cygprofile/process_profiles_unittest.py b/tools/cygprofile/process_profiles_unittest.py index 77fc31c..c896a49 100755 --- a/tools/cygprofile/process_profiles_unittest.py +++ b/tools/cygprofile/process_profiles_unittest.py
@@ -10,7 +10,8 @@ import process_profiles -from test_utils import (SimpleTestSymbol, +from test_utils import (ProfileFile, + SimpleTestSymbol, TestSymbolOffsetProcessor, TestProfileManager) @@ -28,10 +29,10 @@ self.symbol_2, self.symbol_3] self._file_counter = 0 - def File(self, timestamp_sec, phase): - self._file_counter += 1 - return 'file-{}-{}.txt_{}'.format( - self._file_counter, timestamp_sec * 1000 * 1000 * 1000, phase) + def MakeAnnotatedOffset(self, offset, counts): + ao = process_profiles.ProfileManager.AnnotatedOffset(offset) + ao._count = counts + return ao def testGetOffsetToSymbolInfo(self): processor = TestSymbolOffsetProcessor(self.symbol_infos) @@ -103,8 +104,9 @@ self.assertEquals(5, process_profiles._Median([1, 4, 5, 6, 100])) def testRunGroups(self): - files = [self.File(40, 0), self.File(100, 0), self.File(200, 1), - self.File(35, 1), self.File(42, 0), self.File(95, 0)] + files = [ProfileFile(40, 0), ProfileFile(100, 0), + ProfileFile(200, 1), ProfileFile(35, 1), + ProfileFile(42, 0), ProfileFile(95, 0)] mgr = process_profiles.ProfileManager(files) mgr._ComputeRunGroups() self.assertEquals(3, len(mgr._run_groups)) @@ -118,11 +120,34 @@ self.assertTrue(files[5] in mgr._run_groups[1].Filenames()) self.assertTrue(files[2] in mgr._run_groups[2].Filenames()) + def testRunGroupSanity(self): + files = [] + # Generate 20 sets of files in groups separated by 60s. + for ts_base in xrange(0, 20): + ts = ts_base * 60 + files.extend([ProfileFile(ts, 0, 'browser'), + ProfileFile(ts + 1, 0, 'renderer'), + ProfileFile(ts + 2, 1, 'browser'), + ProfileFile(ts + 3, 0, 'gpu'), + ProfileFile(ts + 2, 1, 'renderer'), + ProfileFile(ts + 5, 1, 'gpu')]) + # The following call should not assert. + process_profiles.ProfileManager(files)._ComputeRunGroups() + + files.extend([ProfileFile(20 * 60, 0, 'browser'), + ProfileFile(20 * 60 + 2, 1, 'renderer'), + ProfileFile(21 * 60, 0, 'browser')] + + [ProfileFile(22 * 60, 0, 'renderer') + for _ in xrange(0, 10)]) + + self.assertRaises(AssertionError, + process_profiles.ProfileManager(files)._ComputeRunGroups) + def testReadOffsets(self): mgr = TestProfileManager({ - self.File(30, 0): [1, 3, 5, 7], - self.File(40, 1): [8, 10], - self.File(50, 0): [13, 15]}) + ProfileFile(30, 0): [1, 3, 5, 7], + ProfileFile(40, 1): [8, 10], + ProfileFile(50, 0): [13, 15]}) self.assertListEqual([1, 3, 5, 7, 8, 10, 13, 15], mgr.GetMergedOffsets()) self.assertListEqual([8, 10], mgr.GetMergedOffsets(1)) @@ -130,9 +155,9 @@ def testRunGroupOffsets(self): mgr = TestProfileManager({ - self.File(30, 0): [1, 2, 3, 4], - self.File(150, 0): [9, 11, 13], - self.File(40, 1): [5, 6, 7]}) + ProfileFile(30, 0): [1, 2, 3, 4], + ProfileFile(150, 0): [9, 11, 13], + ProfileFile(40, 1): [5, 6, 7]}) offsets_list = mgr.GetRunGroupOffsets() self.assertEquals(2, len(offsets_list)) self.assertListEqual([1, 2, 3, 4, 5, 6, 7], offsets_list[0]) @@ -150,22 +175,54 @@ # The fact that the ProfileManager sorts by filename is implicit in the # other tests. It is tested explicitly here. mgr = TestProfileManager({ - self.File(40, 0): [1, 2, 3, 4], - self.File(150, 0): [9, 11, 13], - self.File(30, 1): [5, 6, 7]}) + ProfileFile(40, 0): [1, 2, 3, 4], + ProfileFile(150, 0): [9, 11, 13], + ProfileFile(30, 1): [5, 6, 7]}) offsets_list = mgr.GetRunGroupOffsets() self.assertEquals(2, len(offsets_list)) self.assertListEqual([5, 6, 7, 1, 2, 3, 4], offsets_list[0]) def testPhases(self): mgr = TestProfileManager({ - self.File(40, 0): [], - self.File(150, 0): [], - self.File(30, 1): [], - self.File(30, 2): [], - self.File(30, 0): []}) + ProfileFile(40, 0): [], + ProfileFile(150, 0): [], + ProfileFile(30, 1): [], + ProfileFile(30, 2): [], + ProfileFile(30, 0): []}) self.assertEquals(set([0,1,2]), mgr.GetPhases()) + def testGetAnnotatedOffsets(self): + mgr = TestProfileManager({ + ProfileFile(40, 0, ''): [1, 2, 3], + ProfileFile(50, 1, ''): [3, 4, 5], + ProfileFile(51, 0, 'renderer'): [2, 3, 6], + ProfileFile(51, 1, 'gpu-process'): [6, 7], + ProfileFile(70, 0, ''): [2, 8, 9], + ProfileFile(70, 1, ''): [9]}) + offsets = mgr.GetAnnotatedOffsets() + self.assertListEqual([ + self.MakeAnnotatedOffset(1, {(0, 'browser'): 1}), + self.MakeAnnotatedOffset(2, {(0, 'browser'): 2, + (0, 'renderer'): 1}), + self.MakeAnnotatedOffset(3, {(0, 'browser'): 1, + (1, 'browser'): 1, + (0, 'renderer'): 1}), + self.MakeAnnotatedOffset(4, {(1, 'browser'): 1}), + self.MakeAnnotatedOffset(5, {(1, 'browser'): 1}), + self.MakeAnnotatedOffset(6, {(0, 'renderer'): 1, + (1, 'gpu-process'): 1}), + self.MakeAnnotatedOffset(7, {(1, 'gpu-process'): 1}), + self.MakeAnnotatedOffset(8, {(0, 'browser'): 1}), + self.MakeAnnotatedOffset(9, {(0, 'browser'): 1, + (1, 'browser'): 1})], + offsets) + self.assertListEqual(['browser', 'renderer'], + sorted(offsets[1].Processes())) + self.assertListEqual(['browser'], list(offsets[0].Processes())) + self.assertListEqual([0], list(offsets[1].Phases())) + self.assertListEqual([0, 1], sorted(offsets[2].Phases())) + self.assertListEqual([0, 1], sorted(mgr.GetPhases())) + if __name__ == '__main__': unittest.main()
diff --git a/tools/cygprofile/test_utils.py b/tools/cygprofile/test_utils.py index 47043b15..6aacbc9 100644 --- a/tools/cygprofile/test_utils.py +++ b/tools/cygprofile/test_utils.py
@@ -8,6 +8,9 @@ import process_profiles +# Used by ProfileFile to generate unique file names. +_FILE_COUNTER = 0 + SimpleTestSymbol = collections.namedtuple( 'SimpleTestSymbol', ['name', 'offset', 'size']) @@ -25,3 +28,14 @@ def _ReadOffsets(self, filename): return self._filecontents_mapping[filename] + + +def ProfileFile(timestamp_sec, phase, process_name=None): + global _FILE_COUNTER + _FILE_COUNTER += 1 + if process_name: + name_str = process_name + '-' + else: + name_str = '' + return 'test-directory/profile-hitmap-{}{}-{}.txt_{}'.format( + name_str, _FILE_COUNTER, timestamp_sec * 1000 * 1000 * 1000, phase)
diff --git a/tools/grit/grit.py b/tools/grit/grit.py index b17ceb9..2813b93 100755 --- a/tools/grit/grit.py +++ b/tools/grit/grit.py
@@ -13,4 +13,3 @@ if __name__ == '__main__': grit.grit_runner.Main(sys.argv[1:]) -
diff --git a/tools/grit/grit/__init__.py b/tools/grit/grit/__init__.py index 57e6709..a1eeaca 100755 --- a/tools/grit/grit/__init__.py +++ b/tools/grit/grit/__init__.py
@@ -7,4 +7,3 @@ ''' pass -
diff --git a/tools/grit/grit/clique.py b/tools/grit/grit/clique.py index 7d920a8..7607e5d 100755 --- a/tools/grit/grit/clique.py +++ b/tools/grit/grit/clique.py
@@ -483,4 +483,3 @@ language, transl_msg.GetId()) self.clique[language] = transl_msg -
diff --git a/tools/grit/grit/extern/tclib.py b/tools/grit/grit/extern/tclib.py index e84f177e..a9b1a39f 100755 --- a/tools/grit/grit/extern/tclib.py +++ b/tools/grit/grit/extern/tclib.py
@@ -500,4 +500,3 @@ Returns a copy of this Translation. """ return Translation(None, clone_from=self) -
diff --git a/tools/grit/grit/format/__init__.py b/tools/grit/grit/format/__init__.py index 2a3c59ca..28a4dc7 100755 --- a/tools/grit/grit/format/__init__.py +++ b/tools/grit/grit/format/__init__.py
@@ -7,4 +7,3 @@ ''' pass -
diff --git a/tools/grit/grit/gather/regexp.py b/tools/grit/grit/gather/regexp.py index 30488a6..16bc323a 100755 --- a/tools/grit/grit/gather/regexp.py +++ b/tools/grit/grit/gather/regexp.py
@@ -82,4 +82,3 @@ if self.single_message_: self.skeleton_.append(self.uberclique.MakeClique(self.single_message_)) -
diff --git a/tools/grit/grit/gather/tr_html.py b/tools/grit/grit/gather/tr_html.py index 3487251..d5122f6e 100755 --- a/tools/grit/grit/gather/tr_html.py +++ b/tools/grit/grit/gather/tr_html.py
@@ -742,4 +742,3 @@ continue new_skel.append(chunk) self.skeleton_ = new_skel -
diff --git a/tools/grit/grit/gather/txt_unittest.py b/tools/grit/grit/gather/txt_unittest.py index e2ff8a5..80586526 100755 --- a/tools/grit/grit/gather/txt_unittest.py +++ b/tools/grit/grit/gather/txt_unittest.py
@@ -31,4 +31,3 @@ if __name__ == '__main__': unittest.main() -
diff --git a/tools/grit/grit/node/base.py b/tools/grit/grit/node/base.py index e40bad88..76fbb31e 100755 --- a/tools/grit/grit/node/base.py +++ b/tools/grit/grit/node/base.py
@@ -621,4 +621,3 @@ '''Convenience baseclass for nodes that can have content.''' def _ContentType(self): return self._CONTENT_TYPE_MIXED -
diff --git a/tools/grit/grit/node/base_unittest.py b/tools/grit/grit/node/base_unittest.py index f7e7b75..58acdfb 100755 --- a/tools/grit/grit/node/base_unittest.py +++ b/tools/grit/grit/node/base_unittest.py
@@ -255,4 +255,3 @@ if __name__ == '__main__': unittest.main() -
diff --git a/tools/grit/grit/node/custom/filename_unittest.py b/tools/grit/grit/node/custom/filename_unittest.py index 9099086..9ea8eb9 100755 --- a/tools/grit/grit/node/custom/filename_unittest.py +++ b/tools/grit/grit/node/custom/filename_unittest.py
@@ -31,4 +31,3 @@ if __name__ == '__main__': unittest.main() -
diff --git a/tools/grit/grit/node/io.py b/tools/grit/grit/node/io.py index 69146199..83e14b1f 100755 --- a/tools/grit/grit/node/io.py +++ b/tools/grit/grit/node/io.py
@@ -116,4 +116,3 @@ def GetEmitType(self): '''Returns the emit_type for this node. Default is 'append'.''' return self.attrs['emit_type'] -
diff --git a/tools/grit/grit/node/mapping.py b/tools/grit/grit/node/mapping.py index 259be97..71b250b2 100755 --- a/tools/grit/grit/node/mapping.py +++ b/tools/grit/grit/node/mapping.py
@@ -58,4 +58,3 @@ if name not in _ELEMENT_TO_CLASS: raise exception.UnknownElement() return _ELEMENT_TO_CLASS[name] -
diff --git a/tools/grit/grit/node/structure.py b/tools/grit/grit/node/structure.py index 7b6f7bf..3d2012a 100755 --- a/tools/grit/grit/node/structure.py +++ b/tools/grit/grit/node/structure.py
@@ -356,4 +356,3 @@ assert hasattr(self, 'gatherer') if self.ExpandVariables(): self.gatherer.SubstituteMessages(substituter) -
diff --git a/tools/grit/grit/node/variant.py b/tools/grit/grit/node/variant.py index 4206712b..487f7f9 100755 --- a/tools/grit/grit/node/variant.py +++ b/tools/grit/grit/node/variant.py
@@ -39,4 +39,3 @@ def GetInputPath(self): return self.attrs['file'] -
diff --git a/tools/grit/grit/pseudo.py b/tools/grit/grit/pseudo.py index 17a6ec6a..cb57daab 100755 --- a/tools/grit/grit/pseudo.py +++ b/tools/grit/grit/pseudo.py
@@ -125,4 +125,3 @@ transl.AppendText(PseudoString(part)) return transl -
diff --git a/tools/grit/grit/shortcuts.py b/tools/grit/grit/shortcuts.py index 69a4386d..30bdbf7 100755 --- a/tools/grit/grit/shortcuts.py +++ b/tools/grit/grit/shortcuts.py
@@ -90,4 +90,3 @@ for group in groups.values(): warnings += group.GenerateWarnings(tc_project) return warnings -
diff --git a/tools/grit/grit/shortcuts_unittests.py b/tools/grit/grit/shortcuts_unittests.py index 421cfb2..b7c37b5 100755 --- a/tools/grit/grit/shortcuts_unittests.py +++ b/tools/grit/grit/shortcuts_unittests.py
@@ -77,4 +77,3 @@ if __name__ == '__main__': unittest.main() -
diff --git a/tools/grit/grit/tool/__init__.py b/tools/grit/grit/tool/__init__.py index c8565d5..4f769f2a 100755 --- a/tools/grit/grit/tool/__init__.py +++ b/tools/grit/grit/tool/__init__.py
@@ -7,4 +7,3 @@ ''' pass -
diff --git a/tools/grit/grit/tool/android2grd.py b/tools/grit/grit/tool/android2grd.py index c0538ed..e9e0ed1 100755 --- a/tools/grit/grit/tool/android2grd.py +++ b/tools/grit/grit/tool/android2grd.py
@@ -476,4 +476,3 @@ return value == 'true' else: return True -
diff --git a/tools/grit/grit/tool/count.py b/tools/grit/grit/tool/count.py index e87c4900..1517b16 100755 --- a/tools/grit/grit/tool/count.py +++ b/tools/grit/grit/tool/count.py
@@ -32,4 +32,3 @@ count += 1 print "There are %d occurrences of message %s." % (count, id) -
diff --git a/tools/grit/grit/tool/menu_from_parts.py b/tools/grit/grit/tool/menu_from_parts.py index 36d2d40..c7be7bd9 100755 --- a/tools/grit/grit/tool/menu_from_parts.py +++ b/tools/grit/grit/tool/menu_from_parts.py
@@ -76,4 +76,3 @@ with util.WrapOutputStream(open(output_file, 'w')) as f: transl2tc.TranslationToTc.WriteTranslations(f, translations) -
diff --git a/tools/grit/grit/tool/postprocess_interface.py b/tools/grit/grit/tool/postprocess_interface.py index 4a43254..c870b932 100755 --- a/tools/grit/grit/tool/postprocess_interface.py +++ b/tools/grit/grit/tool/postprocess_interface.py
@@ -27,6 +27,3 @@ The root node of the processed GRD tree. ''' raise NotImplementedError() - - -
diff --git a/tools/grit/grit/tool/postprocess_unittest.py b/tools/grit/grit/tool/postprocess_unittest.py index 330db490..91f02d69 100755 --- a/tools/grit/grit/tool/postprocess_unittest.py +++ b/tools/grit/grit/tool/postprocess_unittest.py
@@ -60,4 +60,3 @@ if __name__ == '__main__': unittest.main() -
diff --git a/tools/grit/grit/tool/preprocess_interface.py b/tools/grit/grit/tool/preprocess_interface.py index 4c5456c6..eea10b2 100755 --- a/tools/grit/grit/tool/preprocess_interface.py +++ b/tools/grit/grit/tool/preprocess_interface.py
@@ -23,6 +23,3 @@ The processed text. ''' raise NotImplementedError() - - -
diff --git a/tools/grit/grit/tool/preprocess_unittest.py b/tools/grit/grit/tool/preprocess_unittest.py index 1fc7192..da4242b 100755 --- a/tools/grit/grit/tool/preprocess_unittest.py +++ b/tools/grit/grit/tool/preprocess_unittest.py
@@ -46,4 +46,3 @@ if __name__ == '__main__': unittest.main() -
diff --git a/tools/grit/grit/tool/rc2grd.py b/tools/grit/grit/tool/rc2grd.py index 10d36f60..a0ef77fc 100755 --- a/tools/grit/grit/tool/rc2grd.py +++ b/tools/grit/grit/tool/rc2grd.py
@@ -406,4 +406,3 @@ except: print 'Exception processing message with text "%s"' % text raise -
diff --git a/tools/grit/grit/tool/rc2grd_unittest.py b/tools/grit/grit/tool/rc2grd_unittest.py index b41f5e43..0e48f07f 100755 --- a/tools/grit/grit/tool/rc2grd_unittest.py +++ b/tools/grit/grit/tool/rc2grd_unittest.py
@@ -134,4 +134,3 @@ if __name__ == '__main__': unittest.main() -
diff --git a/tools/grit/grit/tool/test.py b/tools/grit/grit/tool/test.py index 246b3ded..8f4cdd9 100755 --- a/tools/grit/grit/tool/test.py +++ b/tools/grit/grit/tool/test.py
@@ -21,4 +21,3 @@ print 'Options: %s' % repr(global_options) print 'Arguments: %s' % repr(my_arguments) return 0 -
diff --git a/tools/grit/grit/tool/transl2tc.py b/tools/grit/grit/tool/transl2tc.py index f3f06a9..a8af6ed16 100755 --- a/tools/grit/grit/tool/transl2tc.py +++ b/tools/grit/grit/tool/transl2tc.py
@@ -249,4 +249,3 @@ output_file.write(' ') output_file.write(text) output_file.write('\n') -
diff --git a/tools/grit/grit/util_unittest.py b/tools/grit/grit/util_unittest.py index 03f8cfe..ecadfa3c 100755 --- a/tools/grit/grit/util_unittest.py +++ b/tools/grit/grit/util_unittest.py
@@ -116,4 +116,3 @@ if __name__ == '__main__': unittest.main() -
diff --git a/tools/grit/grit/xtb_reader.py b/tools/grit/grit/xtb_reader.py index b92da39e..df6d9f8 100755 --- a/tools/grit/grit/xtb_reader.py +++ b/tools/grit/grit/xtb_reader.py
@@ -138,4 +138,3 @@ xml.sax.parse(xtb_file, handler) assert handler.language != '' return handler.language -
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 4d1aa96..0da6452 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -28641,6 +28641,7 @@ <int value="341152650" label="SoundContentSetting:enabled"/> <int value="345664265" label="BlinkHeapIncrementalMarking:disabled"/> <int value="346711293" label="enable-save-password-bubble"/> + <int value="348115702" label="new-password-form-parsing-for-saving:enabled"/> <int value="348854923" label="v8-cache-strategies-for-cache-storage"/> <int value="350399958" label="ModuleScriptsImportMetaUrl:disabled"/> <int value="352191859" label="disabled-new-style-notification"/> @@ -29065,6 +29066,8 @@ <int value="1194496204" label="NewWallpaperPicker:enabled"/> <int value="1196644408" label="performance-monitor-gathering"/> <int value="1196834473" label="disable-smart-virtual-keyboard"/> + <int value="1201441984" + label="new-password-form-parsing-for-saving:disabled"/> <int value="1205849612" label="enable-sync-synced-notifications"/> <int value="1209221384" label="enable-experimental-accessibility-features"/> <int value="1210343926" label="enable-drop-sync-credential"/> @@ -45702,6 +45705,18 @@ <int value="2" label="EMPTY_FIELD"/> </enum> +<enum name="SyncEntityChange"> + <summary> + Type of change of a sync entity. Recorded once for every sync entity + whenever it is commited to the server or updated from the server. + </summary> + <int value="0" label="Local deletion (commited upstream)"/> + <int value="1" label="Local creation (commited upstream)"/> + <int value="2" label="Local update (commited upstream)"/> + <int value="3" label="Remote deletion (updated downstream)"/> + <int value="4" label="Remote update (updated downstream)"/> +</enum> + <enum name="SyncErrorInfobarTypes"> <summary>Possible errors that can trigger a sync error infobar.</summary> <int value="1" label="Sign in needs update"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b1d326c..9013798e 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -45186,6 +45186,9 @@ </histogram> <histogram name="MessageLoop.DelayedTaskQueue.PendingTasksCountOnIdle"> + <obsolete> + Deprecated as of 07/2018. + </obsolete> <owner>gab@chromium.org</owner> <summary> The size of the delayed task queue when the loop becomes idle. Diagnosis @@ -45194,6 +45197,9 @@ </histogram> <histogram name="MessageLoop.DelayedTaskQueue.PostedDelay" units="ms"> + <obsolete> + Deprecated as of 07/2018. + </obsolete> <owner>gab@chromium.org</owner> <summary> Reports the delay of a delayed task posted to a MessageLoop. Reported once @@ -45201,7 +45207,20 @@ </summary> </histogram> +<histogram name="MessageLoop.DelayedTaskQueueForUI.PendingTasksCountOnIdle"> + <owner>gab@chromium.org</owner> + <summary> + The size of the delayed task queue when the loop becomes idle on a UI + thread. Diagnosis metric for https://crbug.com/850450#c4. Note: this metric + is a bit broken on Mac OSX as CFRunLoop doesn't deterministically invoke + MessageLoop::DoIdleWork(). + </summary> +</histogram> + <histogram name="MessageLoop.ScheduledSleep.Completed" units="ms"> + <obsolete> + Deprecated as of 07/2018. + </obsolete> <owner>gab@chromium.org</owner> <summary> Reports the delay for which the MessageLoop successfully slept until an @@ -45211,6 +45230,9 @@ </histogram> <histogram name="MessageLoop.ScheduledSleep.Interrupted" units="ms"> + <obsolete> + Deprecated as of 07/2018. + </obsolete> <owner>gab@chromium.org</owner> <summary> Reports the delay for which the MessageLoop had planned to sleep (next @@ -100122,6 +100144,17 @@ </summary> </histogram> +<histogram base="true" name="Sync.ModelTypeEntityChange" + enum="SyncEntityChange" expires_after="2020-02-01"> + <owner>jkrcal@chromium.org</owner> + <summary> + Recorded once for every sync entity change (whenever it is commited to the + server or updated from the server). This metric is used for monitoring + general health of sync client-side code. Note: This is only recorded with a + data type suffix. The base version is never recorded. + </summary> +</histogram> + <histogram name="Sync.ModelTypeMemoryKB" units="KB"> <owner>pavely@chromium.org</owner> <summary> @@ -126488,6 +126521,7 @@ <suffix name="USER_EVENT" label="USER_EVENT"/> <suffix name="WIFI_CREDENTIAL" label="WIFI_CREDENTIAL"/> <affected-histogram name="Sync.ModelTypeCount"/> + <affected-histogram name="Sync.ModelTypeEntityChange"/> <affected-histogram name="Sync.ModelTypeMemoryKB"/> </histogram_suffixes>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 6407a9f..b3374da 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -255,8 +255,6 @@ crbug.com/738854 [ Nexus_5X ] system_health.common_mobile/load:tools:drive [ Skip ] crbug.com/738854 [ Android_Webview ] system_health.common_mobile/load:tools:drive [ Skip ] crbug.com/797261 [ Android_Webview ] system_health.common_mobile/load:games:spychase [ Skip ] -crbug.com/798536 [ Android ] system_health.common_mobile/background:news:nytimes [ Skip ] -crbug.com/798536 [ Android ] system_health.common_mobile/load:games:spychase [ Skip ] crbug.com/736147 [ Android_One ] system_health.common_mobile/browse:social:tumblr_infinite_scroll [ Skip ] crbug.com/803461 [ Nexus_5 ] system_health.common_mobile/browse:chrome:newtab [ Skip ]
diff --git a/ui/accelerated_widget_mac/ca_layer_tree_coordinator.mm b/ui/accelerated_widget_mac/ca_layer_tree_coordinator.mm index 9bc48ec..fb4e271 100644 --- a/ui/accelerated_widget_mac/ca_layer_tree_coordinator.mm +++ b/ui/accelerated_widget_mac/ca_layer_tree_coordinator.mm
@@ -48,7 +48,7 @@ if (pending_ca_renderer_layer_tree_) { pending_ca_renderer_layer_tree_->CommitScheduledCALayers( root_ca_layer_.get(), std::move(current_ca_renderer_layer_tree_), - scale_factor_); + pixel_size_, scale_factor_); current_ca_renderer_layer_tree_.swap(pending_ca_renderer_layer_tree_); } else { TRACE_EVENT0("gpu", "Blank frame: No overlays or CALayers");
diff --git a/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm b/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm index 93c7fe4c..ba08f5f6 100644 --- a/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm +++ b/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm
@@ -80,7 +80,8 @@ bool result = ScheduleCALayer(new_ca_layer_tree.get(), properties); EXPECT_TRUE(result); new_ca_layer_tree->CommitScheduledCALayers( - superlayer, std::move(ca_layer_tree), properties->scale_factor); + superlayer, std::move(ca_layer_tree), properties->rect.size(), + properties->scale_factor); std::swap(new_ca_layer_tree, ca_layer_tree); } @@ -508,8 +509,8 @@ bool result = ScheduleCALayer(ca_layer_tree.get(), &properties); EXPECT_TRUE(result); } - ca_layer_tree->CommitScheduledCALayers(superlayer_, nullptr, - properties.scale_factor); + ca_layer_tree->CommitScheduledCALayers( + superlayer_, nullptr, properties.rect.size(), properties.scale_factor); // Validate the root layer. EXPECT_EQ(1u, [[superlayer_ sublayers] count]); @@ -588,8 +589,8 @@ bool result = ScheduleCALayer(ca_layer_tree.get(), &properties); EXPECT_TRUE(result); } - ca_layer_tree->CommitScheduledCALayers(superlayer_, nullptr, - properties.scale_factor); + ca_layer_tree->CommitScheduledCALayers( + superlayer_, nullptr, properties.rect.size(), properties.scale_factor); // Validate the root layer. EXPECT_EQ(1u, [[superlayer_ sublayers] count]); @@ -882,7 +883,8 @@ bool result = ScheduleCALayer(new_ca_layer_tree.get(), &properties); EXPECT_TRUE(result); new_ca_layer_tree->CommitScheduledCALayers( - superlayer_, std::move(ca_layer_tree), properties.scale_factor); + superlayer_, std::move(ca_layer_tree), properties.rect.size(), + properties.scale_factor); std::swap(new_ca_layer_tree, ca_layer_tree); // Validate the tree structure. @@ -896,7 +898,7 @@ EXPECT_EQ(1u, [[transform_layer sublayers] count]); // Validate the content layer and fullscreen low power mode. - EXPECT_TRUE(CGRectEqualToRect([root_layer frame], CGRectZero)); + EXPECT_FALSE(CGRectEqualToRect([root_layer frame], CGRectZero)); EXPECT_NE([root_layer backgroundColor], nil); } @@ -909,7 +911,8 @@ result = ScheduleCALayer(new_ca_layer_tree.get(), &properties); EXPECT_TRUE(result); new_ca_layer_tree->CommitScheduledCALayers( - superlayer_, std::move(ca_layer_tree), properties.scale_factor); + superlayer_, std::move(ca_layer_tree), properties.rect.size(), + properties.scale_factor); std::swap(new_ca_layer_tree, ca_layer_tree); // Validate the tree structure. @@ -936,7 +939,8 @@ result = ScheduleCALayer(new_ca_layer_tree.get(), &properties); EXPECT_TRUE(result); new_ca_layer_tree->CommitScheduledCALayers( - superlayer_, std::move(ca_layer_tree), properties.scale_factor); + superlayer_, std::move(ca_layer_tree), properties.rect.size(), + properties.scale_factor); std::swap(new_ca_layer_tree, ca_layer_tree); // Validate the tree structure. @@ -963,7 +967,8 @@ result = ScheduleCALayer(new_ca_layer_tree.get(), &properties_black); EXPECT_TRUE(result); new_ca_layer_tree->CommitScheduledCALayers( - superlayer_, std::move(ca_layer_tree), properties.scale_factor); + superlayer_, std::move(ca_layer_tree), properties.rect.size(), + properties.scale_factor); std::swap(new_ca_layer_tree, ca_layer_tree); // Validate the tree structure.
diff --git a/ui/accelerated_widget_mac/ca_renderer_layer_tree.h b/ui/accelerated_widget_mac/ca_renderer_layer_tree.h index 7c90bae6..a4e7fe3 100644 --- a/ui/accelerated_widget_mac/ca_renderer_layer_tree.h +++ b/ui/accelerated_widget_mac/ca_renderer_layer_tree.h
@@ -51,6 +51,7 @@ // not re-used by |this| will be removed from the CALayer hierarchy. void CommitScheduledCALayers(CALayer* superlayer, std::unique_ptr<CARendererLayerTree> old_tree, + const gfx::Size& pixel_size, float scale_factor); // Returns the contents used for a given solid color. @@ -86,15 +87,12 @@ // to nil, so that its destructor will not remove an active CALayer. void CommitToCA(CALayer* superlayer, RootLayer* old_layer, + const gfx::Size& pixel_size, float scale_factor); - // Check to see if the CALayer tree is just a video layer on a black - // background. If so, return true and set background_rect to the - // background's bounding rect, otherwise return false. CommitToCA() calls - // this function and, based on its return value, either gives the root - // layer this frame and a black background color or clears them. - bool WantsFullcreenLowPowerBackdrop(float scale_factor, - gfx::RectF* background_rect); + // Return true if the CALayer tree is just a video layer on a black or + // transparent background, false otherwise. + bool WantsFullcreenLowPowerBackdrop(); std::vector<ClipAndSortingLayer> clip_and_sorting_layers; base::scoped_nsobject<CALayer> ca_layer;
diff --git a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm index 9b64866..1c5988fe 100644 --- a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm +++ b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm
@@ -220,6 +220,7 @@ void CARendererLayerTree::CommitScheduledCALayers( CALayer* superlayer, std::unique_ptr<CARendererLayerTree> old_tree, + const gfx::Size& pixel_size, float scale_factor) { TRACE_EVENT0("gpu", "CARendererLayerTree::CommitScheduledCALayers"); RootLayer* old_root_layer = nullptr; @@ -229,7 +230,7 @@ old_root_layer = &old_tree->root_layer_; } - root_layer_.CommitToCA(superlayer, old_root_layer, scale_factor); + root_layer_.CommitToCA(superlayer, old_root_layer, pixel_size, scale_factor); // If there are any extra CALayers in |old_tree| that were not stolen by this // tree, they will be removed from the CALayer tree in this deallocation. old_tree.reset(); @@ -237,9 +238,7 @@ scale_factor_ = scale_factor; } -bool CARendererLayerTree::RootLayer::WantsFullcreenLowPowerBackdrop( - float scale_factor, - gfx::RectF* background_rect) { +bool CARendererLayerTree::RootLayer::WantsFullcreenLowPowerBackdrop() { bool found_video_layer = false; for (auto& clip_layer : clip_and_sorting_layers) { for (auto& transform_layer : clip_layer.transform_layers) { @@ -250,7 +249,6 @@ // See if this is the video layer. if (content_layer.use_av_layer) { - background_rect->Union(gfx::RectF(content_layer.rect)); found_video_layer = true; if (!transform_layer.transform.IsPositiveScaleOrTranslation()) return false; @@ -263,15 +261,13 @@ // solid black or transparent if (content_layer.io_surface) return false; - if (content_layer.background_color == SK_ColorBLACK) { - background_rect->Union(gfx::RectF(content_layer.rect)); - } else if (content_layer.background_color != SK_ColorTRANSPARENT) { + if (content_layer.background_color != SK_ColorBLACK && + content_layer.background_color != SK_ColorTRANSPARENT) { return false; } } } } - background_rect->Scale(1 / scale_factor); return found_video_layer; } @@ -554,6 +550,7 @@ void CARendererLayerTree::RootLayer::CommitToCA(CALayer* superlayer, RootLayer* old_layer, + const gfx::Size& pixel_size, float scale_factor) { if (old_layer) { DCHECK(old_layer->ca_layer); @@ -569,8 +566,9 @@ DLOG(ERROR) << "CARendererLayerTree root layer not attached to tree."; } - gfx::RectF bg_rect; - if (WantsFullcreenLowPowerBackdrop(scale_factor, &bg_rect)) { + if (WantsFullcreenLowPowerBackdrop()) { + const gfx::RectF bg_rect( + ScaleSize(gfx::SizeF(pixel_size), 1 / scale_factor)); if (gfx::RectF([ca_layer frame]) != bg_rect) [ca_layer setFrame:bg_rect.ToCGRect()]; if (![ca_layer backgroundColor])
diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java index df8c615..c5d5f32 100644 --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
@@ -390,17 +390,18 @@ if (photos.length == 1) { GetDisplayNameTask task = - new GetDisplayNameTask(ContextUtils.getApplicationContext(), false); - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Uri.parse(photos[0])); + new GetDisplayNameTask(ContextUtils.getApplicationContext(), false, + new Uri[] {Uri.parse(photos[0])}); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); return; } else { Uri[] filePathArray = new Uri[photos.length]; for (int i = 0; i < photos.length; ++i) { filePathArray[i] = Uri.parse(photos[i]); } - GetDisplayNameTask task = - new GetDisplayNameTask(ContextUtils.getApplicationContext(), true); - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, filePathArray); + GetDisplayNameTask task = new GetDisplayNameTask( + ContextUtils.getApplicationContext(), true, filePathArray); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } break; @@ -565,9 +566,9 @@ for (int i = 0; i < itemCount; ++i) { filePathArray[i] = clipData.getItemAt(i).getUri(); } - GetDisplayNameTask task = - new GetDisplayNameTask(ContextUtils.getApplicationContext(), true); - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, filePathArray); + GetDisplayNameTask task = new GetDisplayNameTask( + ContextUtils.getApplicationContext(), true, filePathArray); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); return; } @@ -577,9 +578,9 @@ } if (ContentResolver.SCHEME_CONTENT.equals(results.getScheme())) { - GetDisplayNameTask task = - new GetDisplayNameTask(ContextUtils.getApplicationContext(), false); - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, results.getData()); + GetDisplayNameTask task = new GetDisplayNameTask( + ContextUtils.getApplicationContext(), false, new Uri[] {results.getData()}); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); return; } @@ -699,32 +700,34 @@ return count; } - class GetDisplayNameTask extends AsyncTask<Uri, Void, String[]> { + class GetDisplayNameTask extends AsyncTask<Void, Void, String[]> { String[] mFilePaths; final Context mContext; final boolean mIsMultiple; + final Uri[] mUris; - public GetDisplayNameTask(Context context, boolean isMultiple) { + public GetDisplayNameTask(Context context, boolean isMultiple, Uri[] uris) { mContext = context; mIsMultiple = isMultiple; + mUris = uris; } @Override - public String[] doInBackground(Uri...uris) { - mFilePaths = new String[uris.length]; - String[] displayNames = new String[uris.length]; + public String[] doInBackground(Void... params) { + mFilePaths = new String[mUris.length]; + String[] displayNames = new String[mUris.length]; try { - for (int i = 0; i < uris.length; i++) { + for (int i = 0; i < mUris.length; i++) { // The selected files must be returned as a list of absolute paths. A MIUI 8.5 // device was observed to return a file:// URI instead, so convert if necessary. // See https://crbug.com/752834 for context. - if (ContentResolver.SCHEME_FILE.equals(uris[i].getScheme())) { - mFilePaths[i] = uris[i].getSchemeSpecificPart(); + if (ContentResolver.SCHEME_FILE.equals(mUris[i].getScheme())) { + mFilePaths[i] = mUris[i].getSchemeSpecificPart(); } else { - mFilePaths[i] = uris[i].toString(); + mFilePaths[i] = mUris[i].toString(); } displayNames[i] = ContentUriUtils.getDisplayName( - uris[i], mContext, MediaStore.MediaColumns.DISPLAY_NAME); + mUris[i], mContext, MediaStore.MediaColumns.DISPLAY_NAME); } } catch (SecurityException e) { // Some third party apps will present themselves as being able
diff --git a/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java b/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java index 101215af..ebcc7d3 100644 --- a/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java +++ b/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
@@ -133,12 +133,12 @@ @Test public void testMultipleFileSelectorWithFileUris() throws Throwable { SelectFileDialog selectFileDialog = new SelectFileDialog(0); - SelectFileDialog.GetDisplayNameTask task = - selectFileDialog.new GetDisplayNameTask(ContextUtils.getApplicationContext(), true); Uri[] filePathArray = new Uri[] { Uri.parse("file:///storage/emulated/0/DCIM/Camera/IMG_0.jpg"), Uri.parse("file:///storage/emulated/0/DCIM/Camera/IMG_1.jpg")}; - task.doInBackground(filePathArray); + SelectFileDialog.GetDisplayNameTask task = selectFileDialog.new GetDisplayNameTask( + ContextUtils.getApplicationContext(), true, filePathArray); + task.doInBackground(); assertEquals(task.mFilePaths[0].toString(), "///storage/emulated/0/DCIM/Camera/IMG_0.jpg"); assertEquals(task.mFilePaths[1].toString(),
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index beae9238..3e0f7dc 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -258,29 +258,6 @@ "//third_party/zlib", ] - # Text rendering conditions (complicated so separated out). - if (use_aura || is_mac || is_android || is_fuchsia) { - # Mac doesn't use RenderTextHarfBuzz by default yet. - sources += [ - "harfbuzz_font_skia.cc", - "harfbuzz_font_skia.h", - "render_text_harfbuzz.cc", - "render_text_harfbuzz.h", - "render_text_mac.h", - "render_text_mac.mm", - "text_utils_skia.cc", - ] - - if (!is_ios) { - sources += [ - "render_text.cc", - "render_text.h", - ] - } - } else { - # We don't support RenderText on these platforms. - } - if (is_android) { set_sources_assignment_filter([]) sources += [ @@ -316,8 +293,17 @@ if (!is_ios) { sources += [ + "harfbuzz_font_skia.cc", + "harfbuzz_font_skia.h", "paint_vector_icon.cc", "paint_vector_icon.h", + "render_text.cc", + "render_text.h", + "render_text_harfbuzz.cc", + "render_text_harfbuzz.h", + "render_text_mac.h", + "render_text_mac.mm", + "text_utils_skia.cc", "vector_icon_types.h", ] }