diff --git a/DEPS b/DEPS index 09ff1ec..026d04b 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '4ef01482025e2e629e35458aa214436d3b4138e8', + 'skia_revision': 'ce425510a07632f14b7b779ec3864f719cb4326b', # 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': 'e43ea3f67b99e1c715c7ab2e02864612ea64f8a9', + 'v8_revision': '691effc377ebae3e8a2c2391913befeda0619d52', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '5bcd9a32232e8cd5df918104eb131be76f833701', + 'pdfium_revision': '3ae3033bff2582029984f91f40f4a8b748a30c96', # 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. @@ -96,7 +96,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': 'f76a7183f0bf2130ff891b857208421e7f00dbd6', + 'catapult_revision': 'f410d46fe0f63a221c8099698bb798a245f2a9c0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/android_webview/glue/BUILD.gn b/android_webview/glue/BUILD.gn index ab52954..25fb8b4a 100644 --- a/android_webview/glue/BUILD.gn +++ b/android_webview/glue/BUILD.gn
@@ -78,5 +78,6 @@ "java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java", "java/src/com/android/webview/chromium/WebViewDatabaseAdapter.java", "java/src/com/android/webview/chromium/WebViewDelegateFactory.java", + "java/src/com/android/webview/chromium/reflection/WebViewConfig.java", ] }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/reflection/WebViewConfig.java b/android_webview/glue/java/src/com/android/webview/chromium/reflection/WebViewConfig.java new file mode 100644 index 0000000..f2445237 --- /dev/null +++ b/android_webview/glue/java/src/com/android/webview/chromium/reflection/WebViewConfig.java
@@ -0,0 +1,22 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package com.android.webview.chromium.reflection; + +import org.chromium.android_webview.AwContentsStatics; +import org.chromium.base.annotations.UsedByReflection; + +/** + * Entry points for reflection into Android WebView internals for static configuration. + * + * Methods in this class may be removed, but they should not be changed in any incompatible way. + * Methods should be removed when we no longer wish to expose the functionality. + */ +@UsedByReflection("") +public class WebViewConfig { + @UsedByReflection("") + public static void disableSafeBrowsing() { + AwContentsStatics.setSafeBrowsingEnabled(false); + } +}
diff --git a/base/BUILD.gn b/base/BUILD.gn index fd1fe2c..48243ce 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1196,7 +1196,6 @@ "process/internal_linux.cc", "process/memory_linux.cc", "process/process_handle_linux.cc", - "process/process_info_linux.cc", "process/process_iterator_linux.cc", "process/process_metrics_linux.cc", "sys_info_linux.cc", @@ -2055,7 +2054,6 @@ "process/memory_unittest.cc", "process/memory_unittest_mac.h", "process/memory_unittest_mac.mm", - "process/process_info_unittest.cc", "process/process_metrics_unittest.cc", "process/process_metrics_unittest_ios.cc", "process/process_unittest.cc",
diff --git a/base/OWNERS b/base/OWNERS index 0e7d010..28043c42 100644 --- a/base/OWNERS +++ b/base/OWNERS
@@ -36,11 +36,6 @@ per-file feature_list*=asvitkine@chromium.org per-file feature_list*=isherman@chromium.org -# For bot infrastructure: -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org - # For TCMalloc tests: per-file security_unittest.cc=jln@chromium.org
diff --git a/base/process/process_info_linux.cc b/base/process/process_info_linux.cc index 2f22748..7cec8f4e 100644 --- a/base/process/process_info_linux.cc +++ b/base/process/process_info_linux.cc
@@ -17,12 +17,10 @@ const Time CurrentProcessInfo::CreationTime() { int64_t start_ticks = internal::ReadProcSelfStatsAndGetFieldAsInt64(internal::VM_STARTTIME); - if (!start_ticks) - return Time(); + DCHECK(start_ticks); TimeDelta start_offset = internal::ClockTicksToTimeDelta(start_ticks); Time boot_time = internal::GetBootTime(); - if (boot_time.is_null()) - return Time(); + DCHECK(!boot_time.is_null()); return Time(boot_time + start_offset); }
diff --git a/base/process/process_info_unittest.cc b/base/process/process_info_unittest.cc deleted file mode 100644 index a757774..0000000 --- a/base/process/process_info_unittest.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 "base/process/process_info.h" - -#include "base/time/time.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { - -#if !defined(OS_IOS) -TEST(ProcessInfoTest, CreationTime) { - Time creation_time = CurrentProcessInfo::CreationTime(); - ASSERT_FALSE(creation_time.is_null()); -} -#endif // !defined(OS_IOS) - -} // namespace base
diff --git a/base/synchronization/waitable_event.h b/base/synchronization/waitable_event.h index 761965f0..e8caffe 100644 --- a/base/synchronization/waitable_event.h +++ b/base/synchronization/waitable_event.h
@@ -112,6 +112,9 @@ // You MUST NOT delete any of the WaitableEvent objects while this wait is // happening, however WaitMany's return "happens after" the |Signal| call // that caused it has completed, like |Wait|. + // + // If more than one WaitableEvent is signaled to unblock WaitMany, the lowest + // index among them is returned. static size_t WaitMany(WaitableEvent** waitables, size_t count); // For asynchronous waiting, see WaitableEventWatcher
diff --git a/base/synchronization/waitable_event_posix.cc b/base/synchronization/waitable_event_posix.cc index 5dfff46..846fa067 100644 --- a/base/synchronization/waitable_event_posix.cc +++ b/base/synchronization/waitable_event_posix.cc
@@ -5,6 +5,7 @@ #include <stddef.h> #include <algorithm> +#include <limits> #include <vector> #include "base/debug/activity_tracker.h" @@ -266,12 +267,10 @@ SyncWaiter sw; const size_t r = EnqueueMany(&waitables[0], count, &sw); - if (r) { + if (r < count) { // One of the events is already signaled. The SyncWaiter has not been - // enqueued anywhere. EnqueueMany returns the count of remaining waitables - // when the signaled one was seen, so the index of the signaled event is - // @count - @r. - return waitables[count - r].second; + // enqueued anywhere. + return waitables[r].second; } // At this point, we hold the locks on all the WaitableEvents and we have @@ -319,38 +318,50 @@ } // ----------------------------------------------------------------------------- -// If return value == 0: +// If return value == count: // The locks of the WaitableEvents have been taken in order and the Waiter has // been enqueued in the wait-list of each. None of the WaitableEvents are // currently signaled // else: // None of the WaitableEvent locks are held. The Waiter has not been enqueued -// in any of them and the return value is the index of the first WaitableEvent -// which was signaled, from the end of the array. +// in any of them and the return value is the index of the WaitableEvent which +// was signaled with the lowest input index from the original WaitMany call. // ----------------------------------------------------------------------------- // static -size_t WaitableEvent::EnqueueMany - (std::pair<WaitableEvent*, size_t>* waitables, - size_t count, Waiter* waiter) { - if (!count) - return 0; - - waitables[0].first->kernel_->lock_.Acquire(); - if (waitables[0].first->kernel_->signaled_) { - if (!waitables[0].first->kernel_->manual_reset_) - waitables[0].first->kernel_->signaled_ = false; - waitables[0].first->kernel_->lock_.Release(); - return count; +size_t WaitableEvent::EnqueueMany(std::pair<WaitableEvent*, size_t>* waitables, + size_t count, + Waiter* waiter) { + size_t winner = count; + size_t winner_index = count; + for (size_t i = 0; i < count; ++i) { + auto& kernel = waitables[i].first->kernel_; + kernel->lock_.Acquire(); + if (kernel->signaled_ && waitables[i].second < winner) { + winner = waitables[i].second; + winner_index = i; } + } - const size_t r = EnqueueMany(waitables + 1, count - 1, waiter); - if (r) { - waitables[0].first->kernel_->lock_.Release(); - } else { - waitables[0].first->Enqueue(waiter); + // No events signaled. All locks acquired. Enqueue the Waiter on all of them + // and return. + if (winner == count) { + for (size_t i = 0; i < count; ++i) + waitables[i].first->Enqueue(waiter); + return count; + } + + // Unlock in reverse order and possibly clear the chosen winner's signal + // before returning its index. + for (auto* w = waitables + count - 1; w >= waitables; --w) { + auto& kernel = w->first->kernel_; + if (w->second == winner) { + if (!kernel->manual_reset_) + kernel->signaled_ = false; } + kernel->lock_.Release(); + } - return r; + return winner_index; } // -----------------------------------------------------------------------------
diff --git a/base/synchronization/waitable_event_unittest.cc b/base/synchronization/waitable_event_unittest.cc index c0e280aa..3aa1af16 100644 --- a/base/synchronization/waitable_event_unittest.cc +++ b/base/synchronization/waitable_event_unittest.cc
@@ -6,6 +6,8 @@ #include <stddef.h> +#include <algorithm> + #include "base/compiler_specific.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" @@ -78,6 +80,42 @@ delete ev[i]; } +TEST(WaitableEventTest, WaitManyLeftToRight) { + WaitableEvent* ev[5]; + for (size_t i = 0; i < 5; ++i) { + ev[i] = new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC, + WaitableEvent::InitialState::NOT_SIGNALED); + } + + // Test for consistent left-to-right return behavior across all permutations + // of the input array. This is to verify that only the indices -- and not + // the WaitableEvents' addresses -- are relevant in determining who wins when + // multiple events are signaled. + + std::sort(ev, ev + 5); + do { + ev[0]->Signal(); + ev[1]->Signal(); + EXPECT_EQ(0u, WaitableEvent::WaitMany(ev, 5)); + + ev[2]->Signal(); + EXPECT_EQ(1u, WaitableEvent::WaitMany(ev, 5)); + EXPECT_EQ(2u, WaitableEvent::WaitMany(ev, 5)); + + ev[3]->Signal(); + ev[4]->Signal(); + ev[0]->Signal(); + EXPECT_EQ(0u, WaitableEvent::WaitMany(ev, 5)); + EXPECT_EQ(3u, WaitableEvent::WaitMany(ev, 5)); + ev[2]->Signal(); + EXPECT_EQ(2u, WaitableEvent::WaitMany(ev, 5)); + EXPECT_EQ(4u, WaitableEvent::WaitMany(ev, 5)); + } while (std::next_permutation(ev, ev + 5)); + + for (size_t i = 0; i < 5; ++i) + delete ev[i]; +} + class WaitableEventSignaler : public PlatformThread::Delegate { public: WaitableEventSignaler(TimeDelta delay, WaitableEvent* event)
diff --git a/base/sys_info.h b/base/sys_info.h index ecaa731..18bdaf0 100644 --- a/base/sys_info.h +++ b/base/sys_info.h
@@ -80,8 +80,6 @@ static std::string OperatingSystemVersion(); // Retrieves detailed numeric values for the OS version. - // TODO(port): Implement a Linux version of this method and enable the - // corresponding unit test. // DON'T USE THIS ON THE MAC OR WINDOWS to determine the current OS release // for OS version-specific feature checks and workarounds. If you must use // an OS version check instead of a feature check, use the base::mac::IsOS*
diff --git a/base/sys_info_posix.cc b/base/sys_info_posix.cc index f480055cc..c4c07d0 100644 --- a/base/sys_info_posix.cc +++ b/base/sys_info_posix.cc
@@ -183,6 +183,30 @@ } #endif +#if !defined(OS_MACOSX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS) +// static +void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version, + int32_t* minor_version, + int32_t* bugfix_version) { + struct utsname info; + if (uname(&info) < 0) { + NOTREACHED(); + *major_version = 0; + *minor_version = 0; + *bugfix_version = 0; + return; + } + int num_read = sscanf(info.release, "%d.%d.%d", major_version, minor_version, + bugfix_version); + if (num_read < 1) + *major_version = 0; + if (num_read < 2) + *minor_version = 0; + if (num_read < 3) + *bugfix_version = 0; +} +#endif + // static std::string SysInfo::OperatingSystemArchitecture() { struct utsname info;
diff --git a/base/sys_info_unittest.cc b/base/sys_info_unittest.cc index e80884b9..94b5a84 100644 --- a/base/sys_info_unittest.cc +++ b/base/sys_info_unittest.cc
@@ -71,7 +71,7 @@ EXPECT_GT(SysInfo::AmountOfTotalDiskSpace(tmp_path), 0) << tmp_path.value(); } -#if defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) TEST_F(SysInfoTest, OperatingSystemVersionNumbers) { int32_t os_major_version = -1; int32_t os_minor_version = -1;
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc index 4c03aeb..6dddb94 100644 --- a/base/trace_event/trace_log.cc +++ b/base/trace_event/trace_log.cc
@@ -19,7 +19,6 @@ #include "base/memory/ref_counted_memory.h" #include "base/memory/singleton.h" #include "base/message_loop/message_loop.h" -#include "base/process/process_info.h" #include "base/process/process_metrics.h" #include "base/stl_util.h" #include "base/strings/string_split.h" @@ -1501,16 +1500,6 @@ process_name_); } -#if !defined(OS_NACL) && !defined(OS_IOS) - Time process_creation_time = CurrentProcessInfo::CreationTime(); - if (!process_creation_time.is_null()) { - TimeDelta process_uptime = Time::Now() - process_creation_time; - InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), - current_thread_id, "process_uptime_seconds", - "uptime", process_uptime.InSeconds()); - } -#endif // !defined(OS_NACL) && !defined(OS_IOS) - if (!process_labels_.empty()) { std::vector<std::string> labels; for (const auto& it : process_labels_)
diff --git a/breakpad/OWNERS b/breakpad/OWNERS index c88bdbe2..0e8489a 100644 --- a/breakpad/OWNERS +++ b/breakpad/OWNERS
@@ -1,8 +1,4 @@ mark@chromium.org thestig@chromium.org -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org - # TEAM: google-breakpad-dev@googlegroups.com
diff --git a/cc/OWNERS b/cc/OWNERS index cbba2c2b..5a30b139 100644 --- a/cc/OWNERS +++ b/cc/OWNERS
@@ -57,9 +57,5 @@ # nduca@chromium.org # mithro@mithis.com / tansell@chromium.org -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org - # TEAM: graphics-dev@chromium.org # COMPONENT: Internals>Compositing
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h index 733273d..cd00cdc6 100644 --- a/cc/paint/paint_canvas.h +++ b/cc/paint/paint_canvas.h
@@ -34,7 +34,6 @@ virtual void flush() = 0; virtual SkISize getBaseLayerSize() const = 0; - virtual bool peekPixels(SkPixmap* pixmap) = 0; virtual bool readPixels(const SkImageInfo& dest_info, void* dest_pixels, size_t dest_row_bytes,
diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc index 41ff72367..0421d89 100644 --- a/cc/paint/skia_paint_canvas.cc +++ b/cc/paint/skia_paint_canvas.cc
@@ -23,6 +23,7 @@ const SkSurfaceProps& props) : canvas_(new SkCanvas(bitmap, props)), owned_(canvas_) {} +SkiaPaintCanvas::SkiaPaintCanvas(SkiaPaintCanvas&& other) = default; SkiaPaintCanvas::~SkiaPaintCanvas() = default; SkMetaData& SkiaPaintCanvas::getMetaData() { @@ -41,10 +42,6 @@ return canvas_->getBaseLayerSize(); } -bool SkiaPaintCanvas::peekPixels(SkPixmap* pixmap) { - return canvas_->peekPixels(pixmap); -} - bool SkiaPaintCanvas::readPixels(const SkImageInfo& dest_info, void* dest_pixels, size_t dest_row_bytes,
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h index 0a0974b..979efdf 100644 --- a/cc/paint/skia_paint_canvas.h +++ b/cc/paint/skia_paint_canvas.h
@@ -28,15 +28,17 @@ explicit SkiaPaintCanvas(SkCanvas* canvas); explicit SkiaPaintCanvas(const SkBitmap& bitmap); explicit SkiaPaintCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props); + explicit SkiaPaintCanvas(SkiaPaintCanvas&& other); ~SkiaPaintCanvas() override; + SkiaPaintCanvas& operator=(SkiaPaintCanvas&& other) = default; + SkMetaData& getMetaData() override; SkImageInfo imageInfo() const override; void flush() override; SkISize getBaseLayerSize() const override; - bool peekPixels(SkPixmap* pixmap) override; bool readPixels(const SkImageInfo& dest_info, void* dest_pixels, size_t dest_row_bytes, @@ -163,6 +165,8 @@ private: SkCanvas* canvas_; std::unique_ptr<SkCanvas> owned_; + + DISALLOW_COPY_AND_ASSIGN(SkiaPaintCanvas); }; } // namespace cc
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 4ef536f..26884a55 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -1521,11 +1521,9 @@ bool LayerTreeImpl::DistributeRootScrollOffset( const gfx::ScrollOffset& root_offset) { - if (!InnerViewportScrollLayer()) + if (!InnerViewportScrollLayer() || !OuterViewportScrollLayer()) return false; - DCHECK(OuterViewportScrollLayer()); - // If we get here, we have both inner/outer viewports, and need to distribute // the scroll offset between them. gfx::ScrollOffset inner_viewport_offset =
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index 89936ce..9e598e4 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -431,14 +431,6 @@ <item name="android:textSize">14sp</item> </style> - <!-- Signin promo dialog--> - <style name="SigninPromoDialog" parent="FullscreenWhite"> - <item name="android:windowFrame">@null</item> - <item name="android:windowIsFloating">true</item> - <item name="android:windowContentOverlay">@null</item> - <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> - </style> - <!-- Contextual Search styles --> <style name="ContextualSearchTextViewLayout"> <item name="android:layout_width">match_parent</item>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index 241c4ae..c310353e 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -27,7 +27,8 @@ <color name="google_grey_600">#757575</color> <color name="google_grey_700">#616161</color> <color name="toolbar_shadow_color">#1d000000</color> - <color name="semi_opaque_white">#80ffffff</color> + <color name="white_alpha_50">#80ffffff</color> + <color name="black_alpha_40">#66000000</color> <color name="toolbar_light_tint">#A3000000</color> <color name="light_grey">#ccc</color> <color name="modal_dialog_scrim_color">#7f000000</color>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java index c8aeceb8..467f1a61 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java
@@ -247,12 +247,6 @@ startMarginAnimation(false); startYOffsetAnimation(false); finishScrollStacks(); - - // TODO(twellington): Add a proper tab selection animation rather than disabling the current - // animation. - if (FeatureUtilities.isChromeHomeEnabled()) { - onUpdateAnimation(System.currentTimeMillis(), true); - } } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java index e72367c3..b10b915 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java
@@ -1956,7 +1956,7 @@ if (tab.getId() == tabId) { tab.setDiscardAmount(getDiscardRange()); tab.setDying(false); - tab.getLayoutTab().setMaxContentHeight(mLayout.getHeightMinusBrowserControls()); + tab.getLayoutTab().setMaxContentHeight(getMaxTabHeight()); } } @@ -2269,6 +2269,16 @@ } /** + * @return The maximum height of a layout tab in the tab switcher. + */ + public float getMaxTabHeight() { + if (FeatureUtilities.isChromeHomeEnabled() && mCurrentMode == Orientation.PORTRAIT) { + return mLayout.getHeight(); + } + return mLayout.getHeightMinusBrowserControls(); + } + + /** * Computes the scale of the tab based on its discard status. * * @param amount The discard amount. @@ -2302,19 +2312,18 @@ mDiscardDirection = getDefaultDiscardDirection(); setWarpState(true, false); final float opaqueTopPadding = mBorderTopPadding - mBorderTransparentTop; - mAnimationFactory = StackAnimation.createAnimationFactory(mLayout.getWidth(), + mAnimationFactory = StackAnimation.createAnimationFactory(this, mLayout.getWidth(), mLayout.getHeight(), mLayout.getHeightMinusBrowserControls(), mBorderTopPadding, opaqueTopPadding, mBorderLeftPadding, mCurrentMode); float dpToPx = mLayout.getContext().getResources().getDisplayMetrics().density; mViewAnimationFactory = new StackViewAnimation(dpToPx, mLayout.getWidth()); if (mStackTabs == null) return; float width = mLayout.getWidth(); - float height = mLayout.getHeightMinusBrowserControls(); for (int i = 0; i < mStackTabs.length; i++) { LayoutTab tab = mStackTabs[i].getLayoutTab(); if (tab == null) continue; tab.setMaxContentWidth(width); - tab.setMaxContentHeight(height); + tab.setMaxContentHeight(getMaxTabHeight()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java index 9c923c69..acae0fd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java
@@ -80,10 +80,12 @@ protected final float mBorderTopHeight; protected final float mBorderTopOpaqueHeight; protected final float mBorderLeftWidth; + protected final Stack mStack; /** * Protected constructor. * + * @param stack The stack using the animations provided by this class. * @param width The width of the layout in dp. * @param height The height of the layout in dp. * @param heightMinusBrowserControls The height of the layout minus the browser controls in dp. @@ -91,9 +93,10 @@ * @param borderFramePaddingTopOpaque The opaque top padding of the border frame in dp. * @param borderFramePaddingLeft The left padding of the border frame in dp. */ - protected StackAnimation(float width, float height, float heightMinusBrowserControls, - float borderFramePaddingTop, float borderFramePaddingTopOpaque, - float borderFramePaddingLeft) { + protected StackAnimation(Stack stack, float width, float height, + float heightMinusBrowserControls, float borderFramePaddingTop, + float borderFramePaddingTopOpaque, float borderFramePaddingLeft) { + mStack = stack; mWidth = width; mHeight = height; mHeightMinusBrowserControls = heightMinusBrowserControls; @@ -107,6 +110,7 @@ * The factory method that creates the particular factory method based on the orientation * parameter. * + * @param stack The stack of tabs being animated. * @param width The width of the layout in dp. * @param height The height of the layout in dp. * @param heightMinusBrowserControls The height of the layout minus the browser controls in dp. @@ -117,19 +121,21 @@ * appropriate {@link StackAnimation}. * @return The TabSwitcherAnimationFactory instance. */ - public static StackAnimation createAnimationFactory(float width, float height, + public static StackAnimation createAnimationFactory(Stack stack, float width, float height, float heightMinusBrowserControls, float borderFramePaddingTop, float borderFramePaddingTopOpaque, float borderFramePaddingLeft, int orientation) { StackAnimation factory = null; switch (orientation) { case Orientation.LANDSCAPE: - factory = new StackAnimationLandscape(width, height, heightMinusBrowserControls, - borderFramePaddingTop, borderFramePaddingTopOpaque, borderFramePaddingLeft); + factory = new StackAnimationLandscape(stack, width, height, + heightMinusBrowserControls, borderFramePaddingTop, + borderFramePaddingTopOpaque, borderFramePaddingLeft); break; case Orientation.PORTRAIT: default: - factory = new StackAnimationPortrait(width, height, heightMinusBrowserControls, - borderFramePaddingTop, borderFramePaddingTopOpaque, borderFramePaddingLeft); + factory = new StackAnimationPortrait(stack, width, height, + heightMinusBrowserControls, borderFramePaddingTop, + borderFramePaddingTopOpaque, borderFramePaddingLeft); break; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimationLandscape.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimationLandscape.java index 5beb7cf..5b37de3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimationLandscape.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimationLandscape.java
@@ -21,6 +21,7 @@ import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation; import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.Animatable; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; +import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.MathUtils; import org.chromium.ui.base.LocalizationUtils; @@ -28,10 +29,10 @@ /** * Only Constructor. */ - public StackAnimationLandscape(float width, float height, float heightMinusBrowserControls, - float borderFramePaddingTop, float borderFramePaddingTopOpaque, - float borderFramePaddingLeft) { - super(width, height, heightMinusBrowserControls, borderFramePaddingTop, + public StackAnimationLandscape(Stack stack, float width, float height, + float heightMinusBrowserControls, float borderFramePaddingTop, + float borderFramePaddingTopOpaque, float borderFramePaddingLeft) { + super(stack, width, height, heightMinusBrowserControls, borderFramePaddingTop, borderFramePaddingTopOpaque, borderFramePaddingLeft); } @@ -54,7 +55,7 @@ addAnimation(set, tab.getLayoutTab(), MAX_CONTENT_HEIGHT, tab.getLayoutTab().getUnclampedOriginalContentHeight(), - mHeightMinusBrowserControls, ENTER_STACK_ANIMATION_DURATION, 0); + mStack.getMaxTabHeight(), ENTER_STACK_ANIMATION_DURATION, 0); if (i < focusIndex) { addAnimation(set, tab, SCROLL_OFFSET, initialScrollOffset, scrollOffset, ENTER_STACK_ANIMATION_DURATION, 0); @@ -128,8 +129,11 @@ set, tab, SCALE, tab.getScale(), 1.0f, TAB_FOCUSED_ANIMATION_DURATION, 0); addAnimation(set, tab, X_IN_STACK_INFLUENCE, tab.getXInStackInfluence(), 0.0f, TAB_FOCUSED_ANIMATION_DURATION, 0); + int tabYInfluenceDuration = FeatureUtilities.isChromeHomeEnabled() + ? TAB_FOCUSED_ANIMATION_DURATION + : TAB_FOCUSED_Y_STACK_DURATION; addAnimation(set, tab, Y_IN_STACK_INFLUENCE, tab.getYInStackInfluence(), 0.0f, - TAB_FOCUSED_Y_STACK_DURATION, 0); + tabYInfluenceDuration, 0); addAnimation(set, tab.getLayoutTab(), MAX_CONTENT_HEIGHT, tab.getLayoutTab().getMaxContentHeight(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimationPortrait.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimationPortrait.java index 652db9b..ae454ab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimationPortrait.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimationPortrait.java
@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation; import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.Animatable; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; +import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.MathUtils; import org.chromium.ui.base.LocalizationUtils; @@ -27,10 +28,10 @@ /** * Only Constructor. */ - public StackAnimationPortrait(float width, float height, float heightMinusBrowserControls, - float borderFramePaddingTop, float borderFramePaddingTopOpaque, - float borderFramePaddingLeft) { - super(width, height, heightMinusBrowserControls, borderFramePaddingTop, + public StackAnimationPortrait(Stack stack, float width, float height, + float heightMinusBrowserControls, float borderFramePaddingTop, + float borderFramePaddingTopOpaque, float borderFramePaddingLeft) { + super(stack, width, height, heightMinusBrowserControls, borderFramePaddingTop, borderFramePaddingTopOpaque, borderFramePaddingLeft); } @@ -62,11 +63,11 @@ float scrollOffset = StackTab.screenToScroll(i * spacing, warpSize); if (i < focusIndex) { - tab.getLayoutTab().setMaxContentHeight(mHeightMinusBrowserControls); + tab.getLayoutTab().setMaxContentHeight(mStack.getMaxTabHeight()); addAnimation(set, tab, SCROLL_OFFSET, initialScrollOffset, scrollOffset, ENTER_STACK_ANIMATION_DURATION, 0); } else if (i > focusIndex) { - tab.getLayoutTab().setMaxContentHeight(mHeightMinusBrowserControls); + tab.getLayoutTab().setMaxContentHeight(mStack.getMaxTabHeight()); tab.setScrollOffset(scrollOffset + trailingScrollOffset); addAnimation( set, tab, Y_IN_STACK_OFFSET, mHeight, 0, ENTER_STACK_ANIMATION_DURATION, 0); @@ -75,7 +76,7 @@ addAnimation(set, tab.getLayoutTab(), MAX_CONTENT_HEIGHT, tab.getLayoutTab().getUnclampedOriginalContentHeight(), - mHeightMinusBrowserControls, ENTER_STACK_ANIMATION_DURATION, + mStack.getMaxTabHeight(), ENTER_STACK_ANIMATION_DURATION, ENTER_STACK_RESIZE_DELAY); addAnimation(set, tab, Y_IN_STACK_INFLUENCE, 0.0f, 1.0f, ENTER_STACK_BORDER_ALPHA_DURATION, 0); @@ -136,8 +137,11 @@ TAB_FOCUSED_ANIMATION_DURATION, 0); addAnimation( set, tab, SCALE, tab.getScale(), 1.0f, TAB_FOCUSED_ANIMATION_DURATION, 0); + int tabYInfluenceDuration = FeatureUtilities.isChromeHomeEnabled() + ? TAB_FOCUSED_ANIMATION_DURATION + : TAB_FOCUSED_Y_STACK_DURATION; addAnimation(set, tab, Y_IN_STACK_INFLUENCE, tab.getYInStackInfluence(), 0.0f, - TAB_FOCUSED_Y_STACK_DURATION, 0); + tabYInfluenceDuration, 0); addAnimation(set, tab.getLayoutTab(), MAX_CONTENT_HEIGHT, tab.getLayoutTab().getMaxContentHeight(), tab.getLayoutTab().getUnclampedOriginalContentHeight(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java index e09cf97..9acd716 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
@@ -411,6 +411,8 @@ boolean handled = CustomTabActivity.handleInActiveContentIfNeeded(getIntent()); if (handled) return; + maybePrefetchDnsInBackground(); + // Create and fire a launch intent. startActivity(createCustomTabActivityIntent( this, getIntent(), !isCustomTabIntent(getIntent()) && mIsHerbIntent));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java index 28a392fc..caf50c4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
@@ -95,11 +95,11 @@ super(context, attrs); int defaultHandleColor = - ApiCompatibilityUtils.getColor(getResources(), R.color.google_grey_500); + ApiCompatibilityUtils.getColor(getResources(), R.color.black_alpha_40); mHandleDark = generateHandleBitmap(defaultHandleColor); int lightHandleColor = - ApiCompatibilityUtils.getColor(getResources(), R.color.semi_opaque_white); + ApiCompatibilityUtils.getColor(getResources(), R.color.white_alpha_50); mHandleLight = generateHandleBitmap(lightHandleColor); } @@ -201,10 +201,11 @@ protected void updateVisualsForToolbarState() { super.updateVisualsForToolbarState(); - // The handle should not show in tab switcher mode. - mToolbarHandleView.setVisibility( - mTabSwitcherState != ToolbarPhone.STATIC_TAB ? View.INVISIBLE : View.VISIBLE); - mToolbarHandleView.setImageBitmap(mUseLightToolbarDrawables ? mHandleLight : mHandleDark); + // The tab switcher's background color should not affect the toolbar handle; it should only + // switch color based on the static tab's theme color. This is done so fade in/out looks + // correct. + boolean isLight = ColorUtils.shouldUseLightForegroundOnBackground(getTabThemeColor()); + mToolbarHandleView.setImageBitmap(isLight ? mHandleLight : mHandleDark); } @Override @@ -252,6 +253,7 @@ mNewTabButton.setAlpha(progress); mLocationBar.setAlpha(1f - progress); + mToolbarHandleView.setAlpha(1f - progress); int tabSwitcherThemeColor = getToolbarColorForVisualState(VisualState.TAB_SWITCHER_NORMAL);
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 03934b7..e6f19e12 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
@@ -59,6 +59,7 @@ import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.util.ColorUtils; +import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.MathUtils; import org.chromium.chrome.browser.widget.TintedImageButton; import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; @@ -706,7 +707,7 @@ // Perform the fade logic before super.dispatchDraw(canvas) so that we can properly // set the values before the draw happens. - if (!mAnimateNormalToolbar) { + if (!mAnimateNormalToolbar || FeatureUtilities.isChromeHomeEnabled()) { drawTabSwitcherFadeAnimation( tabSwitcherAnimationFinished, mTabSwitcherModePercent); }
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 6505600..d706b49 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -1663,29 +1663,11 @@ PostProfileInit(); #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) - // Show the First Run UI if this is the first time Chrome has been run on - // this computer, or we're being compelled to do so by a command line flag. - // Note that this be done _after_ the PrefService is initialized and all - // preferences are registered, since some of the code that the importer - // touches reads preferences. + // Execute first run specific code after the PrefService has been initialized + // and preferences have been registered since some of the import code depends + // on preferences. if (first_run::IsChromeFirstRun()) { - // By default Auto Import is performed on first run. - bool auto_import = true; - -#if defined(OS_WIN) - // Auto Import might be disabled via a field trial. However, this field - // trial is not intended to affect enterprise users. - auto_import = - base::win::IsEnterpriseManaged() || - !base::FeatureList::IsEnabled(features::kDisableFirstRunAutoImportWin); -#endif // defined(OS_WIN) - - if (auto_import) { - first_run::AutoImport(profile_, master_prefs_->homepage_defined, - master_prefs_->do_import_items, - master_prefs_->dont_import_items, - master_prefs_->import_bookmarks_path); - } + first_run::AutoImport(profile_, master_prefs_->import_bookmarks_path); // Note: this can pop the first run consent dialog on linux. first_run::DoPostImportTasks(profile_,
diff --git a/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc b/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc index a2451440..e0be4c8 100644 --- a/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc +++ b/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc
@@ -10,6 +10,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/ssl/ssl_error_handler.h" #include "content/public/browser/browser_thread.h" @@ -82,11 +83,12 @@ DVLOG(1) << "Component ready, version " << version.GetString() << " in " << install_dir.value(); - if (!content::BrowserThread::PostBlockingPoolTask( - FROM_HERE, - base::Bind(&LoadProtoFromDisk, GetInstalledPath(install_dir)))) { - NOTREACHED(); - } + base::PostTaskWithTraits( + FROM_HERE, + base::TaskTraits() + .WithPriority(base::TaskPriority::BACKGROUND) + .MayBlock(), + base::Bind(&LoadProtoFromDisk, GetInstalledPath(install_dir))); } // Called during startup and installation before ComponentReady().
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index bab5ac73..53a9677c 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/extensions/convert_web_app.h" #include "chrome/browser/extensions/extension_assets_manager.h" #include "chrome/browser/extensions/extension_error_reporter.h" +#include "chrome/browser/extensions/extension_install_checker.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/install_tracker.h" #include "chrome/browser/extensions/install_tracker_factory.h" @@ -108,7 +109,8 @@ CrxInstaller::CrxInstaller(base::WeakPtr<ExtensionService> service_weak, std::unique_ptr<ExtensionInstallPrompt> client, const WebstoreInstaller::Approval* approval) - : install_directory_(service_weak->install_directory()), + : profile_(service_weak->profile()), + install_directory_(service_weak->install_directory()), install_source_(Manifest::INTERNAL), approved_(false), hash_check_failed_(false), @@ -130,8 +132,7 @@ did_handle_successfully_(true), error_on_unsupported_requirements_(false), update_from_settings_page_(false), - install_flags_(kInstallFlagNone), - install_checker_(service_weak->profile()) { + install_flags_(kInstallFlagNone) { installer_task_runner_ = service_weak->GetFileTaskRunner(); if (!approval) return; @@ -355,7 +356,7 @@ } } - if (install_checker_.extension()->is_app()) { + if (extension_->is_app()) { // If the app was downloaded, apps_require_extension_mime_type_ // will be set. In this case, check that it was served with the // right mime type. Make an exception for file URLs, which come @@ -388,7 +389,7 @@ pattern.SetHost(download_url_.host()); pattern.SetMatchSubdomains(true); - URLPatternSet patterns = install_checker_.extension()->web_extent(); + URLPatternSet patterns = extension_->web_extent(); for (URLPatternSet::const_iterator i = patterns.begin(); i != patterns.end(); ++i) { if (!pattern.MatchesHost(i->host())) { @@ -431,7 +432,7 @@ install_cause(), extension_misc::NUM_INSTALL_CAUSES); - install_checker_.set_extension(extension); + extension_ = extension; temp_dir_ = temp_dir; if (!install_icon.empty()) install_icon_.reset(new SkBitmap(install_icon)); @@ -510,11 +511,12 @@ // Run the policy, requirements and blacklist checks in parallel. Skip the // checks if the extension is a bookmark app. if (extension()->from_bookmark()) { - CrxInstaller::OnInstallChecksComplete(0); + ConfirmInstall(); } else { - install_checker_.Start( - ExtensionInstallChecker::CHECK_ALL, - false /* fail fast */, + install_checker_ = base::MakeUnique<ExtensionInstallChecker>( + profile_, extension_, ExtensionInstallChecker::CHECK_ALL, + false /* fail fast */); + install_checker_->Start( base::Bind(&CrxInstaller::OnInstallChecksComplete, this)); } } @@ -525,24 +527,24 @@ return; // Check for requirement errors. - if (!install_checker_.requirement_errors().empty()) { + if (!install_checker_->requirement_errors().empty()) { if (error_on_unsupported_requirements_) { ReportFailureFromUIThread( CrxInstallError(CrxInstallError::ERROR_DECLINED, base::UTF8ToUTF16(base::JoinString( - install_checker_.requirement_errors(), " ")))); + install_checker_->requirement_errors(), " ")))); return; } install_flags_ |= kInstallFlagHasRequirementErrors; } // Check the blacklist state. - if (install_checker_.blacklist_state() == BLACKLISTED_MALWARE) { + if (install_checker_->blacklist_state() == BLACKLISTED_MALWARE) { install_flags_ |= kInstallFlagIsBlacklistedForMalware; } - if ((install_checker_.blacklist_state() == BLACKLISTED_MALWARE || - install_checker_.blacklist_state() == BLACKLISTED_UNKNOWN) && + if ((install_checker_->blacklist_state() == BLACKLISTED_MALWARE || + install_checker_->blacklist_state() == BLACKLISTED_UNKNOWN) && !allow_silent_install_) { // User tried to install a blacklisted extension. Show an error and // refuse to install it. @@ -561,7 +563,7 @@ // deal with it. // Check for policy errors. - if (!install_checker_.policy_error().empty()) { + if (!install_checker_->policy_error().empty()) { // We don't want to show the error infobar for installs from the WebStore, // because the WebStore already shows an error dialog itself. // Note: |client_| can be NULL in unit_tests! @@ -569,7 +571,7 @@ client_->install_ui()->SetSkipPostInstallUI(true); ReportFailureFromUIThread( CrxInstallError(CrxInstallError::ERROR_DECLINED, - base::UTF8ToUTF16(install_checker_.policy_error()))); + base::UTF8ToUTF16(install_checker_->policy_error()))); return; } @@ -582,7 +584,7 @@ if (!service || service->browser_terminating()) return; - if (KioskModeInfo::IsKioskOnly(install_checker_.extension().get())) { + if (KioskModeInfo::IsKioskOnly(extension())) { bool in_kiosk_mode = false; #if defined(OS_CHROMEOS) user_manager::UserManager* user_manager = user_manager::UserManager::Get(); @@ -721,13 +723,10 @@ // with base::string16 std::string extension_id = extension()->id(); std::string error; - install_checker_.set_extension( - file_util::LoadExtension( - version_dir, - install_source_, - // Note: modified by UpdateCreationFlagsAndCompleteInstall. - creation_flags_, - &error).get()); + extension_ = file_util::LoadExtension( + version_dir, install_source_, + // Note: modified by UpdateCreationFlagsAndCompleteInstall. + creation_flags_, &error); if (extension()) { ReportSuccessFromFileThread();
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index 7d7168f..e16d57c 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_ #define CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_ +#include <memory> #include <string> #include <vector> @@ -14,7 +15,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/version.h" -#include "chrome/browser/extensions/extension_install_checker.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/webstore_installer.h" @@ -36,6 +36,7 @@ namespace extensions { class CrxInstallError; +class ExtensionInstallChecker; class ExtensionUpdaterTest; // This class installs a crx file into a profile. @@ -200,9 +201,9 @@ bool did_handle_successfully() const { return did_handle_successfully_; } - Profile* profile() { return install_checker_.profile(); } + Profile* profile() { return profile_; } - const Extension* extension() { return install_checker_.extension().get(); } + const Extension* extension() { return extension_.get(); } // The currently installed version of the extension, for updates. Will be // invalid if this isn't an update. @@ -211,7 +212,6 @@ private: friend class ::ExtensionServiceTest; friend class ExtensionUpdaterTest; - friend class ExtensionCrxInstallerTest; CrxInstaller(base::WeakPtr<ExtensionService> service_weak, std::unique_ptr<ExtensionInstallPrompt> client, @@ -288,6 +288,12 @@ install_flags_ &= ~flag; } + // The Profile the extension is being installed in. + Profile* profile_; + + // The extension being installed. + scoped_refptr<const Extension> extension_; + // The file we're installing. base::FilePath source_file_; @@ -438,7 +444,7 @@ int install_flags_; // Performs requirements, policy and blacklist checks on the extension. - ExtensionInstallChecker install_checker_; + std::unique_ptr<ExtensionInstallChecker> install_checker_; DISALLOW_COPY_AND_ASSIGN(CrxInstaller); };
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc index 36098b8..af7b9e43 100644 --- a/chrome/browser/extensions/crx_installer_browsertest.cc +++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -284,16 +284,6 @@ CreateWebAppInfo(kAppTitle, kAppDescription, kAppUrl, 64)); EXPECT_TRUE(WaitForCrxInstallerDone()); ASSERT_TRUE(crx_installer->extension()); - ASSERT_FALSE(HasRequirementErrors(crx_installer.get())); - ASSERT_FALSE(HasPolicyErrors(crx_installer.get())); - } - - bool HasRequirementErrors(CrxInstaller* crx_installer) { - return !crx_installer->install_checker_.requirement_errors().empty(); - } - - bool HasPolicyErrors(CrxInstaller* crx_installer) { - return !crx_installer->install_checker_.policy_error().empty(); } };
diff --git a/chrome/browser/extensions/extension_browsertest.h b/chrome/browser/extensions/extension_browsertest.h index 55eecc6..ca87820 100644 --- a/chrome/browser/extensions/extension_browsertest.h +++ b/chrome/browser/extensions/extension_browsertest.h
@@ -263,7 +263,8 @@ return observer_->WaitForExtensionCrash(extension_id); } - // Wait for the crx installer to be done. Returns true if it really is done. + // Wait for the crx installer to be done. Returns true if it has finished + // successfully. bool WaitForCrxInstallerDone() { return observer_->WaitForCrxInstallerDone(); }
diff --git a/chrome/browser/extensions/extension_install_checker.cc b/chrome/browser/extensions/extension_install_checker.cc index 313225df..d027389d 100644 --- a/chrome/browser/extensions/extension_install_checker.cc +++ b/chrome/browser/extensions/extension_install_checker.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/extensions/extension_install_checker.h" +#include "base/callback_helpers.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/blacklist.h" #include "chrome/browser/extensions/chrome_requirements_checker.h" @@ -14,55 +15,56 @@ namespace extensions { -ExtensionInstallChecker::ExtensionInstallChecker(Profile* profile) +ExtensionInstallChecker::ExtensionInstallChecker( + Profile* profile, + scoped_refptr<const Extension> extension, + int enabled_checks, + bool fail_fast) : profile_(profile), + extension_(extension), blacklist_state_(NOT_BLACKLISTED), policy_allows_load_(true), - current_sequence_number_(0), + enabled_checks_(enabled_checks), running_checks_(0), - fail_fast_(false), - weak_ptr_factory_(this) { -} + fail_fast_(fail_fast), + weak_ptr_factory_(this) {} ExtensionInstallChecker::~ExtensionInstallChecker() { } -void ExtensionInstallChecker::Start(int enabled_checks, - bool fail_fast, - const Callback& callback) { +void ExtensionInstallChecker::Start(const Callback& callback) { // Profile is null in tests. if (profile_) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // TODO(michaelpg): change NOTREACHED to [D]CHECK here and below. if (!extension_.get()) { NOTREACHED(); return; } } - if (is_running() || !enabled_checks || callback.is_null()) { + if (is_running() || !enabled_checks_ || callback.is_null()) { NOTREACHED(); return; } - running_checks_ = enabled_checks; - fail_fast_ = fail_fast; + running_checks_ = enabled_checks_; callback_ = callback; - ResetResults(); // Execute the management policy check first as it is synchronous. - if (enabled_checks & CHECK_MANAGEMENT_POLICY) { + if (enabled_checks_ & CHECK_MANAGEMENT_POLICY) { CheckManagementPolicy(); if (!is_running()) return; } - if (enabled_checks & CHECK_REQUIREMENTS) { + if (enabled_checks_ & CHECK_REQUIREMENTS) { CheckRequirements(); if (!is_running()) return; } - if (enabled_checks & CHECK_BLACKLIST) + if (enabled_checks_ & CHECK_BLACKLIST) CheckBlacklistState(); } @@ -89,21 +91,15 @@ void ExtensionInstallChecker::CheckRequirements() { DCHECK(extension_.get()); - if (!requirements_checker_.get()) - requirements_checker_.reset(new ChromeRequirementsChecker()); + requirements_checker_ = base::MakeUnique<ChromeRequirementsChecker>(); requirements_checker_->Check( - extension_, - base::Bind(&ExtensionInstallChecker::OnRequirementsCheckDone, - weak_ptr_factory_.GetWeakPtr(), - current_sequence_number_)); + extension_, base::Bind(&ExtensionInstallChecker::OnRequirementsCheckDone, + weak_ptr_factory_.GetWeakPtr())); } void ExtensionInstallChecker::OnRequirementsCheckDone( - int sequence_number, const std::vector<std::string>& errors) { - // Some pending results may arrive after fail fast. - if (sequence_number != current_sequence_number_) - return; + DCHECK(is_running()); requirement_errors_ = errors; @@ -118,15 +114,11 @@ blacklist->IsBlacklisted( extension_->id(), base::Bind(&ExtensionInstallChecker::OnBlacklistStateCheckDone, - weak_ptr_factory_.GetWeakPtr(), - current_sequence_number_)); + weak_ptr_factory_.GetWeakPtr())); } -void ExtensionInstallChecker::OnBlacklistStateCheckDone(int sequence_number, - BlacklistState state) { - // Some pending results may arrive after fail fast. - if (sequence_number != current_sequence_number_) - return; +void ExtensionInstallChecker::OnBlacklistStateCheckDone(BlacklistState state) { + DCHECK(is_running()); blacklist_state_ = state; @@ -134,13 +126,6 @@ MaybeInvokeCallback(); } -void ExtensionInstallChecker::ResetResults() { - requirement_errors_.clear(); - blacklist_state_ = NOT_BLACKLISTED; - policy_allows_load_ = true; - policy_error_.clear(); -} - void ExtensionInstallChecker::MaybeInvokeCallback() { if (callback_.is_null()) return; @@ -160,14 +145,7 @@ // If we are failing fast, discard any pending results. weak_ptr_factory_.InvalidateWeakPtrs(); running_checks_ = 0; - ++current_sequence_number_; - - Callback callback_copy = callback_; - callback_.Reset(); - - // This instance may be owned by the callback recipient and deleted here, - // so reset |callback_| first and invoke a copy of the callback. - callback_copy.Run(failed_mask); + base::ResetAndReturn(&callback_).Run(failed_mask); } }
diff --git a/chrome/browser/extensions/extension_install_checker.h b/chrome/browser/extensions/extension_install_checker.h index b73255b..9bafea51 100644 --- a/chrome/browser/extensions/extension_install_checker.h +++ b/chrome/browser/extensions/extension_install_checker.h
@@ -22,8 +22,8 @@ class RequirementsChecker; -// Performs common checks for an extension. Extensions that violate these checks -// would be disabled or not even installed. +// Performs common checks for validating whether an extension may be installed. +// This class should be Start()-ed at most once. class ExtensionInstallChecker { public: // Called when checks are complete. The returned value is a bitmask of @@ -42,25 +42,20 @@ CHECK_ALL = (1 << 3) - 1 }; - explicit ExtensionInstallChecker(Profile* profile); + // |enabled_checks| is a bitmask of CheckTypes to run. + // If |fail_fast| is true, the callback to Start() will be invoked once any + // check fails. Otherwise it will be invoked when all checks have completed. + ExtensionInstallChecker(Profile* profile, + scoped_refptr<const Extension> extension, + int enabled_checks, + bool fail_fast); virtual ~ExtensionInstallChecker(); - // Start a set of checks. |enabled_checks| is a bitmask of CheckTypes to run. - // If |fail_fast| is true, the callback will be invoked once any check fails. - // Otherwise it will be invoked when all checks have completed. |callback| - // will only be called once. + // Starts the set of checks. |callback| will only be called once. // This function must be called on the UI thread. The callback also occurs on // the UI thread. Checks may run asynchronously in parallel. - // If checks are currently running, the caller must wait for the callback to - // be invoked before starting another set of checks. - void Start(int enabled_checks, bool fail_fast, const Callback& callback); - - Profile* profile() const { return profile_; } - - const scoped_refptr<const Extension>& extension() { return extension_; } - void set_extension(const scoped_refptr<const Extension>& extension) { - extension_ = extension; - } + // This function should be invoked at most once. + void Start(const Callback& callback); // Returns true if any checks are currently running. bool is_running() const { return running_checks_ != 0; } @@ -84,14 +79,10 @@ void OnManagementPolicyCheckDone(bool allows_load, const std::string& error); virtual void CheckRequirements(); - void OnRequirementsCheckDone(int sequence_number, - const std::vector<std::string>& errors); + void OnRequirementsCheckDone(const std::vector<std::string>& errors); virtual void CheckBlacklistState(); - void OnBlacklistStateCheckDone(int sequence_number, BlacklistState state); - - virtual void ResetResults(); - int current_sequence_number() const { return current_sequence_number_; } + void OnBlacklistStateCheckDone(BlacklistState state); private: void MaybeInvokeCallback(); @@ -114,10 +105,11 @@ bool policy_allows_load_; std::string policy_error_; - // The sequence number of the currently running checks. - int current_sequence_number_; + // Bitmask of enabled checks. + int enabled_checks_; // Bitmask of currently running checks. + // TODO(michaelpg): Consolidate this with enabled_checks_. int running_checks_; // If true, the callback is invoked when the first check fails.
diff --git a/chrome/browser/extensions/extension_install_checker_unittest.cc b/chrome/browser/extensions/extension_install_checker_unittest.cc index f70d9dd..fb6b9e6 100644 --- a/chrome/browser/extensions/extension_install_checker_unittest.cc +++ b/chrome/browser/extensions/extension_install_checker_unittest.cc
@@ -18,10 +18,6 @@ const char kDummyRequirementsError[] = "Requirements error"; const char kDummyPolicyError[] = "Cannot install extension"; -const char kDummyPolicyError2[] = "Another policy error"; -const char kDummyRequirementsError2[] = "Another requirements error"; -const BlacklistState kBlacklistState2 = BLACKLISTED_SECURITY_VULNERABILITY; - } // namespace // Stubs most of the checks since we are interested in validating the logic in @@ -29,8 +25,8 @@ // checks. class ExtensionInstallCheckerForTest : public ExtensionInstallChecker { public: - ExtensionInstallCheckerForTest() - : ExtensionInstallChecker(NULL), + ExtensionInstallCheckerForTest(int enabled_checks, bool fail_fast) + : ExtensionInstallChecker(nullptr, nullptr, enabled_checks, fail_fast), requirements_check_called_(false), blacklist_check_called_(false), policy_check_called_(false), @@ -50,21 +46,25 @@ bool blacklist_check_called() const { return blacklist_check_called_; } bool policy_check_called() const { return policy_check_called_; } - void MockCheckRequirements(int sequence_number) { + void MockCheckRequirements() { + if (!is_running()) + return; std::vector<std::string> errors; if (!requirements_error_.empty()) errors.push_back(requirements_error_); - OnRequirementsCheckDone(sequence_number, errors); + OnRequirementsCheckDone(errors); } - void MockCheckBlacklistState(int sequence_number) { - OnBlacklistStateCheckDone(sequence_number, blacklist_state_); + void MockCheckBlacklistState() { + if (!is_running()) + return; + OnBlacklistStateCheckDone(blacklist_state_); } protected: void CheckRequirements() override { requirements_check_called_ = true; - MockCheckRequirements(current_sequence_number()); + MockCheckRequirements(); } void CheckManagementPolicy() override { @@ -75,15 +75,7 @@ void CheckBlacklistState() override { blacklist_check_called_ = true; - MockCheckBlacklistState(current_sequence_number()); - } - - void ResetResults() override { - ExtensionInstallChecker::ResetResults(); - - requirements_check_called_ = false; - blacklist_check_called_ = false; - policy_check_called_ = false; + MockCheckBlacklistState(); } bool requirements_check_called_; @@ -99,6 +91,10 @@ // This class implements asynchronous mocks of the requirements and blacklist // checks. class ExtensionInstallCheckerAsync : public ExtensionInstallCheckerForTest { + public: + ExtensionInstallCheckerAsync(int enabled_checks, bool fail_fast) + : ExtensionInstallCheckerForTest(enabled_checks, fail_fast) {} + protected: void CheckRequirements() override { requirements_check_called_ = true; @@ -106,7 +102,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&ExtensionInstallCheckerForTest::MockCheckRequirements, - base::Unretained(this), current_sequence_number())); + base::Unretained(this))); } void CheckBlacklistState() override { @@ -115,7 +111,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&ExtensionInstallCheckerForTest::MockCheckBlacklistState, - base::Unretained(this), current_sequence_number())); + base::Unretained(this))); } }; @@ -148,40 +144,6 @@ ExtensionInstallCheckerTest() {} ~ExtensionInstallCheckerTest() override {} - void RunSecondInvocation(ExtensionInstallCheckerForTest* checker, - int checks_failed) { - EXPECT_GT(checks_failed, 0); - EXPECT_FALSE(checker->is_running()); - ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker); - - // Set up different return values. - checker->set_blacklist_state(kBlacklistState2); - checker->set_policy_check_error(kDummyPolicyError2); - checker->set_requirements_error(kDummyRequirementsError2); - - // Run the install checker again and ensure the second set of return values - // is received. - checker->Start( - ExtensionInstallChecker::CHECK_ALL, - false /* fail fast */, - base::Bind(&ExtensionInstallCheckerTest::ValidateSecondInvocation, - base::Unretained(this), - checker)); - } - - void ValidateSecondInvocation(ExtensionInstallCheckerForTest* checker, - int checks_failed) { - EXPECT_FALSE(checker->is_running()); - EXPECT_EQ(ExtensionInstallChecker::CHECK_REQUIREMENTS | - ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY, - checks_failed); - ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker); - - EXPECT_EQ(kBlacklistState2, checker->blacklist_state()); - ExpectPolicyError(kDummyPolicyError2, *checker); - ExpectRequirementsError(kDummyRequirementsError2, *checker); - } - protected: void SetAllErrors(ExtensionInstallCheckerForTest* checker) { checker->set_blacklist_state(kBlacklistStateError); @@ -242,14 +204,10 @@ } void RunChecker(ExtensionInstallCheckerForTest* checker, - bool fail_fast, - int checks_to_run, int expected_checks_run, int expected_result) { CheckObserver observer; - checker->Start(checks_to_run, - fail_fast, - base::Bind(&CheckObserver::OnChecksComplete, + checker->Start(base::Bind(&CheckObserver::OnChecksComplete, base::Unretained(&observer))); observer.Wait(); @@ -261,8 +219,6 @@ void DoRunAllChecksPass(ExtensionInstallCheckerForTest* checker) { RunChecker(checker, - false /* fail fast */, - ExtensionInstallChecker::CHECK_ALL, ExtensionInstallChecker::CHECK_ALL, 0); @@ -274,8 +230,6 @@ void DoRunAllChecksFail(ExtensionInstallCheckerForTest* checker) { SetAllErrors(checker); RunChecker(checker, - false /* fail fast */, - ExtensionInstallChecker::CHECK_ALL, ExtensionInstallChecker::CHECK_ALL, ExtensionInstallChecker::CHECK_ALL); @@ -284,35 +238,34 @@ ExpectBlacklistError(*checker); } - void DoRunSubsetOfChecks(ExtensionInstallCheckerForTest* checker) { - // Test check set 1. - int tests_to_run = ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY | - ExtensionInstallChecker::CHECK_REQUIREMENTS; - SetAllErrors(checker); - RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run); + void DoRunSubsetOfChecks(int checks_to_run) { + ExtensionInstallCheckerForTest sync_checker(checks_to_run, + /*fail_fast=*/false); + ExtensionInstallCheckerAsync async_checker(checks_to_run, + /*fail_fast=*/false); + ExtensionInstallCheckerForTest* checkers[] = { + &sync_checker, &async_checker, + }; - ExpectRequirementsError(*checker); - ExpectPolicyError(*checker); - ExpectBlacklistPass(*checker); + for (auto* checker : checkers) { + SetAllErrors(checker); + RunChecker(checker, checks_to_run, checks_to_run); - // Test check set 2. - tests_to_run = ExtensionInstallChecker::CHECK_BLACKLIST | - ExtensionInstallChecker::CHECK_REQUIREMENTS; - SetAllErrors(checker); - RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run); + if (checks_to_run & ExtensionInstallChecker::CHECK_REQUIREMENTS) + ExpectRequirementsError(*checker); + else + ExpectRequirementsPass(*checker); - ExpectRequirementsError(*checker); - ExpectPolicyPass(*checker); - ExpectBlacklistError(*checker); + if (checks_to_run & ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY) + ExpectPolicyError(*checker); + else + ExpectPolicyPass(*checker); - // Test a single check. - tests_to_run = ExtensionInstallChecker::CHECK_BLACKLIST; - SetAllErrors(checker); - RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run); - - ExpectRequirementsPass(*checker); - ExpectPolicyPass(*checker); - ExpectBlacklistError(*checker); + if (checks_to_run & ExtensionInstallChecker::CHECK_BLACKLIST) + ExpectBlacklistError(*checker); + else + ExpectBlacklistPass(*checker); + } } private: @@ -320,108 +273,66 @@ base::MessageLoop message_loop; }; -class ExtensionInstallCheckerMultipleInvocationTest - : public ExtensionInstallCheckerTest { - public: - ExtensionInstallCheckerMultipleInvocationTest() : callback_count_(0) {} - ~ExtensionInstallCheckerMultipleInvocationTest() override {} - - void RunSecondInvocation(ExtensionInstallCheckerForTest* checker, - int checks_failed) { - ASSERT_EQ(0, callback_count_); - ++callback_count_; - EXPECT_FALSE(checker->is_running()); - EXPECT_GT(checks_failed, 0); - ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker); - - // Set up different return values. - checker->set_blacklist_state(kBlacklistState2); - checker->set_policy_check_error(kDummyPolicyError2); - checker->set_requirements_error(kDummyRequirementsError2); - - // Run the install checker again and ensure the second set of return values - // is received. - checker->Start(ExtensionInstallChecker::CHECK_ALL, - false /* fail fast */, - base::Bind(&ExtensionInstallCheckerMultipleInvocationTest:: - ValidateSecondInvocation, - base::Unretained(this), - checker)); - } - - void ValidateSecondInvocation(ExtensionInstallCheckerForTest* checker, - int checks_failed) { - ASSERT_EQ(1, callback_count_); - EXPECT_FALSE(checker->is_running()); - EXPECT_EQ(ExtensionInstallChecker::CHECK_REQUIREMENTS | - ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY, - checks_failed); - ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker); - - EXPECT_EQ(kBlacklistState2, checker->blacklist_state()); - ExpectPolicyError(kDummyPolicyError2, *checker); - ExpectRequirementsError(kDummyRequirementsError2, *checker); - } - - private: - int callback_count_; -}; - // Test the case where all tests pass. TEST_F(ExtensionInstallCheckerTest, AllSucceeded) { - ExtensionInstallCheckerForTest sync_checker; + ExtensionInstallCheckerForTest sync_checker( + ExtensionInstallChecker::CHECK_ALL, /*fail_fast=*/false); DoRunAllChecksPass(&sync_checker); - ExtensionInstallCheckerAsync async_checker; + ExtensionInstallCheckerAsync async_checker(ExtensionInstallChecker::CHECK_ALL, + /*fail_fast=*/false); DoRunAllChecksPass(&async_checker); } // Test the case where all tests fail. TEST_F(ExtensionInstallCheckerTest, AllFailed) { - ExtensionInstallCheckerForTest sync_checker; + ExtensionInstallCheckerForTest sync_checker( + ExtensionInstallChecker::CHECK_ALL, /*fail_fast=*/false); DoRunAllChecksFail(&sync_checker); - ExtensionInstallCheckerAsync async_checker; + ExtensionInstallCheckerAsync async_checker(ExtensionInstallChecker::CHECK_ALL, + /*fail_fast=*/false); DoRunAllChecksFail(&async_checker); } // Test running only a subset of tests. TEST_F(ExtensionInstallCheckerTest, RunSubsetOfChecks) { - ExtensionInstallCheckerForTest sync_checker; - ExtensionInstallCheckerAsync async_checker; - DoRunSubsetOfChecks(&sync_checker); - DoRunSubsetOfChecks(&async_checker); + DoRunSubsetOfChecks(ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY | + ExtensionInstallChecker::CHECK_REQUIREMENTS); + DoRunSubsetOfChecks(ExtensionInstallChecker::CHECK_BLACKLIST | + ExtensionInstallChecker::CHECK_REQUIREMENTS); + DoRunSubsetOfChecks(ExtensionInstallChecker::CHECK_BLACKLIST); } // Test fail fast with synchronous callbacks. TEST_F(ExtensionInstallCheckerTest, FailFastSync) { // This test assumes some internal knowledge of the implementation - that // the policy check runs first. - ExtensionInstallCheckerForTest checker; - SetAllErrors(&checker); - RunChecker(&checker, - true /* fail fast */, - ExtensionInstallChecker::CHECK_ALL, - ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY, - ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY); + { + ExtensionInstallCheckerForTest checker(ExtensionInstallChecker::CHECK_ALL, + /*fail_fast=*/true); + SetAllErrors(&checker); + RunChecker(&checker, ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY, + ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY); - ExpectRequirementsPass(checker); - ExpectPolicyError(checker); - ExpectBlacklistPass(checker); + ExpectRequirementsPass(checker); + ExpectPolicyError(checker); + ExpectBlacklistPass(checker); + } - // This test assumes some internal knowledge of the implementation - that - // the requirements check runs before the blacklist check. - SetAllErrors(&checker); - RunChecker(&checker, - true /* fail fast */, - ExtensionInstallChecker::CHECK_REQUIREMENTS | - ExtensionInstallChecker::CHECK_BLACKLIST, - ExtensionInstallChecker::CHECK_REQUIREMENTS, - ExtensionInstallChecker::CHECK_REQUIREMENTS); + { + ExtensionInstallCheckerForTest checker( + ExtensionInstallChecker::CHECK_REQUIREMENTS | + ExtensionInstallChecker::CHECK_BLACKLIST, + /*fail_fast=*/true); + SetAllErrors(&checker); + RunChecker(&checker, ExtensionInstallChecker::CHECK_REQUIREMENTS, + ExtensionInstallChecker::CHECK_REQUIREMENTS); - ExpectRequirementsError(checker); - ExpectPolicyPass(checker); - ExpectBlacklistPass(checker); + ExpectRequirementsError(checker); + ExpectPolicyPass(checker); + ExpectBlacklistPass(checker); + } } // Test fail fast with asynchronous callbacks. @@ -430,7 +341,9 @@ // the requirements check runs before the blacklist check. Both checks should // be called, but the requirements check callback arrives first and the // blacklist result will be discarded. - ExtensionInstallCheckerAsync checker; + ExtensionInstallCheckerAsync checker(ExtensionInstallChecker::CHECK_ALL, + /*fail_fast=*/true); + SetAllErrors(&checker); // The policy check is synchronous and needs to pass for the other tests to @@ -438,8 +351,6 @@ checker.set_policy_check_error(std::string()); RunChecker(&checker, - true /* fail fast */, - ExtensionInstallChecker::CHECK_ALL, ExtensionInstallChecker::CHECK_ALL, ExtensionInstallChecker::CHECK_REQUIREMENTS); @@ -448,41 +359,4 @@ ExpectBlacklistPass(checker); } -// Test multiple invocations of the install checker. Wait for all checks to -// complete. -TEST_F(ExtensionInstallCheckerMultipleInvocationTest, CompleteAll) { - ExtensionInstallCheckerAsync checker; - SetAllErrors(&checker); - - // Start the second check as soon as the callback of the first run is invoked. - checker.Start( - ExtensionInstallChecker::CHECK_ALL, - false /* fail fast */, - base::Bind( - &ExtensionInstallCheckerMultipleInvocationTest::RunSecondInvocation, - base::Unretained(this), - &checker)); - base::RunLoop().RunUntilIdle(); -} - -// Test multiple invocations of the install checker and fail fast. -TEST_F(ExtensionInstallCheckerMultipleInvocationTest, FailFast) { - ExtensionInstallCheckerAsync checker; - SetAllErrors(&checker); - - // The policy check is synchronous and needs to pass for the other tests to - // run. - checker.set_policy_check_error(std::string()); - - // Start the second check as soon as the callback of the first run is invoked. - checker.Start( - ExtensionInstallChecker::CHECK_ALL, - true /* fail fast */, - base::Bind( - &ExtensionInstallCheckerMultipleInvocationTest::RunSecondInvocation, - base::Unretained(this), - &checker)); - base::RunLoop().RunUntilIdle(); -} - } // namespace extensions
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index c3b026a..689f719a 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -2888,16 +2888,10 @@ EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx)); } -#if defined(OS_CHROMEOS) -// Always fails on ChromeOS: http://crbug.com/79737 -#define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx -#else -#define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx -#endif // Test updating a pending CRX as if the source is an external extension // with an update URL. In this case we don't know if the CRX is a theme // or not. -TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) { +TEST_F(ExtensionServiceTest, UpdatePendingExternalCrx) { InitializeEmptyExtensionService(); EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl( theme_crx,
diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc index 02e59d90..148113f3 100644 --- a/chrome/browser/extensions/unpacked_installer.cc +++ b/chrome/browser/extensions/unpacked_installer.cc
@@ -7,9 +7,11 @@ #include "base/bind.h" #include "base/callback.h" #include "base/files/file_util.h" +#include "base/memory/ptr_util.h" #include "base/strings/string_util.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/extension_error_reporter.h" +#include "chrome/browser/extensions/extension_install_checker.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_management.h" #include "chrome/browser/extensions/extension_service.h" @@ -110,10 +112,10 @@ UnpackedInstaller::UnpackedInstaller(ExtensionService* extension_service) : service_weak_(extension_service->AsWeakPtr()), + profile_(extension_service->profile()), prompt_for_plugins_(true), require_modern_manifest_version_(true), - be_noisy_on_failure_(true), - install_checker_(extension_service->profile()) { + be_noisy_on_failure_(true) { DCHECK_CURRENTLY_ON(BrowserThread::UI); } @@ -149,9 +151,8 @@ } std::string error; - install_checker_.set_extension( - file_util::LoadExtension( - extension_path_, Manifest::COMMAND_LINE, GetFlags(), &error).get()); + extension_ = file_util::LoadExtension(extension_path_, Manifest::COMMAND_LINE, + GetFlags(), &error); if (!extension() || !extension_l10n_util::ValidateExtensionLocales( @@ -195,8 +196,7 @@ PluginInfo::HasPlugins(extension()) && !disabled_extensions.Contains(extension()->id())) { SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt( - extension(), - install_checker_.profile(), + extension(), profile_, base::Bind(&UnpackedInstaller::StartInstallChecks, this)); prompt->ShowPrompt(); return; @@ -241,24 +241,26 @@ } } - install_checker_.Start( + install_checker_ = base::MakeUnique<ExtensionInstallChecker>( + profile_, extension_, ExtensionInstallChecker::CHECK_REQUIREMENTS | ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY, - true /* fail fast */, + true /* fail fast */); + install_checker_->Start( base::Bind(&UnpackedInstaller::OnInstallChecksComplete, this)); } void UnpackedInstaller::OnInstallChecksComplete(int failed_checks) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!install_checker_.policy_error().empty()) { - ReportExtensionLoadError(install_checker_.policy_error()); + if (!install_checker_->policy_error().empty()) { + ReportExtensionLoadError(install_checker_->policy_error()); return; } - if (!install_checker_.requirement_errors().empty()) { + if (!install_checker_->requirement_errors().empty()) { ReportExtensionLoadError( - base::JoinString(install_checker_.requirement_errors(), " ")); + base::JoinString(install_checker_->requirement_errors(), " ")); return; } @@ -329,9 +331,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::FILE); std::string error; - install_checker_.set_extension( - file_util::LoadExtension( - extension_path_, Manifest::UNPACKED, flags, &error).get()); + extension_ = file_util::LoadExtension(extension_path_, Manifest::UNPACKED, + flags, &error); if (!extension() || !extension_l10n_util::ValidateExtensionLocales(
diff --git a/chrome/browser/extensions/unpacked_installer.h b/chrome/browser/extensions/unpacked_installer.h index c0416a2..e145bef 100644 --- a/chrome/browser/extensions/unpacked_installer.h +++ b/chrome/browser/extensions/unpacked_installer.h
@@ -14,13 +14,14 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/extensions/extension_install_checker.h" class ExtensionService; +class Profile; namespace extensions { class Extension; +class ExtensionInstallChecker; // Installs and loads an unpacked extension. Because internal state needs to be // held about the instalation process, only one call to Load*() should be made @@ -117,15 +118,21 @@ // Helper to get the Extension::CreateFlags for the installing extension. int GetFlags(); - const Extension* extension() { return install_checker_.extension().get(); } + const Extension* extension() { return extension_.get(); } // The service we will report results back to. base::WeakPtr<ExtensionService> service_weak_; + // The Profile the extension is being installed in. + Profile* profile_; + // The pathname of the directory to load from, which is an absolute path // after GetAbsolutePath has been called. base::FilePath extension_path_; + // The extension being installed. + scoped_refptr<const Extension> extension_; + // If true and the extension contains plugins, we prompt the user before // loading. bool prompt_for_plugins_; @@ -139,7 +146,7 @@ // Checks management policies and requirements before the extension can be // installed. - ExtensionInstallChecker install_checker_; + std::unique_ptr<ExtensionInstallChecker> install_checker_; CompletionCallback callback_;
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc index 06cbc5c..8f66c1ad 100644 --- a/chrome/browser/first_run/first_run.cc +++ b/chrome/browser/first_run/first_run.cc
@@ -55,6 +55,7 @@ #include "chrome/installer/util/master_preferences.h" #include "chrome/installer/util/master_preferences_constants.h" #include "chrome/installer/util/util_constants.h" +#include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/search_engines/template_url_service.h" #include "components/signin/core/browser/signin_manager.h" @@ -198,56 +199,6 @@ } } -// Sets the |items| bitfield according to whether the import data specified by -// |import_type| should be be auto imported or not. -void SetImportItem(PrefService* user_prefs, - const char* pref_path, - int import_items, - int dont_import_items, - importer::ImportItem import_type, - int* items) { - // Work out whether an item is to be imported according to what is specified - // in master preferences. - bool should_import = false; - bool master_pref_set = - ((import_items | dont_import_items) & import_type) != 0; - bool master_pref = ((import_items & ~dont_import_items) & import_type) != 0; - - if (import_type == importer::HISTORY || - (import_type != importer::FAVORITES && - first_run::internal::IsOrganicFirstRun())) { - // History is always imported unless turned off in master_preferences. - // Search engines and home page are imported in organic builds only - // unless turned off in master_preferences. - should_import = !master_pref_set || master_pref; - } else { - // Bookmarks are never imported, unless turned on in master_preferences. - // Search engine and home page import behaviour is similar in non organic - // builds. - should_import = master_pref_set && master_pref; - } - - // If an import policy is set, import items according to policy. If no master - // preference is set, but a corresponding recommended policy is set, import - // item according to recommended policy. If both a master preference and a - // recommended policy is set, the master preference wins. If neither - // recommended nor managed policies are set, import item according to what we - // worked out above. - if (master_pref_set) - user_prefs->SetBoolean(pref_path, should_import); - - if (!user_prefs->FindPreference(pref_path)->IsDefaultValue()) { - if (user_prefs->GetBoolean(pref_path)) - *items |= import_type; - } else { - // no policy (recommended or managed) is set - if (should_import) - *items |= import_type; - } - - user_prefs->ClearPref(pref_path); -} - // Launches the import, via |importer_host|, from |source_profile| into // |target_profile| for the items specified in the |items_to_import| bitfield. // This may be done in a separate process depending on the platform, but it will @@ -298,19 +249,16 @@ // Imports settings from the first profile in |importer_list|. void ImportSettings(Profile* profile, std::unique_ptr<ImporterList> importer_list, - int items_to_import) { + uint16_t items_to_import) { + DCHECK(items_to_import); const importer::SourceProfile& source_profile = importer_list->GetSourceProfileAt(0); - // If no items to import then skip entirely. - if (!items_to_import) - return; // Ensure that importers aren't requested to import items that they do not // support. If there is no overlap, skip. items_to_import &= source_profile.services_supported; - if (items_to_import) { + if (items_to_import) ImportFromSourceProfile(source_profile, profile, items_to_import); - } g_auto_import_state |= first_run::AUTO_IMPORT_PROFILE_IMPORTED; } @@ -495,57 +443,16 @@ ConvertStringVectorToGURLVector( install_prefs.GetFirstRunTabs(), &out_prefs->new_tabs); - bool value = false; - if (install_prefs.GetBool( - installer::master_preferences::kDistroImportSearchPref, &value)) { - if (value) { - out_prefs->do_import_items |= importer::SEARCH_ENGINES; - } else { - out_prefs->dont_import_items |= importer::SEARCH_ENGINES; - } - } - // If we're suppressing the first-run bubble, set that preference now. // Otherwise, wait until the user has completed first run to set it, so the // user is guaranteed to see the bubble iff they have completed the first run // process. + bool value = false; if (install_prefs.GetBool( installer::master_preferences::kDistroSuppressFirstRunBubble, - &value) && value) + &value) && + value) { SetShowFirstRunBubblePref(FIRST_RUN_BUBBLE_SUPPRESS); - - if (install_prefs.GetBool( - installer::master_preferences::kDistroImportHistoryPref, - &value)) { - if (value) { - out_prefs->do_import_items |= importer::HISTORY; - } else { - out_prefs->dont_import_items |= importer::HISTORY; - } - } - - std::string not_used; - out_prefs->homepage_defined = install_prefs.GetString( - prefs::kHomePage, ¬_used); - - if (install_prefs.GetBool( - installer::master_preferences::kDistroImportHomePagePref, - &value)) { - if (value) { - out_prefs->do_import_items |= importer::HOME_PAGE; - } else { - out_prefs->dont_import_items |= importer::HOME_PAGE; - } - } - - // Bookmarks are never imported unless specifically turned on. - if (install_prefs.GetBool( - installer::master_preferences::kDistroImportBookmarksPref, - &value)) { - if (value) - out_prefs->do_import_items |= importer::FAVORITES; - else - out_prefs->dont_import_items |= importer::FAVORITES; } if (install_prefs.GetBool( @@ -616,15 +523,19 @@ } // namespace internal -MasterPrefs::MasterPrefs() - : homepage_defined(false), - do_import_items(0), - dont_import_items(0), - make_chrome_default_for_user(false), - suppress_first_run_default_browser_prompt(false), - welcome_page_on_os_upgrade_enabled(true) {} +MasterPrefs::MasterPrefs() = default; -MasterPrefs::~MasterPrefs() {} +MasterPrefs::~MasterPrefs() = default; + +void RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterBooleanPref(prefs::kImportAutofillFormData, false); + registry->RegisterBooleanPref(prefs::kImportBookmarks, false); + registry->RegisterBooleanPref(prefs::kImportHistory, false); + registry->RegisterBooleanPref(prefs::kImportHomepage, false); + registry->RegisterBooleanPref(prefs::kImportSavedPasswords, false); + registry->RegisterBooleanPref(prefs::kImportSearchEngine, false); +} bool IsChromeFirstRun() { if (g_first_run == internal::FIRST_RUN_UNKNOWN) { @@ -756,84 +667,56 @@ void AutoImport( Profile* profile, - bool homepage_defined, - int import_items, - int dont_import_items, const std::string& import_bookmarks_path) { - base::FilePath local_state_path; - PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); - bool local_state_file_exists = base::PathExists(local_state_path); - - // It may be possible to do the if block below asynchronously. In which case, - // get rid of this RunLoop. http://crbug.com/366116. - base::RunLoop run_loop; - std::unique_ptr<ImporterList> importer_list(new ImporterList()); - importer_list->DetectSourceProfiles( - g_browser_process->GetApplicationLocale(), - false, // include_interactive_profiles? - run_loop.QuitClosure()); - run_loop.Run(); - - // Do import if there is an available profile for us to import. - if (importer_list->count() > 0) { - if (internal::IsOrganicFirstRun()) { - // Home page is imported in organic builds only unless turned off or - // defined in master_preferences. - if (homepage_defined) { - dont_import_items |= importer::HOME_PAGE; - if (import_items & importer::HOME_PAGE) - import_items &= ~importer::HOME_PAGE; - } - // Search engines are not imported automatically in organic builds if the - // user already has a user preferences directory. - if (local_state_file_exists) { - dont_import_items |= importer::SEARCH_ENGINES; - if (import_items & importer::SEARCH_ENGINES) - import_items &= ~importer::SEARCH_ENGINES; - } - } - - PrefService* user_prefs = profile->GetPrefs(); - int items = 0; - - SetImportItem(user_prefs, - prefs::kImportHistory, - import_items, - dont_import_items, - importer::HISTORY, - &items); - SetImportItem(user_prefs, - prefs::kImportHomepage, - import_items, - dont_import_items, - importer::HOME_PAGE, - &items); - SetImportItem(user_prefs, - prefs::kImportSearchEngine, - import_items, - dont_import_items, - importer::SEARCH_ENGINES, - &items); - SetImportItem(user_prefs, - prefs::kImportBookmarks, - import_items, - dont_import_items, - importer::FAVORITES, - &items); - - importer::LogImporterUseToMetrics( - "AutoImport", importer_list->GetSourceProfileAt(0).importer_type); - - ImportSettings(profile, std::move(importer_list), items); - } - - if (!import_bookmarks_path.empty()) { - ImportFromFile(profile, import_bookmarks_path); - } - - content::RecordAction(UserMetricsAction("FirstRunDef_Accept")); - g_auto_import_state |= AUTO_IMPORT_CALLED; + + // Use |profile|'s PrefService to determine what to import. It will reflect in + // order: + // 1) Policies. + // 2) Master preferences (used to initialize user prefs in + // ProcessMasterPreferences()). + // 3) Recommended policies. + // 4) Registered default. + PrefService* prefs = profile->GetPrefs(); + uint16_t items_to_import = 0; + static constexpr struct { + const char* pref_path; + importer::ImportItem bit; + } kImportItems[] = { + {prefs::kImportAutofillFormData, importer::AUTOFILL_FORM_DATA}, + {prefs::kImportBookmarks, importer::FAVORITES}, + {prefs::kImportHistory, importer::HISTORY}, + {prefs::kImportHomepage, importer::HOME_PAGE}, + {prefs::kImportSavedPasswords, importer::PASSWORDS}, + {prefs::kImportSearchEngine, importer::SEARCH_ENGINES}, + }; + + for (const auto& import_item : kImportItems) { + if (prefs->GetBoolean(import_item.pref_path)) + items_to_import |= import_item.bit; + } + + if (items_to_import) { + // It may be possible to do the if block below asynchronously. In which + // case, get rid of this RunLoop. http://crbug.com/366116. + base::RunLoop run_loop; + auto importer_list = base::MakeUnique<ImporterList>(); + importer_list->DetectSourceProfiles( + g_browser_process->GetApplicationLocale(), + false, // include_interactive_profiles? + run_loop.QuitClosure()); + run_loop.Run(); + + if (importer_list->count() > 0) { + importer::LogImporterUseToMetrics( + "AutoImport", importer_list->GetSourceProfileAt(0).importer_type); + + ImportSettings(profile, std::move(importer_list), items_to_import); + } + } + + if (!import_bookmarks_path.empty()) + ImportFromFile(profile, import_bookmarks_path); } void DoPostImportTasks(Profile* profile, bool make_chrome_default_for_user) {
diff --git a/chrome/browser/first_run/first_run.h b/chrome/browser/first_run/first_run.h index 725dade..93f4484 100644 --- a/chrome/browser/first_run/first_run.h +++ b/chrome/browser/first_run/first_run.h
@@ -24,6 +24,10 @@ class WebContents; } +namespace user_prefs { +class PrefRegistrySyncable; +} + // This namespace contains the chrome first-run installation actions needed to // fully test the custom installer. It also contains the opposite actions to // execute during uninstall. When the first run UI is ready we won't @@ -71,12 +75,9 @@ // remove items from here which are being stored temporarily only to be later // dumped into local_state. Also see related TODO in chrome_browser_main.cc. - bool homepage_defined; - int do_import_items; - int dont_import_items; - bool make_chrome_default_for_user; - bool suppress_first_run_default_browser_prompt; - bool welcome_page_on_os_upgrade_enabled; + bool make_chrome_default_for_user = false; + bool suppress_first_run_default_browser_prompt = false; + bool welcome_page_on_os_upgrade_enabled = true; std::vector<GURL> new_tabs; std::vector<GURL> bookmarks; std::string import_bookmarks_path; @@ -86,6 +87,9 @@ std::string suppress_default_browser_prompt_for_version; }; +void RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry); + // Returns true if Chrome should behave as if this is the first time Chrome is // run for this user. bool IsChromeFirstRun(); @@ -151,13 +155,10 @@ // Log a metric for the "FirstRun.SearchEngineBubble" histogram. void LogFirstRunMetric(FirstRunBubbleMetric metric); -// Automatically import history and home page (and search engine, if -// ShouldShowSearchEngineDialog is true). Also imports bookmarks from file if +// Automatically imports items requested by |profile|'s configuration (sum of +// policies and master prefs). Also imports bookmarks from file if // |import_bookmarks_path| is not empty. void AutoImport(Profile* profile, - bool homepage_defined, - int import_items, - int dont_import_items, const std::string& import_bookmarks_path); // Does remaining first run tasks. This can pop the first run consent dialog on
diff --git a/chrome/browser/first_run/first_run_browsertest.cc b/chrome/browser/first_run/first_run_browsertest.cc index 90250a4..321d37a 100644 --- a/chrome/browser/first_run/first_run_browsertest.cc +++ b/chrome/browser/first_run/first_run_browsertest.cc
@@ -176,8 +176,32 @@ #else #define MAYBE_ImportDefault ImportDefault #endif +// No items are imported by default. IN_PROC_BROWSER_TEST_F(FirstRunMasterPrefsImportDefault, MAYBE_ImportDefault) { int auto_import_state = first_run::auto_import_state(); + EXPECT_EQ(MaskExpectedImportState(first_run::AUTO_IMPORT_CALLED), + auto_import_state); +} + +extern const char kImportAll[] = + "{\n" + " \"distribution\": {\n" + " \"import_bookmarks\": true,\n" + " \"import_history\": true,\n" + " \"import_home_page\": true,\n" + " \"import_search_engine\": true\n" + " }\n" + "}\n"; +typedef FirstRunMasterPrefsBrowserTestT<kImportAll> + FirstRunMasterPrefsImportAll; +// http://crbug.com/314221 +#if defined(OS_MACOSX) || (defined(GOOGLE_CHROME_BUILD) && defined(OS_LINUX)) +#define MAYBE_ImportAll DISABLED_ImportAll +#else +#define MAYBE_ImportAll ImportAll +#endif +IN_PROC_BROWSER_TEST_F(FirstRunMasterPrefsImportAll, MAYBE_ImportAll) { + int auto_import_state = first_run::auto_import_state(); EXPECT_EQ(MaskExpectedImportState(first_run::AUTO_IMPORT_CALLED | first_run::AUTO_IMPORT_PROFILE_IMPORTED), auto_import_state); @@ -204,7 +228,6 @@ int auto_import_state = first_run::auto_import_state(); EXPECT_EQ( MaskExpectedImportState(first_run::AUTO_IMPORT_CALLED | - first_run::AUTO_IMPORT_PROFILE_IMPORTED | first_run::AUTO_IMPORT_BOOKMARKS_FILE_IMPORTED), auto_import_state); }
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 5719a73..c9f6e1c 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -1599,33 +1599,24 @@ // Test that if a form gets autofilled, then it gets autofilled on re-creation // as well. -// TODO(vabr): This is flaky everywhere. http://crbug.com/442704 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, - DISABLED_ReCreatedFormsGetFilled) { - NavigateToFile("/password/dynamic_password_form.html"); + ReCreatedFormsGetFilled) { + // At first let us save a credential to the password store. + scoped_refptr<password_manager::TestPasswordStore> password_store = + static_cast<password_manager::TestPasswordStore*>( + PasswordStoreFactory::GetForProfile( + browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS) + .get()); + autofill::PasswordForm signin_form; + signin_form.signon_realm = embedded_test_server()->base_url().spec(); + signin_form.origin = embedded_test_server()->base_url(); + signin_form.action = embedded_test_server()->base_url(); + signin_form.username_value = base::ASCIIToUTF16("temp"); + signin_form.password_value = base::ASCIIToUTF16("random"); + password_store->AddLogin(signin_form); - // Fill in the credentials, and make sure they are saved. - NavigationObserver form_submit_observer(WebContents()); - std::unique_ptr<BubbleObserver> prompt_observer( - new BubbleObserver(WebContents())); - std::string create_fill_and_submit = - "document.getElementById('create_form_button').click();" - "window.setTimeout(function() {" - " var form = document.getElementById('dynamic_form_id');" - " form.username.value = 'temp';" - " form.password.value = 'random';" - " form.submit();" - "}, 0)"; - ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_fill_and_submit)); - form_submit_observer.Wait(); - EXPECT_TRUE(prompt_observer->IsShowingSavePrompt()); - prompt_observer->AcceptSavePrompt(); - - // Reload the original page to have the saved credentials autofilled. - NavigationObserver reload_observer(WebContents()); NavigateToFile("/password/dynamic_password_form.html"); - reload_observer.Wait(); - std::string create_form = + const std::string create_form = "document.getElementById('create_form_button').click();"; ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_form)); // Wait until the username is filled, to make sure autofill kicked in. @@ -1633,7 +1624,7 @@ // Now the form gets deleted and created again. It should get autofilled // again. - std::string delete_form = + const std::string delete_form = "var form = document.getElementById('dynamic_form_id');" "form.parentNode.removeChild(form);"; ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), delete_form));
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index ec501abe..e4e93d66 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/path_service.h" +#include "base/strings/pattern.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" @@ -71,12 +72,13 @@ const int kDefaultKeyModifier = blink::WebInputEvent::ControlKey; #endif -// Using ASSERT_TRUE deliberately instead of ASSERT_EQ or ASSERT_STREQ -// in order to print a more readable message if the strings differ. -#define ASSERT_MULTILINE_STREQ(expected, actual) \ - ASSERT_TRUE(expected == actual) \ - << "Expected:\n" << expected \ - << "\n\nActual:\n" << actual +// Check if the |actual| string matches the string or the string pattern in +// |pattern| and print a readable message if it does not match. +#define ASSERT_MULTILINE_STR_MATCHES(pattern, actual) \ + ASSERT_TRUE(base::MatchPattern(actual, pattern)) \ + << "Expected match pattern:\n" \ + << pattern << "\n\nActual:\n" \ + << actual bool GetGuestCallback(WebContents** guest_out, WebContents* guest) { EXPECT_FALSE(*guest_out); @@ -594,8 +596,7 @@ ax_tree_dump += ui::ToString(node.role); std::string name = node.GetStringAttribute(ui::AX_ATTR_NAME); - base::ReplaceChars(name, "\r", "\\r", &name); - base::ReplaceChars(name, "\n", "\\n", &name); + base::ReplaceChars(name, "\r\n", "", &name); if (!name.empty()) ax_tree_dump += " '" + name + "'"; ax_tree_dump += "\n"; @@ -606,38 +607,41 @@ return ax_tree_dump; } -static const char kExpectedPDFAXTree[] = +// This is a pattern with a few wildcards due to a PDF bug where the +// fi ligature is not parsed correctly on some systems. +// http://crbug.com/701427 + +static const char kExpectedPDFAXTreePattern[] = "embeddedObject\n" " group\n" " region 'Page 1'\n" " paragraph\n" - " staticText '1 First Section\\r\\n'\n" + " staticText '1 First Section'\n" " inlineTextBox '1 '\n" - " inlineTextBox 'First Section\\r\\n'\n" + " inlineTextBox 'First Section'\n" " paragraph\n" - " staticText 'This is the first section.\\r\\n1'\n" - " inlineTextBox 'This is the first section.\\r\\n'\n" + " staticText 'This is the *rst section.1'\n" + " inlineTextBox 'This is the *rst section.'\n" " inlineTextBox '1'\n" " region 'Page 2'\n" " paragraph\n" - " staticText '1.1 First Subsection\\r\\n'\n" + " staticText '1.1 First Subsection'\n" " inlineTextBox '1.1 '\n" - " inlineTextBox 'First Subsection\\r\\n'\n" + " inlineTextBox 'First Subsection'\n" " paragraph\n" - " staticText 'This is the first subsection.\\r\\n2'\n" - " inlineTextBox 'This is the first subsection.\\r\\n'\n" + " staticText 'This is the *rst subsection.2'\n" + " inlineTextBox 'This is the *rst subsection.'\n" " inlineTextBox '2'\n" " region 'Page 3'\n" " paragraph\n" - " staticText '2 Second Section\\r\\n'\n" + " staticText '2 Second Section'\n" " inlineTextBox '2 '\n" - " inlineTextBox 'Second Section\\r\\n'\n" + " inlineTextBox 'Second Section'\n" " paragraph\n" " staticText '3'\n" " inlineTextBox '3'\n"; -// https://crbug.com/701427 -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DISABLED_PdfAccessibility) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibility) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); @@ -648,7 +652,8 @@ "1 First Section\r\n"); ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents); std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree); - ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump); + + ASSERT_MULTILINE_STR_MATCHES(kExpectedPDFAXTreePattern, ax_tree_dump); } #if defined(GOOGLE_CHROME_BUILD) @@ -666,8 +671,7 @@ } #endif -// https://crbug.com/701427 -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DISABLED_PdfAccessibilityEnableLater) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityEnableLater) { // In this test, load the PDF file first, with accessibility off. GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf")); WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); @@ -680,7 +684,7 @@ "1 First Section\r\n"); ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents); std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree); - ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump); + ASSERT_MULTILINE_STR_MATCHES(kExpectedPDFAXTreePattern, ax_tree_dump); } bool RetrieveGuestContents(WebContents** out_guest_contents, @@ -689,8 +693,7 @@ return true; } -// https://crbug.com/701427 -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DISABLED_PdfAccessibilityInIframe) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityInIframe) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_iframe_url(embedded_test_server()->GetURL("/pdf/test-iframe.html")); ui_test_utils::NavigateToURL(browser(), test_iframe_url); @@ -708,11 +711,10 @@ ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents); std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree); - ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump); + ASSERT_MULTILINE_STR_MATCHES(kExpectedPDFAXTreePattern, ax_tree_dump); } -// https://crbug.com/701427 -IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DISABLED_PdfAccessibilityInOOPIF) { +IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityInOOPIF) { content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); GURL test_iframe_url(embedded_test_server()->GetURL( "/pdf/test-cross-site-iframe.html")); @@ -731,7 +733,7 @@ ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents); std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree); - ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump); + ASSERT_MULTILINE_STR_MATCHES(kExpectedPDFAXTreePattern, ax_tree_dump); } #if defined(GOOGLE_CHROME_BUILD)
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 4a6504d..c376de4 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -583,6 +583,7 @@ #if !defined(OS_ANDROID) browser_sync::ForeignSessionHandler::RegisterProfilePrefs(registry); + first_run::RegisterProfilePrefs(registry); gcm::GCMChannelStatusSyncer::RegisterProfilePrefs(registry); gcm::RegisterProfilePrefs(registry); StartupBrowserCreator::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/resources/chromeos/about_os_credits.html b/chrome/browser/resources/chromeos/about_os_credits.html index 5e7caabf..f03cc8a 100644 --- a/chrome/browser/resources/chromeos/about_os_credits.html +++ b/chrome/browser/resources/chromeos/about_os_credits.html
@@ -6,8 +6,8 @@ <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <style> body { - background-color:white; - max-width:1020px; + background-color: white; + max-width: 1020px; } </style> </head> @@ -17,8 +17,9 @@ <a href="http://dev.chromium.org/chromium-os/licensing-for-chromiumos-package-owners">Licensing for Chromium OS Package Owners</a></p> <p> If you need to change styles, fonts, layout, etc of <a href="chrome://os_credits">chrome://os_credits</a> page, -edit <a href="https://chromium.googlesource.com/chromiumos/chromite/+/master/licensing/about_credits.tmpl">chromite/licensing/about_credits.tmpl</a>. +edit <a href="https://chromium.googlesource.com/chromiumos/chromite/+/master/licensing/about_credits.tmpl">chromite/licensing/about_credits.tmpl</a>. The template is used to generate a device-dependent about_os_credits.html when a CrOS image is built.</p> </body> +<script src="keyboard/keyboard_utils.js"></script> </html>
diff --git a/chrome/browser/resources/chromeos/demo_app/OWNERS b/chrome/browser/resources/chromeos/demo_app/OWNERS new file mode 100644 index 0000000..7642048 --- /dev/null +++ b/chrome/browser/resources/chromeos/demo_app/OWNERS
@@ -0,0 +1,2 @@ +hirono@chromium.org +oka@chromium.org
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html index a166666..206c4b05 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -27,6 +27,12 @@ <dom-module id="settings-basic-page"> <template> <style include="settings-page-styles"> + :host([is-subpage-animating]) { + /* Prevent an unwanted horizontal scrollbar when transitioning back from + * a sub-page. */ + overflow: hidden; + } + #advancedToggle { --paper-button: { text-transform: none;
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js index fa0b6848..ae0fc19b 100644 --- a/chrome/browser/resources/settings/route.js +++ b/chrome/browser/resources/settings/route.js
@@ -369,6 +369,11 @@ * parameter during navigation. Defaults to false. */ var navigateTo = function(route, opt_dynamicParameters, opt_removeSearch) { + // The ADVANCED route only serves as a parent of subpages, and should not + // be possible to navigate to it directly. + if (route == settings.Route.ADVANCED) + route = settings.Route.BASIC; + var params = opt_dynamicParameters || new URLSearchParams(); var removeSearch = !!opt_removeSearch;
diff --git a/chrome/browser/resources/settings/settings_page/main_page_behavior.js b/chrome/browser/resources/settings/settings_page/main_page_behavior.js index 6e7fe98..600499e7 100644 --- a/chrome/browser/resources/settings/settings_page/main_page_behavior.js +++ b/chrome/browser/resources/settings/settings_page/main_page_behavior.js
@@ -11,6 +11,16 @@ var MainPageBehaviorImpl = { properties: { /** + * Help CSS to alter style during the horizontal swipe animation. + * Note that this is unrelated to the |currentAnimation_| (which refers to + * the vertical exapand animation). + */ + isSubpageAnimating: { + reflectToAttribute: true, + type: Boolean, + }, + + /** * Whether a search operation is in progress or previous search results are * being displayed. * @private {boolean} @@ -25,6 +35,10 @@ /** @type {?HTMLElement} The scrolling container. */ scroller: null, + listeners: { + 'neon-animation-finish': 'onNeonAnimationFinish_' + }, + /** @override */ attached: function() { if (this.domHost && this.domHost.parentNode.tagName == 'PAPER-HEADER-PANEL') @@ -34,6 +48,17 @@ }, /** + * Remove the is-animating attribute once the animation is complete. + * This may catch animations finishing more often than needed, which is not + * known to cause any issues (e.g. when animating from a shallower page to a + * deeper page; or when transitioning to the main page). + * @private + */ + onNeonAnimationFinish_: function() { + this.isSubpageAnimating = false; + }, + + /** * @param {!settings.Route} newRoute * @param {settings.Route} oldRoute */ @@ -57,6 +82,9 @@ !settings.lastRouteChangeWasPopstate() || oldRouteWasSection || oldRoute == settings.Route.BASIC; + if (oldRoute && (oldRoute.isSubpage() || newRoute.isSubpage())) + this.isSubpageAnimating = true; + // For previously uncreated pages (including on first load), allow the page // to render before scrolling to or expanding the section. if (!oldRoute || this.scrollHeight == 0) @@ -120,6 +148,7 @@ // Need to exclude routes that correspond to 'non-sectioned' children of // ADVANCED, otherwise tryTransitionToSection_ will recurse endlessly. !currentRoute.isNavigableDialog) { + assert(currentRoute.section); promise = this.$$('#advancedPageTemplate').get(); }
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.css b/chrome/browser/resources/vr_shell/vr_shell_ui.css index 3693cf9..8b1f5b7 100644 --- a/chrome/browser/resources/vr_shell/vr_shell_ui.css +++ b/chrome/browser/resources/vr_shell/vr_shell_ui.css
@@ -86,16 +86,16 @@ } .round-button { - background-color: #eee; + background-color: #fbfbfb; background-position: center; background-repeat: no-repeat; - background-size: contain; - border-radius: 10%; - height: 96px; + background-size: 70px; + border-radius: 6px; + height: 112px; margin: auto auto; opacity: 0.8; - transition: opacity 150ms ease-in-out; - width: 96px; + transition: opacity 50ms ease-in-out; + width: 112px; } .button-caption { @@ -105,7 +105,7 @@ opacity: 0; overflow: hidden; text-align: center; - transition: opacity 150ms ease-in-out; + transition: opacity 50ms ease-in-out; white-space: nowrap; } @@ -129,7 +129,7 @@ } .disabled-button { - background-color: #aaa; + background-color: #bbb; } #back-button, @@ -149,13 +149,21 @@ } #reload-ui-button { + --rotX: -0.2; + --rotY: 0; + --rotZ: 0; + --scale: 1; + --tranX: 0; + --tranY: -0.7; + --tranZ: -0.4; + background-color: rgba(255,255,255,0.25); color: white; font-size: 24px; padding: 12px; } #reload-ui-button:hover { - background-color: pink; + background-color: turquoise; } #content-interceptor { @@ -204,25 +212,26 @@ } #url-indicator-container { + --scale: 1.2; --tranX: 0; - --tranY: -0.65; - --tranZ: -1.2; + --tranY: -0.75; + --tranZ: -1.8; } #url-indicator-border { - --fadeTimeMs: 500; - --fadeYOffset: -0.1; + --fadeTimeMs: 200; + --fadeYOffset: -0.05; --opacity: 0.9; --statusBarColor: rgb(66, 133, 244); background-color: #ececec; - border-radius: 200px; + border-radius: 6px; padding: 6px; } #url-indicator { align-items: center; background-color: #ececec; - border-radius: 200px; + border-radius: 6px; box-sizing: border-box; display: flex; height: 104px; @@ -275,14 +284,10 @@ } #omnibox-ui-element { - --tranX: 0; - --tranY: -0.1; - --tranZ: -1.0; background-color: transparent; box-sizing: border-box; - font-family: arial; font-size: 16px; - width: 400px; + width: 368px; } #suggestions { @@ -310,19 +315,23 @@ #omnibox-url-element { background-color: white; - border: 1px solid grey; + border-radius: 6px; box-sizing: border-box; display: flex; flex-direction: row-reverse; /* Right-justify for convienence. */ + height: 64px; margin-top: 2px; - padding: 5px; + padding: 8px; + transition: background-color 50ms ease-in-out; } #omnibox-input-field { + background-color: transparent; border: none; - font-size: 16px; + font-size: 27px; outline: none; /* Do not show an outline when focused. */ overflow: hidden; + text-align: center; white-space: nowrap; width: 100%; }
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.js b/chrome/browser/resources/vr_shell/vr_shell_ui.js index f01ace1..b7d3a8d33 100644 --- a/chrome/browser/resources/vr_shell/vr_shell_ui.js +++ b/chrome/browser/resources/vr_shell/vr_shell_ui.js
@@ -16,9 +16,9 @@ // This value should match the one in VrShellImpl.java /** @const */ var UI_DPR = 1.2; - function getStyleFloat(style, property) { + function getStyleFloat(style, property, defaultValue) { let value = parseFloat(style.getPropertyValue(property)); - return isNaN(value) ? 0 : value; + return isNaN(value) ? defaultValue : value; } function getStyleString(style, property) { @@ -28,16 +28,17 @@ class ContentQuad { constructor() { - /** @const */ this.SCREEN_HEIGHT = 1.6; - /** @const */ this.SCREEN_RATIO = 16 / 9; + /** @const */ this.SCREEN_HEIGHT = 1.375; + /** @const */ this.SCREEN_RATIO = 9.6 / 6.4; + /** @const */ this.BROWSING_SCREEN_ELEVATION = -0.15; /** @const */ this.BROWSING_SCREEN_DISTANCE = 2.0; /** @const */ this.FULLSCREEN_DISTANCE = 3.0; /** @const */ this.CSS_WIDTH_PIXELS = 960.0; /** @const */ this.CSS_HEIGHT_PIXELS = 640.0; /** @const */ this.DPR = 1.2; /** @const */ this.MENU_MODE_SCREEN_DISTANCE = 2.0; - /** @const */ this.MENU_MODE_SCREEN_HEIGHT = 0.8; - /** @const */ this.MENU_MODE_SCREEN_ELEVATION = 0.2; + /** @const */ this.MENU_MODE_SCREEN_HEIGHT = 0.48; + /** @const */ this.MENU_MODE_SCREEN_ELEVATION = -0.125; /** @const */ this.BACKGROUND_DISTANCE_MULTIPLIER = 1.414; /** @const */ this.DOM_INTERCEPTOR_SELECTOR = '#content-interceptor'; /** @const */ this.DOM_INTERCEPTOR_ELEVATION = 0.01; @@ -50,7 +51,8 @@ element.setVisible(false); element.setSize( this.SCREEN_HEIGHT * this.SCREEN_RATIO, this.SCREEN_HEIGHT); - element.setTranslation(0, 0, -this.BROWSING_SCREEN_DISTANCE); + element.setTranslation( + 0, this.BROWSING_SCREEN_ELEVATION, -this.BROWSING_SCREEN_DISTANCE); this.elementId = ui.addElement(element); // Place an invisible (fill none) but hittable plane behind the content @@ -113,7 +115,7 @@ updateState() { // Defaults content quad parameters. - let y = 0; + let y = this.BROWSING_SCREEN_ELEVATION; let distance = this.BROWSING_SCREEN_DISTANCE; let height = this.SCREEN_HEIGHT; @@ -167,13 +169,30 @@ this.sizeY = pixelHeight / 1000; element.setSize(this.sizeX, this.sizeY); - // Pull additional custom properties from CSS. + // Parse element CSS properties. let style = window.getComputedStyle(domElement); - this.translationX = getStyleFloat(style, '--tranX'); - this.translationY = getStyleFloat(style, '--tranY'); - this.translationZ = getStyleFloat(style, '--tranZ'); - element.setTranslation( - this.translationX, this.translationY, this.translationZ); + + this.translationX = getStyleFloat(style, '--tranX', 0); + this.translationY = getStyleFloat(style, '--tranY', 0); + this.translationZ = getStyleFloat(style, '--tranZ', 0); + if (this.translationX != 0 || this.translationY != 0 || + this.translationZ != 0) { + element.setTranslation( + this.translationX, this.translationY, this.translationZ); + } + + this.scale = getStyleFloat(style, '--scale', 1); + if (this.scale != 1) { + element.setScale(this.scale, this.scale, this.scale); + } + + this.rotationX = getStyleFloat(style, '--rotX', 0); + this.rotationY = getStyleFloat(style, '--rotY', 0); + this.rotationZ = getStyleFloat(style, '--rotZ', 0); + if (this.rotationX != 0 || this.rotationY != 0 || this.rotationZ != 0) { + element.setRotation( + this.rotationX, this.rotationY, this.rotationZ, 2 * Math.PI); + } this.id = ui.addElement(element); this.domElement = domElement; @@ -384,9 +403,9 @@ ], ]; - /** @const */ var BUTTON_Y = -0.27; - /** @const */ var BUTTON_Z = -1; - /** @const */ var BUTTON_SPACING = 0.11; + /** @const */ var BUTTON_Y = -0.53; + /** @const */ var BUTTON_Z = -2; + /** @const */ var BUTTON_SPACING = 0.14; let controls = new api.UiElement(0, 0, 0, 0); controls.setVisible(false); @@ -441,9 +460,6 @@ let update = new api.UiElementUpdate(); update.setVisible(false); - update.setSize(0.25, 0.1); - update.setTranslation(0, -1.0, -1.0); - update.setRotation(1, 0, 0, -0.8); ui.updateElement(this.uiElement.id, update); } @@ -566,9 +582,9 @@ let style = window.getComputedStyle(border); this.statusBarColor = getStyleString(style, '--statusBarColor'); this.backgroundColor = style.backgroundColor; - this.fadeTimeMs = getStyleFloat(style, '--fadeTimeMs'); - this.fadeYOffset = getStyleFloat(style, '--fadeYOffset'); - this.opacity = getStyleFloat(style, '--opacity'); + this.fadeTimeMs = getStyleFloat(style, '--fadeTimeMs', 0); + this.fadeYOffset = getStyleFloat(style, '--fadeYOffset', 0); + this.opacity = getStyleFloat(style, '--opacity', 1); } getSecurityIconElementId(level) { @@ -711,7 +727,7 @@ constructor() { /** @const */ this.SCENE_GROUND_SIZE = 25.0; /** @const */ this.SCENE_HEIGHT = 4.0; - /** @const */ this.GRIDLINE_COUNT = 10; + /** @const */ this.GRIDLINE_COUNT = 40; /** @const */ this.HORIZON_COLOR = {r: 0.57, g: 0.57, b: 0.57, a: 1.0}; /** @const */ this.CENTER_COLOR = {r: 0.48, g: 0.48, b: 0.48, a: 1.0}; /** @const */ this.FULLSCREEN_BACKGROUND_COLOR = @@ -734,7 +750,7 @@ ceilingPlane.setSize(this.SCENE_GROUND_SIZE, this.SCENE_GROUND_SIZE); ceilingPlane.setFill( new api.OpaqueGradient(this.HORIZON_COLOR, this.CENTER_COLOR)); - ceilingPlane.setTranslation(0, this.SCENE_HEIGHT / 2, 0); + ceilingPlane.setTranslation(0, this.SCENE_HEIGHT * 2, 0); ceilingPlane.setRotation(1.0, 0.0, 0.0, Math.PI / 2); ceilingPlane.setDrawPhase(0); this.ceilingPlaneId = ui.addElement(ceilingPlane); @@ -808,6 +824,10 @@ class Omnibox { constructor() { + /** @const */ this.ELEVATION = -0.7; + /** @const */ this.DISTANCE = -1.99; + /** @const */ this.SCALE = -this.DISTANCE; + this.enabled = false; let root = document.querySelector('#omnibox-ui-element'); @@ -817,6 +837,8 @@ // Initially invisible. let update = new api.UiElementUpdate(); update.setVisible(false); + update.setTranslation(0, this.ELEVATION, this.DISTANCE); + update.setScale(this.SCALE, this.SCALE, this.SCALE); ui.updateElement(this.domUiElement.id, update); // Field-clearing button. @@ -923,8 +945,8 @@ /** @const */ var DOM_NEW_TAB_BUTTON_SELECTOR = '#new-tab'; /** @const */ var DOM_NEW_INCOGNITO_TAB_BUTTON_SELECTOR = '#new-incognito-tab'; - /** @const */ var TAB_CONTAINER_Y_OFFSET = 0.4; - /** @const */ var TAB_CONTAINER_Z_OFFSET = -1; + /** @const */ var TAB_CONTAINER_Y_OFFSET = 0.3; + /** @const */ var TAB_CONTAINER_Z_OFFSET = -2; this.domTabs = {}; this.contentQuadId = contentQuadId; @@ -1050,7 +1072,7 @@ constructor(contentQuadId) { /** @const */ this.SCALE = 1.4; /** @const */ this.ANGLE_UP = Math.PI / 8; - /** @const */ this.Y_OFFSET = -0.9; + /** @const */ this.Y_OFFSET = -1.0; /** @const */ this.Z_OFFSET = -1.8; this.element = new DomUiElement('#vkb');
diff --git a/chrome/browser/thumbnails/content_analysis_unittest.cc b/chrome/browser/thumbnails/content_analysis_unittest.cc index 325615e..6d44d14 100644 --- a/chrome/browser/thumbnails/content_analysis_unittest.cc +++ b/chrome/browser/thumbnails/content_analysis_unittest.cc
@@ -88,7 +88,7 @@ canvas.FillRect(gfx::Rect(0, 0, 800, 600), SkColorSetRGB(10, 10, 10)); canvas.FillRect(gfx::Rect(400, 300, 1, 1), SkColorSetRGB(255, 255, 255)); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap reduced_color; reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), @@ -131,7 +131,7 @@ canvas.FillRect(gfx::Rect(0, 0, 800, 600), SkColorSetRGB(0, 0, 0)); canvas.DrawRect(draw_rect, SkColorSetRGB(255, 255, 255)); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap reduced_color; reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), @@ -169,7 +169,7 @@ canvas.FillRect(image_rect, SkColorSetRGB(0, 0, 0)); canvas.DrawRect(draw_rect, SkColorSetRGB(255, 255, 255)); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap reduced_color; reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), source.height())); @@ -232,7 +232,7 @@ canvas.DrawRect(gfx::Rect(300, 250, 99, 100), SkColorSetRGB(255, 255, 255)); canvas.DrawRect(gfx::Rect(401, 250, 99, 100), SkColorSetRGB(255, 255, 255)); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap reduced_color; reduced_color.allocPixels(SkImageInfo::MakeA8(source.width(), source.height())); @@ -554,7 +554,7 @@ std::fill_n(columns.begin() + 300, 100, true); std::fill_n(columns.begin() + 500, 100, true); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap result = ComputeDecimatedImage(source, rows, columns); EXPECT_FALSE(result.empty()); EXPECT_EQ(300, result.width()); @@ -666,7 +666,7 @@ canvas.DrawRect(pict_rect, SkColorSetRGB(0, 0, 0)); } - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap result = CreateRetargetedThumbnailImage( source, gfx::Size(424, 264), 2.5);
diff --git a/chrome/browser/thumbnails/content_based_thumbnailing_algorithm_unittest.cc b/chrome/browser/thumbnails/content_based_thumbnailing_algorithm_unittest.cc index ef13e40..7fff79c 100644 --- a/chrome/browser/thumbnails/content_based_thumbnailing_algorithm_unittest.cc +++ b/chrome/browser/thumbnails/content_based_thumbnailing_algorithm_unittest.cc
@@ -140,7 +140,7 @@ // The image consists of vertical non-overlapping stripes 150 pixels wide. canvas.FillRect(gfx::Rect(200, 200, 800, 400), SkColorSetRGB(255, 255, 255)); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); ConsumerCallbackCatcher catcher; const gfx::Size thumbnail_size(432, 284);
diff --git a/chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc b/chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc index 535553c..e321e58 100644 --- a/chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc +++ b/chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc
@@ -24,7 +24,7 @@ TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_TallerThanWide) { // The input bitmap is vertically long. gfx::Canvas canvas(gfx::Size(40, 90), 1.0f, true); - SkBitmap bitmap = canvas.ToBitmap(); + SkBitmap bitmap = canvas.GetBitmap(); // The desired size is square. thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; @@ -40,7 +40,7 @@ TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_WiderThanTall) { // The input bitmap is horizontally long. gfx::Canvas canvas(gfx::Size(70, 40), 1.0f, true); - SkBitmap bitmap = canvas.ToBitmap(); + SkBitmap bitmap = canvas.GetBitmap(); // The desired size is square. thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; @@ -56,7 +56,7 @@ TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_TooWiderThanTall) { // The input bitmap is horizontally very long. gfx::Canvas canvas(gfx::Size(90, 40), 1.0f, true); - SkBitmap bitmap = canvas.ToBitmap(); + SkBitmap bitmap = canvas.GetBitmap(); // The desired size is square. thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; @@ -72,7 +72,7 @@ TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_NotClipped) { // The input bitmap is square. gfx::Canvas canvas(gfx::Size(40, 40), 1.0f, true); - SkBitmap bitmap = canvas.ToBitmap(); + SkBitmap bitmap = canvas.GetBitmap(); // The desired size is square. thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; @@ -88,7 +88,7 @@ TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_NonSquareOutput) { // The input bitmap is square. gfx::Canvas canvas(gfx::Size(40, 40), 1.0f, true); - SkBitmap bitmap = canvas.ToBitmap(); + SkBitmap bitmap = canvas.GetBitmap(); // The desired size is horizontally long. thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED;
diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc index c01a8466..554d1cc 100644 --- a/chrome/browser/ui/browser_ui_prefs.cc +++ b/chrome/browser/ui/browser_ui_prefs.cc
@@ -71,12 +71,6 @@ registry->RegisterDictionaryPref(prefs::kBrowserWindowPlacement); registry->RegisterDictionaryPref(prefs::kBrowserWindowPlacementPopup); registry->RegisterDictionaryPref(prefs::kAppWindowPlacement); - registry->RegisterBooleanPref(prefs::kImportAutofillFormData, true); - registry->RegisterBooleanPref(prefs::kImportBookmarks, true); - registry->RegisterBooleanPref(prefs::kImportHistory, true); - registry->RegisterBooleanPref(prefs::kImportHomepage, true); - registry->RegisterBooleanPref(prefs::kImportSavedPasswords, true); - registry->RegisterBooleanPref(prefs::kImportSearchEngine, true); registry->RegisterBooleanPref( prefs::kEnableDoNotTrack, false,
diff --git a/chrome/browser/ui/webui/settings/profile_info_handler.cc b/chrome/browser/ui/webui/settings/profile_info_handler.cc index 6d38d2b..d577cd5 100644 --- a/chrome/browser/ui/webui/settings/profile_info_handler.cc +++ b/chrome/browser/ui/webui/settings/profile_info_handler.cc
@@ -214,8 +214,9 @@ name = base::UTF16ToUTF8(entry->GetName()); if (entry->IsUsingGAIAPicture() && entry->GetGAIAPicture()) { - gfx::Image icon = - profiles::GetAvatarIconForWebUI(entry->GetAvatarIcon(), true); + constexpr int kAvatarIconSize = 40; + gfx::Image icon = profiles::GetSizedAvatarIcon( + entry->GetAvatarIcon(), true, kAvatarIconSize, kAvatarIconSize); icon_url = webui::GetBitmapDataUrl(icon.AsBitmap()); } else { icon_url = profiles::GetDefaultAvatarIconUrl(entry->GetAvatarIconIndex());
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 786a279..cf12a9f 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -96,10 +96,6 @@ // user promoting Chrome for iOS. const base::Feature kDesktopIOSPromotion{"DesktopIOSPromotion", base::FEATURE_DISABLED_BY_DEFAULT}; - -// Disables the AutoImport feature on first run. See crbug.com/555550 -const base::Feature kDisableFirstRunAutoImportWin{ - "DisableFirstRunAutoImport", base::FEATURE_DISABLED_BY_DEFAULT}; #endif // Experiment to display a toggle allowing users to opt-out of persisting a
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index f44f462..24dbb6c 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -62,7 +62,6 @@ #if defined(OS_WIN) extern const base::Feature kDesktopIOSPromotion; -extern const base::Feature kDisableFirstRunAutoImportWin; #endif // defined(OS_WIN) extern const base::Feature kDisplayPersistenceToggleInPermissionPrompts;
diff --git a/chrome/common/trace_event_args_whitelist.cc b/chrome/common/trace_event_args_whitelist.cc index 740852f4..3b021a24 100644 --- a/chrome/common/trace_event_args_whitelist.cc +++ b/chrome/common/trace_event_args_whitelist.cc
@@ -24,7 +24,6 @@ const WhitelistEntry kEventArgsWhitelist[] = { {"__metadata", "thread_name", nullptr}, {"__metadata", "process_name", nullptr}, - {"__metadata", "process_runtime_sec", nullptr}, {"ipc", "SyncChannel::Send", nullptr}, {"toplevel", "*", nullptr}, {"latencyInfo", "*", kInputLatencyAllowedArgs},
diff --git a/chrome/installer/util/master_preferences.cc b/chrome/installer/util/master_preferences.cc index fa01417..223aa32 100644 --- a/chrome/installer/util/master_preferences.cc +++ b/chrome/installer/util/master_preferences.cc
@@ -226,6 +226,29 @@ installer::master_preferences::kDoNotCreateQuickLaunchShortcut, true); } + // Deprecated boolean import master preferences now mapped to their duplicates + // in prefs::. + static constexpr char kDistroImportHistoryPref[] = "import_history"; + static constexpr char kDistroImportHomePagePref[] = "import_home_page"; + static constexpr char kDistroImportSearchPref[] = "import_search_engine"; + static constexpr char kDistroImportBookmarksPref[] = "import_bookmarks"; + + static constexpr struct { + const char* old_distro_pref_path; + const char* modern_pref_path; + } kLegacyDistroImportPrefMappings[] = { + {kDistroImportBookmarksPref, prefs::kImportBookmarks}, + {kDistroImportHistoryPref, prefs::kImportHistory}, + {kDistroImportHomePagePref, prefs::kImportHomepage}, + {kDistroImportSearchPref, prefs::kImportSearchEngine}, + }; + + for (const auto& mapping : kLegacyDistroImportPrefMappings) { + bool value = false; + if (GetBool(mapping.old_distro_pref_path, &value)) + master_dictionary_->SetBoolean(mapping.modern_pref_path, value); + } + #if BUILDFLAG(ENABLE_RLZ) // Map the RLZ ping delay shipped in the distribution dictionary into real // prefs.
diff --git a/chrome/installer/util/master_preferences.h b/chrome/installer/util/master_preferences.h index 61582943..1eadf29 100644 --- a/chrome/installer/util/master_preferences.h +++ b/chrome/installer/util/master_preferences.h
@@ -39,11 +39,7 @@ // "distribution": { // "create_all_shortcuts": true, // "do_not_launch_chrome": false, -// "import_bookmarks": false, // "import_bookmarks_from_file": "c:\\path", -// "import_history": false, -// "import_home_page": false, -// "import_search_engine": true, // "make_chrome_default": false, // "make_chrome_default_for_user": true, // "ping_delay": 40, @@ -65,7 +61,13 @@ // "https://igoogle.com" // ], // "homepage": "http://example.org", -// "homepage_is_newtabpage": false +// "homepage_is_newtabpage": false, +// "import_autofill_form_data": false, +// "import_bookmarks": false, +// "import_history": false, +// "import_home_page": false, +// "import_saved_passwords": false, +// "import_search_engine": false // } // // A reserved "distribution" entry in the file is used to group related
diff --git a/chrome/installer/util/master_preferences_constants.cc b/chrome/installer/util/master_preferences_constants.cc index 2a1aeed..81aeae0 100644 --- a/chrome/installer/util/master_preferences_constants.cc +++ b/chrome/installer/util/master_preferences_constants.cc
@@ -8,12 +8,8 @@ namespace master_preferences { const char kDisableLogging[] = "disable_logging"; const char kDistroDict[] = "distribution"; - const char kDistroImportBookmarksPref[] = "import_bookmarks"; const char kDistroImportBookmarksFromFilePref[] = "import_bookmarks_from_file"; - const char kDistroImportHistoryPref[] = "import_history"; - const char kDistroImportHomePagePref[] = "import_home_page"; - const char kDistroImportSearchPref[] = "import_search_engine"; const char kDistroSuppressDefaultBrowserPromptPref[] = "suppress_default_browser_prompt_for_version"; const char kDistroSuppressFirstRunBubble[] = "suppress_first_run_bubble";
diff --git a/chrome/installer/util/master_preferences_constants.h b/chrome/installer/util/master_preferences_constants.h index c37b732..1ac32af 100644 --- a/chrome/installer/util/master_preferences_constants.h +++ b/chrome/installer/util/master_preferences_constants.h
@@ -19,17 +19,9 @@ extern const char kDisableLogging[]; // Name of the dictionary that holds the distribution values. extern const char kDistroDict[]; -// Boolean pref that triggers silent import of the default browser bookmarks. -extern const char kDistroImportBookmarksPref[]; // String pref that triggers silent import of bookmarks from the html file at // given path. extern const char kDistroImportBookmarksFromFilePref[]; -// Boolean pref that triggers silent import of the default browser history. -extern const char kDistroImportHistoryPref[]; -// Boolean pref that triggers silent import of the default browser homepage. -extern const char kDistroImportHomePagePref[]; -// Boolean pref that triggers silent import of the default search engine. -extern const char kDistroImportSearchPref[]; // String of Chrome version for which the "set as default browser" infobar will // never be shown. extern const char kDistroSuppressDefaultBrowserPromptPref[];
diff --git a/chrome/installer/util/master_preferences_unittest.cc b/chrome/installer/util/master_preferences_unittest.cc index e91b8b9..0b53d91 100644 --- a/chrome/installer/util/master_preferences_unittest.cc +++ b/chrome/installer/util/master_preferences_unittest.cc
@@ -75,11 +75,7 @@ "{ \n" " \"distribution\": { \n" " \"show_welcome_page\": true,\n" - " \"import_search_engine\": true,\n" - " \"import_history\": true,\n" - " \"import_bookmarks\": true,\n" " \"import_bookmarks_from_file\": \"c:\\\\foo\",\n" - " \"import_home_page\": true,\n" " \"welcome_page_on_os_upgrade_enabled\": true,\n" " \"do_not_create_any_shortcuts\": true,\n" " \"do_not_create_desktop_shortcut\": true,\n" @@ -93,7 +89,7 @@ " \"require_eula\": true\n" " },\n" " \"blah\": {\n" - " \"import_history\": false\n" + " \"show_welcome_page\": false\n" " }\n" "} \n"; @@ -103,10 +99,6 @@ EXPECT_TRUE(prefs.read_from_file()); const char* const expected_true[] = { - installer::master_preferences::kDistroImportSearchPref, - installer::master_preferences::kDistroImportHistoryPref, - installer::master_preferences::kDistroImportBookmarksPref, - installer::master_preferences::kDistroImportHomePagePref, installer::master_preferences::kDistroWelcomePageOnOSUpgradeEnabled, installer::master_preferences::kDoNotCreateAnyShortcuts, installer::master_preferences::kDoNotCreateDesktopShortcut, @@ -135,16 +127,14 @@ TEST_F(MasterPreferencesTest, ParseMissingDistroParams) { const char text[] = - "{ \n" - " \"distribution\": { \n" - " \"import_search_engine\": true,\n" - " \"import_bookmarks\": false,\n" - " \"import_bookmarks_from_file\": \"\",\n" - " \"do_not_create_desktop_shortcut\": true,\n" - " \"do_not_create_quick_launch_shortcut\": true,\n" - " \"do_not_launch_chrome\": true\n" - " }\n" - "} \n"; + "{ \n" + " \"distribution\": { \n" + " \"import_bookmarks_from_file\": \"\",\n" + " \"do_not_create_desktop_shortcut\": true,\n" + " \"do_not_create_quick_launch_shortcut\": true,\n" + " \"do_not_launch_chrome\": false\n" + " }\n" + "} \n"; EXPECT_TRUE(base::WriteFile(prefs_file(), text, static_cast<int>(strlen(text)))); @@ -152,11 +142,9 @@ EXPECT_TRUE(prefs.read_from_file()); ExpectedBooleans expected_bool[] = { - { installer::master_preferences::kDistroImportSearchPref, true }, - { installer::master_preferences::kDistroImportBookmarksPref, false }, - { installer::master_preferences::kDoNotCreateDesktopShortcut, true }, - { installer::master_preferences::kDoNotCreateQuickLaunchShortcut, true }, - { installer::master_preferences::kDoNotLaunchChrome, true }, + {installer::master_preferences::kDoNotCreateDesktopShortcut, true}, + {installer::master_preferences::kDoNotCreateQuickLaunchShortcut, true}, + {installer::master_preferences::kDoNotLaunchChrome, false}, }; bool value = false; @@ -166,7 +154,6 @@ } const char* const missing_bools[] = { - installer::master_preferences::kDistroImportHomePagePref, installer::master_preferences::kDistroWelcomePageOnOSUpgradeEnabled, installer::master_preferences::kDoNotRegisterForUpdateLaunch, installer::master_preferences::kMakeChromeDefault, @@ -318,6 +305,10 @@ "{" " \"distribution\": {" " \"create_all_shortcuts\": false,\n" + " \"import_bookmarks\": true,\n" + " \"import_history\": true,\n" + " \"import_home_page\": true,\n" + " \"import_search_engine\": true,\n" " \"ping_delay\": 40\n" " }" "}"; @@ -340,6 +331,20 @@ EXPECT_TRUE(do_not_create_quick_launch_shortcut); EXPECT_FALSE(do_not_create_taskbar_shortcut); + bool actual_value = false; + EXPECT_TRUE(prefs.master_dictionary().GetBoolean(prefs::kImportBookmarks, + &actual_value)); + EXPECT_TRUE(actual_value); + EXPECT_TRUE(prefs.master_dictionary().GetBoolean(prefs::kImportHistory, + &actual_value)); + EXPECT_TRUE(actual_value); + EXPECT_TRUE(prefs.master_dictionary().GetBoolean(prefs::kImportHomepage, + &actual_value)); + EXPECT_TRUE(actual_value); + EXPECT_TRUE(prefs.master_dictionary().GetBoolean(prefs::kImportSearchEngine, + &actual_value)); + EXPECT_TRUE(actual_value); + #if BUILDFLAG(ENABLE_RLZ) int rlz_ping_delay = 0; EXPECT_TRUE(prefs.master_dictionary().GetInteger(prefs::kRlzPingDelaySeconds,
diff --git a/chrome/test/data/webui/settings/route_tests.js b/chrome/test/data/webui/settings/route_tests.js index 7344683e..ab0c682 100644 --- a/chrome/test/data/webui/settings/route_tests.js +++ b/chrome/test/data/webui/settings/route_tests.js
@@ -106,7 +106,7 @@ return testNavigateBackUsesHistory( settings.Route.ADVANCED, settings.Route.PEOPLE, - settings.Route.ADVANCED); + settings.Route.BASIC); }); test('navigate back to sibling route', function() { @@ -144,6 +144,11 @@ assertEquals('', settings.getQueryParameters().toString()); }); + test('navigateTo ADVANCED forwards to BASIC', function() { + settings.navigateTo(settings.Route.ADVANCED); + assertEquals(settings.Route.BASIC, settings.getCurrentRoute()); + }); + test('popstate flag works', function() { settings.navigateTo(settings.Route.BASIC); assertFalse(settings.lastRouteChangeWasPopstate());
diff --git a/components/OWNERS b/components/OWNERS index 1dbc3891..5e5ca55 100644 --- a/components/OWNERS +++ b/components/OWNERS
@@ -11,8 +11,6 @@ per-file crash_strings.grdp=file://components/crash/OWNERS per-file dom_distiller_strings.grdp=file://components/dom_distiller/OWNERS per-file error_page_strings.grdp=file://components/error_page/OWNERS -per-file nacl_helper_nonsfi_unittests.isolate=file://components/nacl/OWNERS -per-file nacl_loader_unittests.isolate=file://components/nacl/OWNERS per-file ntp_snippets_strings.grdp=file://components/ntp_snippets/OWNERS per-file omnibox_strings.grdp=file://components/omnibox/OWNERS per-file password_manager_strings.grdp=file://components/password_manager/OWNERS @@ -31,9 +29,6 @@ per-file translate_strings.grdp=file://components/translate/OWNERS per-file undo_strings.grdp=file://components/undo/OWNERS per-file web_contents_delegate_android_strings.grdp=file://components/web_contents_delegate_android/OWNERS -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org # These are for the common case of adding or removing tests. If you're making # structural changes, please get a review from one of the overall components
diff --git a/components/offline_items_collection/core/offline_content_aggregator.cc b/components/offline_items_collection/core/offline_content_aggregator.cc index b856247..acbfd5a 100644 --- a/components/offline_items_collection/core/offline_content_aggregator.cc +++ b/components/offline_items_collection/core/offline_content_aggregator.cc
@@ -39,19 +39,28 @@ // Validate that this is the first OfflineContentProvider registered that is // associated with |name_space|. DCHECK(providers_.find(name_space) == providers_.end()); - DCHECK(pending_actions_.find(provider) == pending_actions_.end()); + + // Only set up the connection to the provider if the provider isn't associated + // with any other namespace. + if (!MapContainsValue(providers_, provider)) + provider->AddObserver(this); providers_[name_space] = provider; - provider->AddObserver(this); } void OfflineContentAggregator::UnregisterProvider( const std::string& name_space) { - auto it = providers_.find(name_space); + auto provider_it = providers_.find(name_space); - it->second->RemoveObserver(this); - pending_actions_.erase(it->second); - providers_.erase(it); + OfflineContentProvider* provider = provider_it->second; + providers_.erase(provider_it); + + // Only clean up the connection to the provider if the provider isn't + // associated with any other namespace. + if (!MapContainsValue(providers_, provider)) { + provider->RemoveObserver(this); + pending_actions_.erase(provider); + } } bool OfflineContentAggregator::AreItemsAvailable() { @@ -119,12 +128,17 @@ OfflineContentProvider::OfflineItemList OfflineContentAggregator::GetAllItems() { + // Create a set of unique providers to iterate over. + std::set<OfflineContentProvider*> providers; + for (auto provider_it : providers_) + providers.insert(provider_it.second); + OfflineItemList items; - for (auto& it : providers_) { - if (!it.second->AreItemsAvailable()) + for (auto* provider : providers) { + if (!provider->AreItemsAvailable()) continue; - OfflineItemList provider_items = it.second->GetAllItems(); + OfflineItemList provider_items = provider->GetAllItems(); items.insert(items.end(), provider_items.begin(), provider_items.end()); }
diff --git a/components/offline_items_collection/core/offline_content_aggregator.h b/components/offline_items_collection/core/offline_content_aggregator.h index 6271d9e..0349708 100644 --- a/components/offline_items_collection/core/offline_content_aggregator.h +++ b/components/offline_items_collection/core/offline_content_aggregator.h
@@ -57,6 +57,17 @@ // |name_space|. UI actions taken on OfflineItems with |name_space| will be // routed to |provider|. |provider| is expected to only expose OfflineItems // with |name_space| set. + // It is okay to register the same provider with multiple unique namespaces. + // The class will work as expected with a few caveats. These are fixable if + // they are necessary for proper operation. Contact dtrainor@ if changes to + // this behavior is needed. + // 1. Unregistering the first namespace won't remove any pending actions + // that are queued for this provider. That means the provider might + // still get actions for the removed namespace once it is done + // initializing itself. This case must be handled by the individual + // provider for now. + // 2. The provider needs to handle calls to GetAllItems properly (not return + // any items for a namespace that it didn't register). void RegisterProvider(const std::string& name_space, OfflineContentProvider* provider);
diff --git a/components/offline_items_collection/core/offline_content_aggregator_unittest.cc b/components/offline_items_collection/core/offline_content_aggregator_unittest.cc index 0ed47057..3619340 100644 --- a/components/offline_items_collection/core/offline_content_aggregator_unittest.cc +++ b/components/offline_items_collection/core/offline_content_aggregator_unittest.cc
@@ -4,6 +4,8 @@ #include "components/offline_items_collection/core/offline_content_aggregator.h" +#include <map> + #include "base/memory/ptr_util.h" #include "base/test/test_mock_time_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -14,11 +16,41 @@ #include "testing/gtest/include/gtest/gtest.h" using testing::_; +using testing::ContainerEq; using testing::Return; namespace offline_items_collection { namespace { +struct CompareOfflineItemsById { + bool operator()(const OfflineItem& a, const OfflineItem& b) const { + return a.id < b.id; + } +}; + +// A custom comparator that makes sure two vectors contain the same elements. +// TODO(dtrainor): Look into building a better matcher that works with gmock. +template <typename T> +bool VectorContentsEq(const std::vector<T>& list1, + const std::vector<T>& list2) { + if (list1.size() != list2.size()) + return false; + + std::map<T, int, CompareOfflineItemsById> occurance_counts; + for (auto it = list1.begin(); it != list1.end(); it++) + occurance_counts[*it]++; + + for (auto it = list2.begin(); it != list2.end(); it++) + occurance_counts[*it]--; + + for (auto it = occurance_counts.begin(); it != occurance_counts.end(); it++) { + if (it->second != 0) + return false; + } + + return true; +} + // Helper class that automatically unregisters itself from the aggregator in the // case that someone calls OpenItem on it. class OpenItemRemovalOfflineContentProvider @@ -141,12 +173,13 @@ EXPECT_CALL(provider2, GetAllItems()).WillRepeatedly(Return(items2)); provider1.NotifyOnItemsAvailable(); - EXPECT_EQ(items1, aggregator_.GetAllItems()); + EXPECT_TRUE(VectorContentsEq(items1, aggregator_.GetAllItems())); OfflineContentProvider::OfflineItemList combined_items(items1); combined_items.insert(combined_items.end(), items2.begin(), items2.end()); provider2.NotifyOnItemsAvailable(); - EXPECT_EQ(combined_items, aggregator_.GetAllItems()); + + EXPECT_TRUE(VectorContentsEq(combined_items, aggregator_.GetAllItems())); } TEST_F(OfflineContentAggregatorTest, QueryingItemFromRemovedProvider) { @@ -404,5 +437,41 @@ provider1.NotifyOnItemsAvailable(); } +TEST_F(OfflineContentAggregatorTest, SameProviderWithMultipleNamespaces) { + MockOfflineContentProvider provider; + ScopedMockOfflineContentProvider::ScopedMockObserver observer(&aggregator_); + + ContentId id1("1", "A"); + ContentId id2("2", "B"); + OfflineItem item1(id1); + OfflineItem item2(id2); + OfflineContentProvider::OfflineItemList items; + items.push_back(item1); + items.push_back(item2); + + aggregator_.RegisterProvider("1", &provider); + aggregator_.RegisterProvider("2", &provider); + EXPECT_TRUE(provider.HasObserver(&aggregator_)); + + EXPECT_CALL(provider, GetAllItems()).WillRepeatedly(Return(items)); + EXPECT_CALL(provider, GetItemById(id1)).WillRepeatedly(Return(&item1)); + EXPECT_CALL(provider, GetItemById(id2)).WillRepeatedly(Return(&item2)); + + EXPECT_CALL(observer, OnItemsAvailable(&aggregator_)).Times(1); + provider.NotifyOnItemsAvailable(); + + EXPECT_TRUE(VectorContentsEq(items, aggregator_.GetAllItems())); + EXPECT_EQ(&item1, aggregator_.GetItemById(id1)); + EXPECT_EQ(&item2, aggregator_.GetItemById(id2)); + + aggregator_.UnregisterProvider("1"); + EXPECT_TRUE(provider.HasObserver(&aggregator_)); + EXPECT_EQ(nullptr, aggregator_.GetItemById(id1)); + EXPECT_EQ(&item2, aggregator_.GetItemById(id2)); + + aggregator_.UnregisterProvider("2"); + EXPECT_FALSE(provider.HasObserver(&aggregator_)); +} + } // namespace } // namespace offline_items_collection
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 371d02a..e1b3201 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -52,8 +52,8 @@ "form_saver.h", "form_saver_impl.cc", "form_saver_impl.h", - "http_password_migrator.cc", - "http_password_migrator.h", + "http_password_store_migrator.cc", + "http_password_store_migrator.h", "import/csv_reader.cc", "import/csv_reader.h", "import/password_csv_reader.cc", @@ -280,7 +280,7 @@ "facet_manager_unittest.cc", "form_fetcher_impl_unittest.cc", "form_saver_impl_unittest.cc", - "http_password_migrator_unittest.cc", + "http_password_store_migrator_unittest.cc", "import/csv_reader_unittest.cc", "import/password_csv_reader_unittest.cc", "import/password_importer_unittest.cc",
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/components/password_manager/core/browser/credential_manager_pending_request_task.cc index c82cabf..6600bd4 100644 --- a/components/password_manager/core/browser/credential_manager_pending_request_task.cc +++ b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -133,7 +133,7 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> results) { if (results.empty()) { // Try to migrate the HTTP passwords and process them later. - http_migrator_ = base::MakeUnique<HttpPasswordMigrator>( + http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>( origin_, delegate_->client(), this); return; }
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.h b/components/password_manager/core/browser/credential_manager_pending_request_task.h index 289a820e..a444a72 100644 --- a/components/password_manager/core/browser/credential_manager_pending_request_task.h +++ b/components/password_manager/core/browser/credential_manager_pending_request_task.h
@@ -12,7 +12,7 @@ #include "base/callback_forward.h" #include "base/macros.h" -#include "components/password_manager/core/browser/http_password_migrator.h" +#include "components/password_manager/core/browser/http_password_store_migrator.h" #include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/browser/password_store_consumer.h" #include "url/gurl.h" @@ -55,7 +55,7 @@ // Retrieves credentials from the PasswordStore. class CredentialManagerPendingRequestTask : public PasswordStoreConsumer, - public HttpPasswordMigrator::Consumer { + public HttpPasswordStoreMigrator::Consumer { public: CredentialManagerPendingRequestTask( CredentialManagerPendingRequestTaskDelegate* delegate, @@ -73,7 +73,7 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> results) override; private: - // HttpPasswordMigrator::Consumer: + // HttpPasswordStoreMigrator::Consumer: void ProcessMigratedForms( std::vector<std::unique_ptr<autofill::PasswordForm>> forms) override; @@ -87,7 +87,7 @@ const bool include_passwords_; std::set<std::string> federations_; - std::unique_ptr<HttpPasswordMigrator> http_migrator_; + std::unique_ptr<HttpPasswordStoreMigrator> http_migrator_; DISALLOW_COPY_AND_ASSIGN(CredentialManagerPendingRequestTask); };
diff --git a/components/password_manager/core/browser/form_fetcher_impl.cc b/components/password_manager/core/browser/form_fetcher_impl.cc index c4f922c..b73501a 100644 --- a/components/password_manager/core/browser/form_fetcher_impl.cc +++ b/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -128,8 +128,8 @@ if (should_migrate_http_passwords_ && results.empty() && form_digest_.origin.SchemeIs(url::kHttpsScheme)) { - http_migrator_ = base::MakeUnique<HttpPasswordMigrator>(form_digest_.origin, - client_, this); + http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>( + form_digest_.origin, client_, this); return; }
diff --git a/components/password_manager/core/browser/form_fetcher_impl.h b/components/password_manager/core/browser/form_fetcher_impl.h index a9a1e7ac..af6ba69 100644 --- a/components/password_manager/core/browser/form_fetcher_impl.h +++ b/components/password_manager/core/browser/form_fetcher_impl.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "components/password_manager/core/browser/form_fetcher.h" -#include "components/password_manager/core/browser/http_password_migrator.h" +#include "components/password_manager/core/browser/http_password_store_migrator.h" #include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/browser/password_store_consumer.h" @@ -23,7 +23,7 @@ // with a particular origin. class FormFetcherImpl : public FormFetcher, public PasswordStoreConsumer, - public HttpPasswordMigrator::Consumer { + public HttpPasswordStoreMigrator::Consumer { public: // |form_digest| describes what credentials need to be retrieved and // |client| serves the PasswordStore, the logging information etc. @@ -48,7 +48,7 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> results) override; void OnGetSiteStatistics(std::vector<InteractionsStats> stats) override; - // HttpPasswordMigrator::Consumer: + // HttpPasswordStoreMigrator::Consumer: void ProcessMigratedForms( std::vector<std::unique_ptr<autofill::PasswordForm>> forms) override; @@ -96,7 +96,7 @@ const bool should_migrate_http_passwords_; // Does the actual migration. - std::unique_ptr<HttpPasswordMigrator> http_migrator_; + std::unique_ptr<HttpPasswordStoreMigrator> http_migrator_; DISALLOW_COPY_AND_ASSIGN(FormFetcherImpl); };
diff --git a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc index 310c7baf..e3e2806 100644 --- a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc +++ b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
@@ -477,7 +477,7 @@ EXPECT_CALL(*mock_store_, AddLogin(https_form)); EXPECT_CALL(consumer_, ProcessMatches(UnorderedElementsAre(Pointee(https_form)), 0u)); - static_cast<HttpPasswordMigrator*>(migrator_ptr.get()) + static_cast<HttpPasswordStoreMigrator*>(migrator_ptr.get()) ->OnGetPasswordStoreResults(MakeResults({http_form})); EXPECT_THAT(form_fetcher_->GetFederatedMatches(), IsEmpty()); @@ -548,7 +548,7 @@ // Now perform the actual migration. EXPECT_CALL(*mock_store_, AddLogin(https_form)); - static_cast<HttpPasswordMigrator*>(migrator_ptr.get()) + static_cast<HttpPasswordStoreMigrator*>(migrator_ptr.get()) ->OnGetPasswordStoreResults(MakeResults({http_form})); EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); }
diff --git a/components/password_manager/core/browser/http_password_migrator.cc b/components/password_manager/core/browser/http_password_store_migrator.cc similarity index 85% rename from components/password_manager/core/browser/http_password_migrator.cc rename to components/password_manager/core/browser/http_password_store_migrator.cc index 1bfb65e6..db243cb 100644 --- a/components/password_manager/core/browser/http_password_migrator.cc +++ b/components/password_manager/core/browser/http_password_store_migrator.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/password_manager/core/browser/http_password_migrator.h" +#include "components/password_manager/core/browser/http_password_store_migrator.h" #include "base/memory/weak_ptr.h" #include "components/password_manager/core/browser/password_manager_client.h" @@ -21,16 +21,17 @@ const base::WeakPtr<PasswordStoreConsumer>& migrator, bool is_hsts) { if (migrator) { - static_cast<HttpPasswordMigrator*>(migrator.get()) + static_cast<HttpPasswordStoreMigrator*>(migrator.get()) ->OnHSTSQueryResult(is_hsts); } } } // namespace -HttpPasswordMigrator::HttpPasswordMigrator(const GURL& https_origin, - const PasswordManagerClient* client, - Consumer* consumer) +HttpPasswordStoreMigrator::HttpPasswordStoreMigrator( + const GURL& https_origin, + const PasswordManagerClient* client, + Consumer* consumer) : client_(client), consumer_(consumer) { DCHECK(client_); DCHECK(https_origin.is_valid()); @@ -41,14 +42,15 @@ GURL http_origin = https_origin.ReplaceComponents(rep); PasswordStore::FormDigest form(autofill::PasswordForm::SCHEME_HTML, http_origin.GetOrigin().spec(), http_origin); + http_origin_domain_ = http_origin.GetOrigin(); client_->GetPasswordStore()->GetLogins(form, this); client_->PostHSTSQueryForHost( https_origin, base::Bind(&OnHSTSQueryResultHelper, GetWeakPtr())); } -HttpPasswordMigrator::~HttpPasswordMigrator() = default; +HttpPasswordStoreMigrator::~HttpPasswordStoreMigrator() = default; -void HttpPasswordMigrator::OnGetPasswordStoreResults( +void HttpPasswordStoreMigrator::OnGetPasswordStoreResults( std::vector<std::unique_ptr<autofill::PasswordForm>> results) { DCHECK(thread_checker_.CalledOnValidThread()); results_ = std::move(results); @@ -58,16 +60,19 @@ ProcessPasswordStoreResults(); } -void HttpPasswordMigrator::OnHSTSQueryResult(bool is_hsts) { +void HttpPasswordStoreMigrator::OnHSTSQueryResult(bool is_hsts) { DCHECK(thread_checker_.CalledOnValidThread()); mode_ = is_hsts ? MigrationMode::MOVE : MigrationMode::COPY; got_hsts_query_result_ = true; + if (is_hsts) + client_->GetPasswordStore()->RemoveSiteStats(http_origin_domain_); + if (got_password_store_results_) ProcessPasswordStoreResults(); } -void HttpPasswordMigrator::ProcessPasswordStoreResults() { +void HttpPasswordStoreMigrator::ProcessPasswordStoreResults() { // Android and PSL matches are ignored. results_.erase( std::remove_if(results_.begin(), results_.end(),
diff --git a/components/password_manager/core/browser/http_password_migrator.h b/components/password_manager/core/browser/http_password_store_migrator.h similarity index 75% rename from components/password_manager/core/browser/http_password_migrator.h rename to components/password_manager/core/browser/http_password_store_migrator.h index 4f71156..47a378c 100644 --- a/components/password_manager/core/browser/http_password_migrator.h +++ b/components/password_manager/core/browser/http_password_store_migrator.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_PASSWORD_MANAGER_CORE_BROWSER_HTTP_PASSWORD_MIGRATOR_H_ -#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_HTTP_PASSWORD_MIGRATOR_H_ +#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_HTTP_PASSWORD_STORE_MIGRATOR_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_HTTP_PASSWORD_STORE_MIGRATOR_H_ #include <memory> #include <vector> @@ -11,13 +11,12 @@ #include "base/macros.h" #include "base/threading/thread_checker.h" #include "components/password_manager/core/browser/password_store_consumer.h" +#include "url/gurl.h" namespace autofill { struct PasswordForm; } -class GURL; - namespace password_manager { class PasswordManagerClient; @@ -28,9 +27,12 @@ // HTTP password is considered obsolete and will be replaced by an HTTPS // version. If HSTS is not enabled, some parts of the site might still be served // via HTTP, which is why the password is copied in this case. -class HttpPasswordMigrator : public PasswordStoreConsumer { +// Furthermore, if a site has migrated to HTTPS and HSTS is enabled, the +// corresponding HTTP site statistics are cleared as well, since they are +// obsolete. +class HttpPasswordStoreMigrator : public PasswordStoreConsumer { public: - // API to be implemented by an embedder of HttpPasswordMigrator. + // API to be implemented by an embedder of HttpPasswordStoreMigrator. class Consumer { public: virtual ~Consumer() = default; @@ -42,10 +44,10 @@ }; // |https_origin| should specify a valid HTTPS URL. - HttpPasswordMigrator(const GURL& https_origin, - const PasswordManagerClient* client, - Consumer* consumer); - ~HttpPasswordMigrator() override; + HttpPasswordStoreMigrator(const GURL& https_origin, + const PasswordManagerClient* client, + Consumer* consumer); + ~HttpPasswordStoreMigrator() override; // PasswordStoreConsumer: void OnGetPasswordStoreResults( @@ -73,11 +75,12 @@ bool got_password_store_results_ = false; MigrationMode mode_; std::vector<std::unique_ptr<autofill::PasswordForm>> results_; + GURL http_origin_domain_; base::ThreadChecker thread_checker_; - DISALLOW_COPY_AND_ASSIGN(HttpPasswordMigrator); + DISALLOW_COPY_AND_ASSIGN(HttpPasswordStoreMigrator); }; } // namespace password_manager -#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_HTTP_PASSWORD_MIGRATOR_H_ +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_HTTP_PASSWORD_STORE_MIGRATOR_H_
diff --git a/components/password_manager/core/browser/http_password_migrator_unittest.cc b/components/password_manager/core/browser/http_password_store_migrator_unittest.cc similarity index 62% rename from components/password_manager/core/browser/http_password_migrator_unittest.cc rename to components/password_manager/core/browser/http_password_store_migrator_unittest.cc index 084daa7..6aa5d2b 100644 --- a/components/password_manager/core/browser/http_password_migrator_unittest.cc +++ b/components/password_manager/core/browser/http_password_store_migrator_unittest.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/password_manager/core/browser/http_password_migrator.h" +#include "components/password_manager/core/browser/http_password_store_migrator.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "components/password_manager/core/browser/mock_password_store.h" #include "components/password_manager/core/browser/stub_password_manager_client.h" @@ -17,8 +18,10 @@ using autofill::PasswordForm; using testing::ElementsAre; +using testing::Invoke; using testing::Pointee; using testing::SaveArg; +using testing::Unused; using testing::_; constexpr char kTestHttpsURL[] = "https://example.org/"; @@ -60,7 +63,7 @@ return form; } -class MockConsumer : public HttpPasswordMigrator::Consumer { +class MockConsumer : public HttpPasswordStoreMigrator::Consumer { public: MOCK_METHOD1(ProcessForms, void(const std::vector<autofill::PasswordForm*>& forms)); @@ -92,13 +95,15 @@ } // namespace -class HttpPasswordMigratorTest : public testing::Test { +class HttpPasswordStoreMigratorTest : public testing::Test { public: - HttpPasswordMigratorTest() + HttpPasswordStoreMigratorTest() : mock_store_(new testing::StrictMock<MockPasswordStore>), client_(mock_store_.get()) {} - ~HttpPasswordMigratorTest() override { mock_store_->ShutdownOnUIThread(); } + ~HttpPasswordStoreMigratorTest() override { + mock_store_->ShutdownOnUIThread(); + } MockConsumer& consumer() { return consumer_; } MockPasswordStore& store() { return *mock_store_; } @@ -107,6 +112,7 @@ protected: void TestEmptyStore(bool is_hsts); void TestFullStore(bool is_hsts); + void TestMigratorDeletionByConsumer(bool is_hsts); private: base::MessageLoop message_loop_; // Used by mock_store_. @@ -114,33 +120,45 @@ scoped_refptr<MockPasswordStore> mock_store_; MockPasswordManagerClient client_; - DISALLOW_COPY_AND_ASSIGN(HttpPasswordMigratorTest); + DISALLOW_COPY_AND_ASSIGN(HttpPasswordStoreMigratorTest); }; -void HttpPasswordMigratorTest::TestEmptyStore(bool is_hsts) { +void HttpPasswordStoreMigratorTest::TestEmptyStore(bool is_hsts) { PasswordStore::FormDigest form(autofill::PasswordForm::SCHEME_HTML, kTestHttpURL, GURL(kTestHttpURL)); EXPECT_CALL(store(), GetLogins(form, _)); PasswordManagerClient::HSTSCallback callback; EXPECT_CALL(client(), PostHSTSQueryForHost(GURL(kTestHttpsURL), _)) .WillOnce(SaveArg<1>(&callback)); - HttpPasswordMigrator migrator(GURL(kTestHttpsURL), &client(), &consumer()); + HttpPasswordStoreMigrator migrator(GURL(kTestHttpsURL), &client(), + &consumer()); callback.Run(is_hsts); + // We expect a potential call to |RemoveSiteStatsImpl| which is a async task + // posted from |PasswordStore::RemoveSiteStats|. Hence the following lines are + // necessary to ensure |RemoveSiteStatsImpl| gets called when expected. + EXPECT_CALL(store(), RemoveSiteStatsImpl(GURL(kTestHttpURL))).Times(is_hsts); + base::RunLoop().RunUntilIdle(); EXPECT_CALL(consumer(), ProcessForms(std::vector<autofill::PasswordForm*>())); migrator.OnGetPasswordStoreResults( std::vector<std::unique_ptr<autofill::PasswordForm>>()); } -void HttpPasswordMigratorTest::TestFullStore(bool is_hsts) { +void HttpPasswordStoreMigratorTest::TestFullStore(bool is_hsts) { PasswordStore::FormDigest form_digest(autofill::PasswordForm::SCHEME_HTML, kTestHttpURL, GURL(kTestHttpURL)); EXPECT_CALL(store(), GetLogins(form_digest, _)); PasswordManagerClient::HSTSCallback callback; EXPECT_CALL(client(), PostHSTSQueryForHost(GURL(kTestHttpsURL), _)) .WillOnce(SaveArg<1>(&callback)); - HttpPasswordMigrator migrator(GURL(kTestHttpsURL), &client(), &consumer()); + HttpPasswordStoreMigrator migrator(GURL(kTestHttpsURL), &client(), + &consumer()); callback.Run(is_hsts); + // We expect a potential call to |RemoveSiteStatsImpl| which is a async task + // posted from |PasswordStore::RemoveSiteStats|. Hence the following lines are + // necessary to ensure |RemoveSiteStatsImpl| gets called when expected. + EXPECT_CALL(store(), RemoveSiteStatsImpl(GURL(kTestHttpURL))).Times(is_hsts); + base::RunLoop().RunUntilIdle(); PasswordForm form = CreateTestForm(); PasswordForm psl_form = CreateTestPSLForm(); @@ -159,20 +177,57 @@ migrator.OnGetPasswordStoreResults(std::move(results)); } -TEST_F(HttpPasswordMigratorTest, EmptyStoreWithHSTS) { +// This test checks whether the migration successfully completes even if the +// migrator gets explicitly deleted by its consumer. This test will crash if +// this is not the case. +void HttpPasswordStoreMigratorTest::TestMigratorDeletionByConsumer( + bool is_hsts) { + // Setup expectations on store and client. + EXPECT_CALL(store(), GetLogins(_, _)); + PasswordManagerClient::HSTSCallback callback; + EXPECT_CALL(client(), PostHSTSQueryForHost(GURL(kTestHttpsURL), _)) + .WillOnce(SaveArg<1>(&callback)); + + // Construct the migrator, call |OnGetPasswordStoreResults| explicitly and + // manually delete it. + auto migrator = base::MakeUnique<HttpPasswordStoreMigrator>( + GURL(kTestHttpsURL), &client(), &consumer()); + migrator->OnGetPasswordStoreResults( + std::vector<std::unique_ptr<autofill::PasswordForm>>()); + EXPECT_CALL(consumer(), ProcessForms(_)).WillOnce(Invoke([&migrator](Unused) { + migrator.reset(); + })); + + callback.Run(is_hsts); + // We expect a potential call to |RemoveSiteStatsImpl| which is a async task + // posted from |PasswordStore::RemoveSiteStats|. Hence the following lines are + // necessary to ensure |RemoveSiteStatsImpl| gets called when expected. + EXPECT_CALL(store(), RemoveSiteStatsImpl(GURL(kTestHttpURL))).Times(is_hsts); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(HttpPasswordStoreMigratorTest, EmptyStoreWithHSTS) { TestEmptyStore(true); } -TEST_F(HttpPasswordMigratorTest, EmptyStoreWithoutHSTS) { +TEST_F(HttpPasswordStoreMigratorTest, EmptyStoreWithoutHSTS) { TestEmptyStore(false); } -TEST_F(HttpPasswordMigratorTest, FullStoreWithHSTS) { +TEST_F(HttpPasswordStoreMigratorTest, FullStoreWithHSTS) { TestFullStore(true); } -TEST_F(HttpPasswordMigratorTest, FullStoreWithoutHSTS) { +TEST_F(HttpPasswordStoreMigratorTest, FullStoreWithoutHSTS) { TestFullStore(false); } +TEST_F(HttpPasswordStoreMigratorTest, MigratorDeletionByConsumerWithHSTS) { + TestMigratorDeletionByConsumer(true); +} + +TEST_F(HttpPasswordStoreMigratorTest, MigratorDeletionByConsumerWithoutHSTS) { + TestMigratorDeletionByConsumer(false); +} + } // namespace password_manager
diff --git a/components/wallpaper/wallpaper_color_calculator_unittest.cc b/components/wallpaper/wallpaper_color_calculator_unittest.cc index 398d0fa..31268f7 100644 --- a/components/wallpaper/wallpaper_color_calculator_unittest.cc +++ b/components/wallpaper/wallpaper_color_calculator_unittest.cc
@@ -82,7 +82,7 @@ canvas.FillRect(gfx::Rect(kImageSize), kGray); canvas.FillRect(gfx::Rect(0, 1, 300, 1), kVibrantGreen); - image_ = gfx::ImageSkia::CreateFrom1xBitmap(canvas.ToBitmap()); + image_ = gfx::ImageSkia::CreateFrom1xBitmap(canvas.GetBitmap()); calculator_ = base::MakeUnique<WallpaperColorCalculator>( image_, color_utils::LumaRange::NORMAL,
diff --git a/content/OWNERS b/content/OWNERS index 4e1c8d0..41531f0 100644 --- a/content/OWNERS +++ b/content/OWNERS
@@ -22,8 +22,4 @@ per-file *.sb=set noparent per-file *.sb=rsesek@chromium.org -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org - # COMPONENT: Internals>Core
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc index 1fb1130..9202ef8 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/debug/crash_logging.h" +#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -1018,8 +1019,12 @@ // If no host is found, the navigation has been cancelled in the meantime. // Just return as the navigation will be stopped in the renderer as well. - if (provider_host == nullptr) + if (provider_host == nullptr) { + // TODO(clamy): remove this Dump when the root cause for crbug.com/703972 + // has been found. + base::debug::DumpWithoutCrashing(); return; + } DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, info.type); provider_host->CompleteNavigationInitialized(render_process_id_, info.route_id, this);
diff --git a/content/renderer/media/webmediaplayer_ms_compositor.cc b/content/renderer/media/webmediaplayer_ms_compositor.cc index c0097d7..763b183 100644 --- a/content/renderer/media/webmediaplayer_ms_compositor.cc +++ b/content/renderer/media/webmediaplayer_ms_compositor.cc
@@ -48,25 +48,27 @@ media::PIXEL_FORMAT_I420, frame->coded_size(), frame->visible_rect(), frame->natural_size(), frame->timestamp()); - sk_sp<cc::PaintSurface> surface = cc::PaintSurface::MakeRasterN32Premul( - frame->visible_rect().width(), frame->visible_rect().height()); - ui::ContextProviderCommandBuffer* const provider = RenderThreadImpl::current()->SharedMainThreadContextProvider().get(); - if (surface && provider) { - DCHECK(provider->ContextGL()); - video_renderer->Copy( - frame.get(), surface->getCanvas(), - media::Context3D(provider->ContextGL(), provider->GrContext())); - } else { + if (!provider) { // Return a black frame (yuv = {0, 0x80, 0x80}). return media::VideoFrame::CreateColorFrame( frame->visible_rect().size(), 0u, 0x80, 0x80, frame->timestamp()); } + SkBitmap bitmap; + bitmap.allocPixels(SkImageInfo::MakeN32Premul( + frame->visible_rect().width(), frame->visible_rect().height())); + cc::SkiaPaintCanvas paint_canvas(bitmap); + + DCHECK(provider->ContextGL()); + video_renderer->Copy( + frame.get(), &paint_canvas, + media::Context3D(provider->ContextGL(), provider->GrContext())); + SkPixmap pixmap; - const bool result = surface->getCanvas()->peekPixels(&pixmap); - DCHECK(result) << "Error trying to access PaintSurface's pixels"; + const bool result = bitmap.peekPixels(&pixmap); + DCHECK(result) << "Error trying to access SkBitmap's pixels"; const uint32 source_pixel_format = (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc index 77b5241..edde298 100644 --- a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
@@ -101,27 +101,30 @@ frame->format() == media::PIXEL_FORMAT_UYVY || frame->format() == media::PIXEL_FORMAT_NV12); ScopedWaitableEvent event(waiter); - sk_sp<cc::PaintSurface> surface = cc::PaintSurface::MakeRasterN32Premul( - frame->visible_rect().width(), frame->visible_rect().height()); - if (!surface || !provider_) { + if (!provider_) { // Return a black frame (yuv = {0, 0x80, 0x80}). *new_frame = media::VideoFrame::CreateColorFrame( frame->visible_rect().size(), 0u, 0x80, 0x80, frame->timestamp()); return; } + SkBitmap bitmap; + bitmap.allocPixels(SkImageInfo::MakeN32Premul( + frame->visible_rect().width(), frame->visible_rect().height())); + cc::SkiaPaintCanvas paint_canvas(bitmap); + *new_frame = media::VideoFrame::CreateFrame( media::PIXEL_FORMAT_I420, frame->coded_size(), frame->visible_rect(), frame->natural_size(), frame->timestamp()); DCHECK(provider_->ContextGL()); canvas_video_renderer_->Copy( - frame.get(), surface->getCanvas(), + frame.get(), &paint_canvas, media::Context3D(provider_->ContextGL(), provider_->GrContext())); SkPixmap pixmap; - const bool result = surface->getCanvas()->peekPixels(&pixmap); - DCHECK(result) << "Error trying to access PaintSurface's pixels"; + const bool result = bitmap.peekPixels(&pixmap); + DCHECK(result) << "Error trying to access SkBitmap's pixels"; const uint32 source_pixel_format = (kN32_SkColorType == kRGBA_8888_SkColorType) ? cricket::FOURCC_ABGR : cricket::FOURCC_ARGB;
diff --git a/content/renderer/mus/renderer_window_tree_client.cc b/content/renderer/mus/renderer_window_tree_client.cc index 6940056..8cb2e657 100644 --- a/content/renderer/mus/renderer_window_tree_client.cc +++ b/content/renderer/mus/renderer_window_tree_client.cc
@@ -119,6 +119,13 @@ void RendererWindowTreeClient::OnCaptureChanged(ui::Id new_capture_window_id, ui::Id old_capture_window_id) {} +void RendererWindowTreeClient::OnFrameSinkIdAllocated( + ui::Id window_id, + const cc::FrameSinkId& frame_sink_id) { + // TODO(fsamuel): OOPIF's |frame_sink_id| is ready. The OOPIF can now be + // embedded by the parent. +} + void RendererWindowTreeClient::OnTopLevelCreated( uint32_t change_id, ui::mojom::WindowDataPtr data,
diff --git a/content/renderer/mus/renderer_window_tree_client.h b/content/renderer/mus/renderer_window_tree_client.h index 3241ca48..982e6acf 100644 --- a/content/renderer/mus/renderer_window_tree_client.h +++ b/content/renderer/mus/renderer_window_tree_client.h
@@ -74,6 +74,8 @@ void OnUnembed(ui::Id window_id) override; void OnCaptureChanged(ui::Id new_capture_window_id, ui::Id old_capture_window_id) override; + void OnFrameSinkIdAllocated(ui::Id window_id, + const cc::FrameSinkId& frame_sink_id) override; void OnTopLevelCreated(uint32_t change_id, ui::mojom::WindowDataPtr data, int64_t display_id,
diff --git a/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc b/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc index 01763945..d5c2e3b 100644 --- a/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc +++ b/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc
@@ -105,7 +105,7 @@ gfx::Canvas canvas(gfx::Size(20, 10), 1.0f, true); canvas.FillRect(gfx::Rect(20, 10), SK_ColorBLACK); canvas.FillRect(gfx::Rect(10, 10), SK_ColorWHITE); - SkBitmap interesting_bitmap = canvas.ToBitmap(); + SkBitmap interesting_bitmap = canvas.GetBitmap(); // Don't throttle for a boring frame. throttler()->OnImageFlush(boring_bitmap);
diff --git a/extensions/browser/api/runtime/runtime_apitest.cc b/extensions/browser/api/runtime/runtime_apitest.cc index 422251a..1bb7850 100644 --- a/extensions/browser/api/runtime/runtime_apitest.cc +++ b/extensions/browser/api/runtime/runtime_apitest.cc
@@ -80,7 +80,8 @@ } // Tests chrome.runtime.reload -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeReload) { +// This test is flaky: crbug.com/366181 +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_ChromeRuntimeReload) { ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); const char kManifest[] = "{"
diff --git a/extensions/test/extension_test_notification_observer.cc b/extensions/test/extension_test_notification_observer.cc index 0e4d75d0c..7d6db807 100644 --- a/extensions/test/extension_test_notification_observer.cc +++ b/extensions/test/extension_test_notification_observer.cc
@@ -127,7 +127,8 @@ bool ExtensionTestNotificationObserver::WaitForCrxInstallerDone() { int before = crx_installers_done_observed_; WaitForNotification(NOTIFICATION_CRX_INSTALLER_DONE); - return crx_installers_done_observed_ == before + 1; + return crx_installers_done_observed_ == before + 1 && + !last_loaded_extension_id_.empty(); } void ExtensionTestNotificationObserver::Watch(
diff --git a/extensions/test/extension_test_notification_observer.h b/extensions/test/extension_test_notification_observer.h index 655084e..418d567a 100644 --- a/extensions/test/extension_test_notification_observer.h +++ b/extensions/test/extension_test_notification_observer.h
@@ -46,7 +46,8 @@ // crashed. bool WaitForExtensionCrash(const std::string& extension_id); - // Wait for the crx installer to be done. Returns true if it really is done. + // Wait for the crx installer to be done. Returns true if it has finished + // successfully. bool WaitForCrxInstallerDone(); // Watch for the given event type from the given source.
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index d3836079..479b2d6 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -6703,7 +6703,7 @@ typedef cmds::%(func_name)s::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( c.%(last_arg_name)s_shm_id, c.%(last_arg_name)s_shm_offset, - &buffer_size); + sizeof(Result), &buffer_size); %(last_arg_type)s %(last_arg_name)s = result ? result->GetData() : NULL; if (%(last_arg_name)s == NULL) { return error::kOutOfBounds;
diff --git a/gpu/command_buffer/service/common_decoder.cc b/gpu/command_buffer/service/common_decoder.cc index b879f95..a561056 100644 --- a/gpu/command_buffer/service/common_decoder.cc +++ b/gpu/command_buffer/service/common_decoder.cc
@@ -143,10 +143,11 @@ void* CommonDecoder::GetAddressAndSize(unsigned int shm_id, unsigned int data_offset, + unsigned int minimum_size, unsigned int* data_size) { CHECK(engine_); scoped_refptr<gpu::Buffer> buffer = engine_->GetSharedMemoryBuffer(shm_id); - if (!buffer.get()) + if (!buffer.get() || buffer->GetRemainingSize(data_offset) < minimum_size) return NULL; return buffer->GetDataAddressAndSize(data_offset, data_size); }
diff --git a/gpu/command_buffer/service/common_decoder.h b/gpu/command_buffer/service/common_decoder.h index 5b41775b..3c23d53 100644 --- a/gpu/command_buffer/service/common_decoder.h +++ b/gpu/command_buffer/service/common_decoder.h
@@ -152,13 +152,16 @@ void* GetAddressAndSize(unsigned int shm_id, unsigned int offset, + unsigned int minimum_size, unsigned int* size); template <typename T> T GetSharedMemoryAndSizeAs(unsigned int shm_id, unsigned int offset, + unsigned int minimum_size, unsigned int* size) { - return static_cast<T>(GetAddressAndSize(shm_id, offset, size)); + return static_cast<T>( + GetAddressAndSize(shm_id, offset, minimum_size, size)); } unsigned int GetSharedMemorySize(unsigned int shm_id, unsigned int offset);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc index 156a071..3e08b52 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc
@@ -226,7 +226,7 @@ unsigned int buffer_size = 0; typedef cmds::GetActiveUniformBlockiv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -440,7 +440,7 @@ unsigned int buffer_size = 0; typedef cmds::GetInternalformativ::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -649,7 +649,7 @@ unsigned int buffer_size = 0; typedef cmds::GetUniformfv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLfloat* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -678,7 +678,7 @@ unsigned int buffer_size = 0; typedef cmds::GetUniformiv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -707,7 +707,7 @@ unsigned int buffer_size = 0; typedef cmds::GetUniformuiv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLuint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -808,7 +808,7 @@ unsigned int buffer_size = 0; typedef cmds::GetVertexAttribPointerv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.pointer_shm_id, c.pointer_shm_offset, &buffer_size); + c.pointer_shm_id, c.pointer_shm_offset, sizeof(Result), &buffer_size); GLuint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -857,7 +857,7 @@ unsigned int buffer_size = 0; if (c.pixels_shm_id != 0) { pixels = GetSharedMemoryAndSizeAs<uint8_t*>( - c.pixels_shm_id, c.pixels_shm_offset, &buffer_size); + c.pixels_shm_id, c.pixels_shm_offset, 0, &buffer_size); if (!pixels) { return error::kOutOfBounds; } @@ -946,7 +946,7 @@ if (pixels_shm_id != 0 || pixels_shm_offset != 0) { pixels = GetSharedMemoryAndSizeAs<uint8_t*>( - pixels_shm_id, pixels_shm_offset, &buffer_size); + pixels_shm_id, pixels_shm_offset, 0, &buffer_size); if (!pixels) { return error::kOutOfBounds; } @@ -984,7 +984,7 @@ if (pixels_shm_id != 0 || pixels_shm_offset != 0) { pixels = GetSharedMemoryAndSizeAs<uint8_t*>( - pixels_shm_id, pixels_shm_offset, &buffer_size); + pixels_shm_id, pixels_shm_offset, 0, &buffer_size); if (!pixels) { return error::kOutOfBounds; } @@ -1021,7 +1021,7 @@ if (pixels_shm_id != 0 || pixels_shm_offset != 0) { pixels = GetSharedMemoryAndSizeAs<uint8_t*>( - pixels_shm_id, pixels_shm_offset, &buffer_size); + pixels_shm_id, pixels_shm_offset, 0, &buffer_size); if (!pixels) { return error::kOutOfBounds; } @@ -1060,7 +1060,7 @@ if (pixels_shm_id != 0 || pixels_shm_offset != 0) { pixels = GetSharedMemoryAndSizeAs<uint8_t*>( - pixels_shm_id, pixels_shm_offset, &buffer_size); + pixels_shm_id, pixels_shm_offset, 0, &buffer_size); if (!pixels) { return error::kOutOfBounds; } @@ -1897,7 +1897,7 @@ if (coords_shm_id != 0 || coords_shm_offset != 0) { unsigned int memory_size = 0; coords = GetSharedMemoryAndSizeAs<const GLvoid*>( - coords_shm_id, coords_shm_offset, &memory_size); + coords_shm_id, coords_shm_offset, 0, &memory_size); coords_bufsize = static_cast<GLsizei>(memory_size); } @@ -2068,7 +2068,7 @@ if (paths_shm_id != 0 || paths_shm_offset != 0) { unsigned int memory_size = 0; paths = GetSharedMemoryAndSizeAs<const GLvoid*>( - paths_shm_id, paths_shm_offset, &memory_size); + paths_shm_id, paths_shm_offset, 0, &memory_size); paths_bufsize = static_cast<GLsizei>(memory_size); } @@ -2085,7 +2085,8 @@ if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) { unsigned int memory_size = 0; transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>( - c.transformValues_shm_id, c.transformValues_shm_offset, &memory_size); + c.transformValues_shm_id, c.transformValues_shm_offset, 0, + &memory_size); transform_values_bufsize = static_cast<GLsizei>(memory_size); } if (!transform_values) { @@ -2120,7 +2121,7 @@ if (paths_shm_id != 0 || paths_shm_offset != 0) { unsigned int memory_size = 0; paths = GetSharedMemoryAndSizeAs<const GLvoid*>( - paths_shm_id, paths_shm_offset, &memory_size); + paths_shm_id, paths_shm_offset, 0, &memory_size); paths_bufsize = static_cast<GLsizei>(memory_size); } @@ -2137,7 +2138,8 @@ if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) { unsigned int memory_size = 0; transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>( - c.transformValues_shm_id, c.transformValues_shm_offset, &memory_size); + c.transformValues_shm_id, c.transformValues_shm_offset, 0, + &memory_size); transform_values_bufsize = static_cast<GLsizei>(memory_size); } if (!transform_values) { @@ -2170,7 +2172,7 @@ if (paths_shm_id != 0 || paths_shm_offset != 0) { unsigned int memory_size = 0; paths = GetSharedMemoryAndSizeAs<const GLvoid*>( - paths_shm_id, paths_shm_offset, &memory_size); + paths_shm_id, paths_shm_offset, 0, &memory_size); paths_bufsize = static_cast<GLsizei>(memory_size); } @@ -2186,7 +2188,8 @@ if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) { unsigned int memory_size = 0; transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>( - c.transformValues_shm_id, c.transformValues_shm_offset, &memory_size); + c.transformValues_shm_id, c.transformValues_shm_offset, 0, + &memory_size); transform_values_bufsize = static_cast<GLsizei>(memory_size); } if (!transform_values) { @@ -2221,7 +2224,7 @@ if (paths_shm_id != 0 || paths_shm_offset != 0) { unsigned int memory_size = 0; paths = GetSharedMemoryAndSizeAs<const GLvoid*>( - paths_shm_id, paths_shm_offset, &memory_size); + paths_shm_id, paths_shm_offset, 0, &memory_size); paths_bufsize = static_cast<GLsizei>(memory_size); } @@ -2237,7 +2240,8 @@ if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) { unsigned int memory_size = 0; transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>( - c.transformValues_shm_id, c.transformValues_shm_offset, &memory_size); + c.transformValues_shm_id, c.transformValues_shm_offset, 0, + &memory_size); transform_values_bufsize = static_cast<GLsizei>(memory_size); } if (!transform_values) { @@ -2271,7 +2275,7 @@ if (paths_shm_id != 0 || paths_shm_offset != 0) { unsigned int memory_size = 0; paths = GetSharedMemoryAndSizeAs<const GLvoid*>( - paths_shm_id, paths_shm_offset, &memory_size); + paths_shm_id, paths_shm_offset, 0, &memory_size); paths_bufsize = static_cast<GLsizei>(memory_size); } @@ -2289,7 +2293,8 @@ if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) { unsigned int memory_size = 0; transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>( - c.transformValues_shm_id, c.transformValues_shm_offset, &memory_size); + c.transformValues_shm_id, c.transformValues_shm_offset, 0, + &memory_size); transform_values_bufsize = static_cast<GLsizei>(memory_size); } if (!transform_values) { @@ -2324,7 +2329,7 @@ if (paths_shm_id != 0 || paths_shm_offset != 0) { unsigned int memory_size = 0; paths = GetSharedMemoryAndSizeAs<const GLvoid*>( - paths_shm_id, paths_shm_offset, &memory_size); + paths_shm_id, paths_shm_offset, 0, &memory_size); paths_bufsize = static_cast<GLsizei>(memory_size); } @@ -2342,7 +2347,8 @@ if (c.transformValues_shm_id != 0 || c.transformValues_shm_offset != 0) { unsigned int memory_size = 0; transform_values = GetSharedMemoryAndSizeAs<const GLfloat*>( - c.transformValues_shm_id, c.transformValues_shm_offset, &memory_size); + c.transformValues_shm_id, c.transformValues_shm_offset, 0, + &memory_size); transform_values_bufsize = static_cast<GLsizei>(memory_size); } if (!transform_values) { @@ -2403,7 +2409,7 @@ if (c.coeffs_shm_id != 0 || c.coeffs_shm_offset != 0) { unsigned int memory_size = 0; coeffs = GetSharedMemoryAndSizeAs<const GLfloat*>( - c.coeffs_shm_id, c.coeffs_shm_offset, &memory_size); + c.coeffs_shm_id, c.coeffs_shm_offset, 0, &memory_size); coeffs_bufsize = static_cast<GLsizei>(memory_size); } if (!coeffs) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index bc19ef16..d4eb37e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -1079,7 +1079,7 @@ unsigned int buffer_size = 0; typedef cmds::GetBooleanv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLboolean* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1109,7 +1109,7 @@ unsigned int buffer_size = 0; typedef cmds::GetBufferParameteri64v::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint64* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1139,7 +1139,7 @@ unsigned int buffer_size = 0; typedef cmds::GetBufferParameteriv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1186,7 +1186,7 @@ unsigned int buffer_size = 0; typedef cmds::GetFloatv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLfloat* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1219,7 +1219,7 @@ unsigned int buffer_size = 0; typedef cmds::GetFramebufferAttachmentParameteriv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1248,7 +1248,7 @@ unsigned int buffer_size = 0; typedef cmds::GetInteger64v::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint64* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1277,7 +1277,7 @@ unsigned int buffer_size = 0; typedef cmds::GetIntegeri_v::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.data_shm_id, c.data_shm_offset, &buffer_size); + c.data_shm_id, c.data_shm_offset, sizeof(Result), &buffer_size); GLint* data = result ? result->GetData() : NULL; if (data == NULL) { return error::kOutOfBounds; @@ -1306,7 +1306,7 @@ unsigned int buffer_size = 0; typedef cmds::GetInteger64i_v::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.data_shm_id, c.data_shm_offset, &buffer_size); + c.data_shm_id, c.data_shm_offset, sizeof(Result), &buffer_size); GLint64* data = result ? result->GetData() : NULL; if (data == NULL) { return error::kOutOfBounds; @@ -1334,7 +1334,7 @@ unsigned int buffer_size = 0; typedef cmds::GetIntegerv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1363,7 +1363,7 @@ unsigned int buffer_size = 0; typedef cmds::GetProgramiv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1393,7 +1393,7 @@ unsigned int buffer_size = 0; typedef cmds::GetRenderbufferParameteriv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1424,7 +1424,7 @@ unsigned int buffer_size = 0; typedef cmds::GetSamplerParameterfv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLfloat* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1455,7 +1455,7 @@ unsigned int buffer_size = 0; typedef cmds::GetSamplerParameteriv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1485,7 +1485,7 @@ unsigned int buffer_size = 0; typedef cmds::GetShaderiv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1514,7 +1514,7 @@ unsigned int buffer_size = 0; typedef cmds::GetSynciv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.values_shm_id, c.values_shm_offset, &buffer_size); + c.values_shm_id, c.values_shm_offset, sizeof(Result), &buffer_size); GLint* values = result ? result->GetData() : NULL; if (values == NULL) { return error::kOutOfBounds; @@ -1543,7 +1543,7 @@ unsigned int buffer_size = 0; typedef cmds::GetTexParameterfv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLfloat* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1573,7 +1573,7 @@ unsigned int buffer_size = 0; typedef cmds::GetTexParameteriv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1603,7 +1603,7 @@ unsigned int buffer_size = 0; typedef cmds::GetVertexAttribfv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLfloat* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1633,7 +1633,7 @@ unsigned int buffer_size = 0; typedef cmds::GetVertexAttribiv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1663,7 +1663,7 @@ unsigned int buffer_size = 0; typedef cmds::GetVertexAttribIiv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds; @@ -1693,7 +1693,7 @@ unsigned int buffer_size = 0; typedef cmds::GetVertexAttribIuiv::Result Result; Result* result = GetSharedMemoryAndSizeAs<Result*>( - c.params_shm_id, c.params_shm_offset, &buffer_size); + c.params_shm_id, c.params_shm_offset, sizeof(Result), &buffer_size); GLuint* params = result ? result->GetData() : NULL; if (params == NULL) { return error::kOutOfBounds;
diff --git a/gpu/command_buffer/tests/fuzzer_main.cc b/gpu/command_buffer/tests/fuzzer_main.cc index 87111b4..557b228 100644 --- a/gpu/command_buffer/tests/fuzzer_main.cc +++ b/gpu/command_buffer/tests/fuzzer_main.cc
@@ -190,12 +190,12 @@ } void ResetDecoder() { + decoder_->Destroy(true); + decoder_.reset(); if (recreate_context_) { context_->ReleaseCurrent(nullptr); context_ = nullptr; } - decoder_->Destroy(true); - decoder_.reset(); command_buffer_.reset(); }
diff --git a/media/OWNERS b/media/OWNERS index ceeec91..50e4f034 100644 --- a/media/OWNERS +++ b/media/OWNERS
@@ -20,8 +20,4 @@ wolenetz@chromium.org xhwang@chromium.org -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org - # COMPONENT: Internals>Media
diff --git a/net/OWNERS b/net/OWNERS index 589e980b..904fb38 100644 --- a/net/OWNERS +++ b/net/OWNERS
@@ -17,10 +17,6 @@ xunjieli@chromium.org zhongyi@chromium.org -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org - per-file BUILD.gn=bengr@chromium.org per-file net.gyp*=bengr@chromium.org
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index af348737..5f870c6 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -13,6 +13,7 @@ #include <algorithm> #include <string> +#include "base/auto_reset.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/compiler_specific.h" @@ -190,6 +191,7 @@ total_received_bytes_(0), total_sent_bytes_(0), websocket_handshake_stream_base_create_helper_(NULL), + in_do_loop_(false), weak_factory_(this) { TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); static_assert(HttpCache::Transaction::kNumValidationHeaders == @@ -714,11 +716,14 @@ int HttpCache::Transaction::DoLoop(int result) { DCHECK_NE(STATE_UNSET, next_state_); DCHECK_NE(STATE_NONE, next_state_); + DCHECK(!in_do_loop_); int rv = result; do { State state = next_state_; next_state_ = STATE_UNSET; + base::AutoReset<bool> scoped_in_do_loop(&in_do_loop_, true); + switch (state) { case STATE_GET_BACKEND: DCHECK_EQ(OK, rv); @@ -898,7 +903,7 @@ int HttpCache::Transaction::DoGetBackend() { cache_pending_ = true; - next_state_ = STATE_GET_BACKEND_COMPLETE; + TransitionToState(STATE_GET_BACKEND_COMPLETE); net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND); return cache_->GetBackendForTransaction(this); } @@ -916,7 +921,7 @@ if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { if (effective_load_flags_ & LOAD_BYPASS_CACHE) { // The client has asked for nonsense. - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_MISS; } mode_ = READ; @@ -955,7 +960,7 @@ // If must use cache, then we must fail. This can happen for back/forward // navigations to a page generated via a form post. if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_MISS; } @@ -964,9 +969,9 @@ partial_->RestoreHeaders(&custom_request_->extra_headers); partial_.reset(); } - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); } else { - next_state_ = STATE_INIT_ENTRY; + TransitionToState(STATE_INIT_ENTRY); } // This is only set if we have something to do with the response. @@ -980,23 +985,23 @@ DCHECK(!new_entry_); if (!cache_.get()) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_UNEXPECTED; } if (mode_ == WRITE) { - next_state_ = STATE_DOOM_ENTRY; + TransitionToState(STATE_DOOM_ENTRY); return OK; } - next_state_ = STATE_OPEN_ENTRY; + TransitionToState(STATE_OPEN_ENTRY); return OK; } int HttpCache::Transaction::DoOpenEntry() { TRACE_EVENT0("io", "HttpCacheTransaction::DoOpenEntry"); DCHECK(!new_entry_); - next_state_ = STATE_OPEN_ENTRY_COMPLETE; + TransitionToState(STATE_OPEN_ENTRY_COMPLETE); cache_pending_ = true; net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_OPEN_ENTRY); first_cache_access_since_ = TimeTicks::Now(); @@ -1012,12 +1017,12 @@ result); cache_pending_ = false; if (result == OK) { - next_state_ = STATE_ADD_TO_ENTRY; + TransitionToState(STATE_ADD_TO_ENTRY); return OK; } if (result == ERR_CACHE_RACE) { - next_state_ = STATE_INIT_ENTRY; + TransitionToState(STATE_INIT_ENTRY); return OK; } @@ -1025,31 +1030,31 @@ (request_->method == "HEAD" && mode_ == READ_WRITE)) { DCHECK(mode_ == READ_WRITE || mode_ == WRITE || request_->method == "HEAD"); mode_ = NONE; - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); return OK; } if (mode_ == READ_WRITE) { mode_ = WRITE; - next_state_ = STATE_CREATE_ENTRY; + TransitionToState(STATE_CREATE_ENTRY); return OK; } if (mode_ == UPDATE) { // There is no cache entry to update; proceed without caching. mode_ = NONE; - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); return OK; } // The entry does not exist, and we are not permitted to create a new entry, // so we must fail. - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_MISS; } int HttpCache::Transaction::DoDoomEntry() { TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntry"); - next_state_ = STATE_DOOM_ENTRY_COMPLETE; + TransitionToState(STATE_DOOM_ENTRY_COMPLETE); cache_pending_ = true; if (first_cache_access_since_.is_null()) first_cache_access_since_ = TimeTicks::Now(); @@ -1061,17 +1066,16 @@ TRACE_EVENT0("io", "HttpCacheTransaction::DoDoomEntryComplete"); net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY, result); - next_state_ = STATE_CREATE_ENTRY; cache_pending_ = false; - if (result == ERR_CACHE_RACE) - next_state_ = STATE_INIT_ENTRY; + TransitionToState(result == ERR_CACHE_RACE ? STATE_INIT_ENTRY + : STATE_CREATE_ENTRY); return OK; } int HttpCache::Transaction::DoCreateEntry() { TRACE_EVENT0("io", "HttpCacheTransaction::DoCreateEntry"); DCHECK(!new_entry_); - next_state_ = STATE_CREATE_ENTRY_COMPLETE; + TransitionToState(STATE_CREATE_ENTRY_COMPLETE); cache_pending_ = true; net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_CREATE_ENTRY); return cache_->CreateEntry(cache_key_, &new_entry_, this); @@ -1087,11 +1091,11 @@ cache_pending_ = false; switch (result) { case OK: - next_state_ = STATE_ADD_TO_ENTRY; + TransitionToState(STATE_ADD_TO_ENTRY); break; case ERR_CACHE_RACE: - next_state_ = STATE_INIT_ENTRY; + TransitionToState(STATE_INIT_ENTRY); break; default: @@ -1103,7 +1107,7 @@ mode_ = NONE; if (partial_) partial_->RestoreHeaders(&custom_request_->extra_headers); - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); } return OK; } @@ -1112,14 +1116,17 @@ TRACE_EVENT0("io", "HttpCacheTransaction::DoAddToEntry"); DCHECK(new_entry_); cache_pending_ = true; - next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; + TransitionToState(STATE_ADD_TO_ENTRY_COMPLETE); net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY); DCHECK(entry_lock_waiting_since_.is_null()); entry_lock_waiting_since_ = TimeTicks::Now(); int rv = cache_->AddTransactionToEntry(new_entry_, this); if (rv == ERR_IO_PENDING) { if (bypass_lock_for_test_) { - OnAddToEntryTimeout(entry_lock_waiting_since_); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(&HttpCache::Transaction::OnAddToEntryTimeout, + weak_factory_.GetWeakPtr(), entry_lock_waiting_since_)); } else { int timeout_milliseconds = 20 * 1000; if (partial_ && new_entry_->writer && @@ -1169,19 +1176,19 @@ new_entry_ = NULL; if (result == ERR_CACHE_RACE) { - next_state_ = STATE_INIT_ENTRY; + TransitionToState(STATE_INIT_ENTRY); return OK; } if (result == ERR_CACHE_LOCK_TIMEOUT) { if (mode_ == READ) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_MISS; } // The cache is busy, bypass it for this transaction. mode_ = NONE; - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); if (partial_) { partial_->RestoreHeaders(&custom_request_->extra_headers); partial_.reset(); @@ -1194,18 +1201,18 @@ // TODO(jkarlin): We should either handle the case or DCHECK. if (result != OK) { NOTREACHED(); - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return result; } if (mode_ == WRITE) { if (partial_) partial_->RestoreHeaders(&custom_request_->extra_headers); - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); } else { // We have to read the headers from the cached entry. DCHECK(mode_ & READ_META); - next_state_ = STATE_CACHE_READ_RESPONSE; + TransitionToState(STATE_CACHE_READ_RESPONSE); } return OK; } @@ -1213,7 +1220,7 @@ int HttpCache::Transaction::DoCacheReadResponse() { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadResponse"); DCHECK(entry_); - next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE; + TransitionToState(STATE_CACHE_READ_RESPONSE_COMPLETE); io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); read_buf_ = new IOBuffer(io_buf_len_); @@ -1254,7 +1261,7 @@ // will fall back to the network after the timeout. DCHECK(!partial_); mode_ = NONE; - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); return OK; } @@ -1263,11 +1270,11 @@ // Either this is the first use of an entry since it was prefetched XOR // this is a prefetch. The value of response.unused_since_prefetch is // valid for this transaction but the bit needs to be flipped in storage. - next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH; + TransitionToState(STATE_TOGGLE_UNUSED_SINCE_PREFETCH); return OK; } - next_state_ = STATE_CACHE_DISPATCH_VALIDATION; + TransitionToState(STATE_CACHE_DISPATCH_VALIDATION); return OK; } @@ -1280,7 +1287,7 @@ // transaction then metadata will be written to cache twice. If prefetching // becomes more common, consider combining the writes. - next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE; + TransitionToState(STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE); return WriteResponseInfoToEntry(false); } @@ -1291,7 +1298,7 @@ "HttpCacheTransaction::DoCacheToggleUnusedSincePrefetchComplete"); // Restore the original value for this transaction. response_.unused_since_prefetch = !response_.unused_since_prefetch; - next_state_ = STATE_CACHE_DISPATCH_VALIDATION; + TransitionToState(STATE_CACHE_DISPATCH_VALIDATION); return OnWriteResponseInfoToEntryComplete(result); } @@ -1330,14 +1337,14 @@ } int HttpCache::Transaction::DoCacheQueryData() { - next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; + TransitionToState(STATE_CACHE_QUERY_DATA_COMPLETE); return entry_->disk_entry->ReadyForSparseIO(io_callback_); } int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { DCHECK_EQ(OK, result); if (!cache_.get()) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_UNEXPECTED; } @@ -1347,11 +1354,11 @@ // We may end up here multiple times for a given request. int HttpCache::Transaction::DoStartPartialCacheValidation() { if (mode_ == NONE) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OK; } - next_state_ = STATE_COMPLETE_PARTIAL_CACHE_VALIDATION; + TransitionToState(STATE_COMPLETE_PARTIAL_CACHE_VALIDATION); return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); } @@ -1364,12 +1371,12 @@ cache_->DoneReadingFromEntry(entry_, this); entry_ = NULL; } - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return result; } if (result < 0) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return result; } @@ -1377,7 +1384,7 @@ &custom_request_->extra_headers); if (reading_ && partial_->IsCurrentRangeCached()) { - next_state_ = STATE_CACHE_READ_DATA; + TransitionToState(STATE_CACHE_READ_DATA); return OK; } @@ -1395,7 +1402,7 @@ int rv = cache_->network_layer_->CreateTransaction(priority_, &network_trans_); if (rv != OK) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return rv; } network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_); @@ -1409,7 +1416,7 @@ network_trans_->SetWebSocketHandshakeStreamCreateHelper( websocket_handshake_stream_base_create_helper_); - next_state_ = STATE_SEND_REQUEST_COMPLETE; + TransitionToState(STATE_SEND_REQUEST_COMPLETE); rv = network_trans_->Start(request_, io_callback_, net_log_); return rv; } @@ -1417,7 +1424,7 @@ int HttpCache::Transaction::DoSendRequestComplete(int result) { TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequestComplete"); if (!cache_.get()) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_UNEXPECTED; } @@ -1427,7 +1434,7 @@ mode_ = WRITE; if (result == OK) { - next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; + TransitionToState(STATE_SUCCESSFUL_SEND_REQUEST); return OK; } @@ -1448,7 +1455,7 @@ DoneWritingToEntry(true); } - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return result; } @@ -1462,7 +1469,7 @@ new_response->headers->response_code() == 407) { SetAuthResponse(*new_response); if (!reading_) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OK; } @@ -1471,7 +1478,7 @@ // this URL moments ago. if (IsReadyToRestartForAuth()) { DCHECK(!response_.auth_challenge.get()); - next_state_ = STATE_SEND_REQUEST_COMPLETE; + TransitionToState(STATE_SEND_REQUEST_COMPLETE); // In theory we should check to see if there are new cookies, but there // is no way to do that from here. return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_); @@ -1487,7 +1494,7 @@ mode_ = NONE; partial_.reset(); ResetNetworkTransaction(); - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_AUTH_FAILURE_AFTER_READ; } @@ -1502,7 +1509,7 @@ SetResponse(HttpResponseInfo()); ResetNetworkTransaction(); new_response_ = NULL; - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); return OK; } @@ -1543,7 +1550,7 @@ (request_->method == "GET" || request_->method == "POST")) { // If there is an active entry it may be destroyed with this transaction. SetResponse(*new_response_); - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OK; } @@ -1551,21 +1558,20 @@ if (mode_ == READ_WRITE || mode_ == UPDATE) { if (new_response->headers->response_code() == 304 || handling_206_) { UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); - next_state_ = STATE_UPDATE_CACHED_RESPONSE; + TransitionToState(STATE_UPDATE_CACHED_RESPONSE); return OK; } UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); mode_ = WRITE; } - next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; + TransitionToState(STATE_OVERWRITE_CACHED_RESPONSE); return OK; } // We received 304 or 206 and we want to update the cached response headers. int HttpCache::Transaction::DoUpdateCachedResponse() { TRACE_EVENT0("io", "HttpCacheTransaction::DoUpdateCachedResponse"); - next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; int rv = OK; // Update the cached response based on the headers and properties of // new_response_. @@ -1590,28 +1596,32 @@ int ret = cache_->DoomEntry(cache_key_, NULL); DCHECK_EQ(OK, ret); } + TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE); } else { // If we are already reading, we already updated the headers for this // request; doing it again will change Content-Length. if (!reading_) { - next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE; + TransitionToState(STATE_CACHE_WRITE_UPDATED_RESPONSE); rv = OK; + } else { + TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE); } } + return rv; } int HttpCache::Transaction::DoCacheWriteUpdatedResponse() { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteUpdatedResponse"); - next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE; + TransitionToState(STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE); return WriteResponseInfoToEntry(false); } int HttpCache::Transaction::DoCacheWriteUpdatedResponseComplete(int result) { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteUpdatedResponseComplete"); - next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; + TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE); return OnWriteResponseInfoToEntryComplete(result); } @@ -1640,18 +1650,18 @@ // the first part to the user. ResetNetworkTransaction(); new_response_ = NULL; - next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; + TransitionToState(STATE_START_PARTIAL_CACHE_VALIDATION); partial_->SetRangeToStartDownload(); return OK; } - next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; + TransitionToState(STATE_OVERWRITE_CACHED_RESPONSE); return OK; } int HttpCache::Transaction::DoOverwriteCachedResponse() { TRACE_EVENT0("io", "HttpCacheTransaction::DoOverwriteCachedResponse"); if (mode_ & READ) { - next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; + TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); return OK; } @@ -1666,7 +1676,7 @@ DoneWritingToEntry(false); mode_ = NONE; new_response_ = NULL; - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OK; } @@ -1676,29 +1686,29 @@ DoneWritingToEntry(false); if (partial_) partial_->FixResponseHeaders(response_.headers.get(), true); - next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; + TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); return OK; } - next_state_ = STATE_CACHE_WRITE_RESPONSE; + TransitionToState(STATE_CACHE_WRITE_RESPONSE); return OK; } int HttpCache::Transaction::DoCacheWriteResponse() { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); - next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; + TransitionToState(STATE_CACHE_WRITE_RESPONSE_COMPLETE); return WriteResponseInfoToEntry(truncated_); } int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); - next_state_ = STATE_TRUNCATE_CACHED_DATA; + TransitionToState(STATE_TRUNCATE_CACHED_DATA); return OnWriteResponseInfoToEntryComplete(result); } int HttpCache::Transaction::DoTruncateCachedData() { TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); - next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; + TransitionToState(STATE_TRUNCATE_CACHED_DATA_COMPLETE); if (!entry_) return OK; if (net_log_.IsCapturing()) @@ -1716,13 +1726,13 @@ } } - next_state_ = STATE_TRUNCATE_CACHED_METADATA; + TransitionToState(STATE_TRUNCATE_CACHED_METADATA); return OK; } int HttpCache::Transaction::DoTruncateCachedMetadata() { TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedMetadata"); - next_state_ = STATE_TRUNCATE_CACHED_METADATA_COMPLETE; + TransitionToState(STATE_TRUNCATE_CACHED_METADATA_COMPLETE); if (!entry_) return OK; @@ -1740,7 +1750,7 @@ } } - next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; + TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); return OK; } @@ -1749,25 +1759,25 @@ if (!partial_) { if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) - next_state_ = STATE_CACHE_READ_METADATA; + TransitionToState(STATE_CACHE_READ_METADATA); else - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OK; } if (reading_) { if (network_trans_.get()) { - next_state_ = STATE_NETWORK_READ; + TransitionToState(STATE_NETWORK_READ); } else { - next_state_ = STATE_CACHE_READ_DATA; + TransitionToState(STATE_CACHE_READ_DATA); } } else if (mode_ != NONE) { // We are about to return the headers for a byte-range request to the user, // so let's fix them. partial_->FixResponseHeaders(response_.headers.get(), true); - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); } else { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); } return OK; } @@ -1776,7 +1786,7 @@ TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata"); DCHECK(entry_); DCHECK(!response_.metadata.get()); - next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; + TransitionToState(STATE_CACHE_READ_METADATA_COMPLETE); response_.metadata = new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); @@ -1794,13 +1804,13 @@ result); if (result != response_.metadata->size()) return OnCacheReadError(result, false); - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OK; } int HttpCache::Transaction::DoNetworkRead() { TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); - next_state_ = STATE_NETWORK_READ_COMPLETE; + TransitionToState(STATE_NETWORK_READ_COMPLETE); return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); } @@ -1809,18 +1819,18 @@ DCHECK(mode_ & WRITE || mode_ == NONE); if (!cache_.get()) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_UNEXPECTED; } // If there is an error or we aren't saving the data, we are done; just wait // until the destructor runs to see if we can keep the data. if (mode_ == NONE || result < 0) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return result; } - next_state_ = STATE_CACHE_WRITE_DATA; + TransitionToState(STATE_CACHE_WRITE_DATA); return result; } @@ -1828,12 +1838,12 @@ TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); if (request_->method == "HEAD") { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return 0; } DCHECK(entry_); - next_state_ = STATE_CACHE_READ_DATA_COMPLETE; + TransitionToState(STATE_CACHE_READ_DATA_COMPLETE); if (net_log_.IsCapturing()) net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); @@ -1855,7 +1865,7 @@ } if (!cache_.get()) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_UNEXPECTED; } @@ -1876,13 +1886,13 @@ return OnCacheReadError(result, false); } - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return result; } int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteData"); - next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; + TransitionToState(STATE_CACHE_WRITE_DATA_COMPLETE); write_len_ = num_bytes; if (entry_) { if (net_log_.IsCapturing()) @@ -1906,7 +1916,7 @@ } } if (!cache_.get()) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_UNEXPECTED; } @@ -1941,20 +1951,20 @@ } } - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return result; } int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); - next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; + TransitionToState(STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE); return WriteResponseInfoToEntry(true); } int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OnWriteResponseInfoToEntryComplete(result); } @@ -2091,18 +2101,18 @@ // TODO(jkarlin): Either handle this case or DCHECK. if (response_.headers->response_code() == 206 || partial_) { NOTREACHED(); - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_MISS; } // We don't have the whole resource. if (truncated_) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_MISS; } if (RequiresValidation() != VALIDATION_NONE) { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_MISS; } @@ -2110,9 +2120,9 @@ FixHeadersForHead(); if (entry_->disk_entry->GetDataSize(kMetadataIndex)) - next_state_ = STATE_CACHE_READ_METADATA; + TransitionToState(STATE_CACHE_READ_METADATA); else - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OK; } @@ -2138,7 +2148,7 @@ return SetupEntryForRead(); // Bail out! - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); mode_ = NONE; return OK; } @@ -2176,7 +2186,7 @@ DCHECK_NE(206, response_.headers->response_code()); } - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); } return OK; } @@ -2203,7 +2213,7 @@ } } - next_state_ = STATE_CACHE_QUERY_DATA; + TransitionToState(STATE_CACHE_QUERY_DATA); return OK; } @@ -2224,7 +2234,7 @@ invalid_range_ = true; } - next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; + TransitionToState(STATE_START_PARTIAL_CACHE_VALIDATION); return OK; } @@ -2267,7 +2277,7 @@ type, EXTERNALLY_CONDITIONALIZED_MAX); - next_state_ = STATE_SEND_REQUEST; + TransitionToState(STATE_SEND_REQUEST); return OK; } @@ -2619,7 +2629,7 @@ if (truncated_ || is_sparse_ || !invalid_range_) { // We are going to return the saved response headers to the caller, so // we may need to adjust them first. - next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; + TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); return OK; } else { partial_.reset(); @@ -2632,9 +2642,9 @@ FixHeadersForHead(); if (entry_->disk_entry->GetDataSize(kMetadataIndex)) - next_state_ = STATE_CACHE_READ_METADATA; + TransitionToState(STATE_CACHE_READ_METADATA); else - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return OK; } @@ -2740,11 +2750,11 @@ entry_ = NULL; is_sparse_ = false; partial_.reset(); - next_state_ = STATE_GET_BACKEND; + TransitionToState(STATE_GET_BACKEND); return OK; } - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); return ERR_CACHE_READ_FAILURE; } @@ -2779,9 +2789,9 @@ if (result == 0) { // We need to move on to the next range. ResetNetworkTransaction(); - next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; + TransitionToState(STATE_START_PARTIAL_CACHE_VALIDATION); } else { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); } return result; } @@ -2791,11 +2801,11 @@ if (result == 0 && mode_ == READ_WRITE) { // We need to move on to the next range. - next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; + TransitionToState(STATE_START_PARTIAL_CACHE_VALIDATION); } else if (result < 0) { return OnCacheReadError(result, false); } else { - next_state_ = STATE_NONE; + TransitionToState(STATE_NONE); } return result; } @@ -2808,7 +2818,7 @@ // to Doom the entry again). mode_ = WRITE; ResetPartialState(!range_requested_); - next_state_ = STATE_CREATE_ENTRY; + TransitionToState(STATE_CREATE_ENTRY); return OK; } @@ -3073,4 +3083,11 @@ DoLoop(result); } +void HttpCache::Transaction::TransitionToState(State state) { + // Ensure that the state is only set once per Do* state. + DCHECK(in_do_loop_); + DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state; + next_state_ = state; +} + } // namespace net
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h index 0998695..a8fca542 100644 --- a/net/http/http_cache_transaction.h +++ b/net/http/http_cache_transaction.h
@@ -434,6 +434,10 @@ // Called to signal completion of asynchronous IO. void OnIOComplete(int result); + // When in a DoLoop, use this to set the next state as it verifies that the + // state isn't set twice. + void TransitionToState(State state); + State next_state_; const HttpRequestInfo* request_; RequestPriority priority_; @@ -508,6 +512,9 @@ BeforeNetworkStartCallback before_network_start_callback_; BeforeHeadersSentCallback before_headers_sent_callback_; + // True if the Transaction is currently processing the DoLoop. + bool in_do_loop_; + base::WeakPtrFactory<Transaction> weak_factory_; DISALLOW_COPY_AND_ASSIGN(Transaction);
diff --git a/services/service_manager/runner/host/service_process_launcher.cc b/services/service_manager/runner/host/service_process_launcher.cc index 3b92bf6..52077bb 100644 --- a/services/service_manager/runner/host/service_process_launcher.cc +++ b/services/service_manager/runner/host/service_process_launcher.cc
@@ -189,10 +189,17 @@ } if (child_process_.IsValid()) { - DVLOG(0) << "Launched child process pid=" << child_process_.Pid() - << ", instance=" << target_.instance() - << ", name=" << target_.name() - << ", user_id=" << target_.user_id(); +#if defined(OS_CHROMEOS) + // Always log instead of DVLOG because knowing which pid maps to which + // service is vital for interpreting crashes after-the-fact and Chrome OS + // devices generally run release builds, even in development. + VLOG(0) +#else + DVLOG(0) +#endif + << "Launched child process pid=" << child_process_.Pid() + << ", instance=" << target_.instance() << ", name=" << target_.name() + << ", user_id=" << target_.user_id(); if (mojo_ipc_channel_.get()) { mojo_ipc_channel_->ChildProcessLaunched();
diff --git a/services/ui/public/interfaces/window_tree.mojom b/services/ui/public/interfaces/window_tree.mojom index e38b7f0..13de19f 100644 --- a/services/ui/public/interfaces/window_tree.mojom +++ b/services/ui/public/interfaces/window_tree.mojom
@@ -339,6 +339,11 @@ // change. OnCaptureChanged(uint32 new_capture, uint32 old_capture); + // This is called on the owner of a window when it embeds a client in it, + // which includes the window manager creating a new window at the request of + // another client. + OnFrameSinkIdAllocated(uint32 window, cc.mojom.FrameSinkId frame_sink_id); + // Called in response to NewTopLevelWindow() successfully completing. // |parent_drawn| is true if the parent of the window is drawn, see // OnDrawnStateChanged() for details. |display_id| identifies the display this
diff --git a/services/ui/ws/test_change_tracker.cc b/services/ui/ws/test_change_tracker.cc index 06f9344..e52a2da1 100644 --- a/services/ui/ws/test_change_tracker.cc +++ b/services/ui/ws/test_change_tracker.cc
@@ -54,6 +54,11 @@ WindowIdToString(change.window_id).c_str(), WindowIdToString(change.window_id2).c_str()); + case CHANGE_TYPE_FRAME_SINK_ID_ALLOCATED: + return base::StringPrintf("OnFrameSinkIdAllocated window=%s %s", + WindowIdToString(change.window_id).c_str(), + change.frame_sink_id.ToString().c_str()); + case CHANGE_TYPE_NODE_ADD_TRANSIENT_WINDOW: return base::StringPrintf("AddTransientWindow parent = %s child = %s", WindowIdToString(change.window_id).c_str(), @@ -304,6 +309,16 @@ AddChange(change); } +void TestChangeTracker::OnFrameSinkIdAllocated( + Id window_id, + const cc::FrameSinkId& frame_sink_id) { + Change change; + change.type = CHANGE_TYPE_FRAME_SINK_ID_ALLOCATED; + change.window_id = window_id; + change.frame_sink_id = frame_sink_id; + AddChange(change); +} + void TestChangeTracker::OnWindowHierarchyChanged( Id window_id, Id old_parent_id,
diff --git a/services/ui/ws/test_change_tracker.h b/services/ui/ws/test_change_tracker.h index 84c978e8..d736fe67 100644 --- a/services/ui/ws/test_change_tracker.h +++ b/services/ui/ws/test_change_tracker.h
@@ -22,6 +22,7 @@ enum ChangeType { CHANGE_TYPE_CAPTURE_CHANGED, + CHANGE_TYPE_FRAME_SINK_ID_ALLOCATED, CHANGE_TYPE_EMBED, CHANGE_TYPE_EMBEDDED_APP_DISCONNECTED, CHANGE_TYPE_UNEMBED, @@ -148,6 +149,8 @@ void OnEmbeddedAppDisconnected(Id window_id); void OnUnembed(Id window_id); void OnCaptureChanged(Id new_capture_window_id, Id old_capture_window_id); + void OnFrameSinkIdAllocated(Id window_id, + const cc::FrameSinkId& frame_sink_id); void OnTransientWindowAdded(Id window_id, Id transient_window_id); void OnTransientWindowRemoved(Id window_id, Id transient_window_id); void OnWindowBoundsChanged(
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc index 61d1932..48c2ae8 100644 --- a/services/ui/ws/test_utils.cc +++ b/services/ui/ws/test_utils.cc
@@ -290,6 +290,12 @@ tracker_.OnCaptureChanged(new_capture_window_id, old_capture_window_id); } +void TestWindowTreeClient::OnFrameSinkIdAllocated( + Id window_id, + const cc::FrameSinkId& frame_sink_id) { + tracker_.OnFrameSinkIdAllocated(window_id, frame_sink_id); +} + void TestWindowTreeClient::OnTopLevelCreated( uint32_t change_id, mojom::WindowDataPtr data,
diff --git a/services/ui/ws/test_utils.h b/services/ui/ws/test_utils.h index 3f68927..df4488d 100644 --- a/services/ui/ws/test_utils.h +++ b/services/ui/ws/test_utils.h
@@ -404,6 +404,8 @@ void OnUnembed(Id window_id) override; void OnCaptureChanged(Id new_capture_window_id, Id old_capture_window_id) override; + void OnFrameSinkIdAllocated(Id window_id, + const cc::FrameSinkId& frame_sink_id) override; void OnTopLevelCreated(uint32_t change_id, mojom::WindowDataPtr data, int64_t display_id,
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc index df00978b..c6651fe 100644 --- a/services/ui/ws/window_tree.cc +++ b/services/ui/ws/window_tree.cc
@@ -470,17 +470,18 @@ } bool WindowTree::Embed(const ClientWindowId& window_id, - mojom::WindowTreeClientPtr client, + mojom::WindowTreeClientPtr window_tree_client, uint32_t flags) { - if (!client || !CanEmbed(window_id)) + if (!window_tree_client || !CanEmbed(window_id)) return false; ServerWindow* window = GetWindowByClientId(window_id); PrepareForEmbed(window); // When embedding we don't know the user id of where the TreeClient came // from. Use an invalid id, which limits what the client is able to do. - window_server_->EmbedAtWindow(window, InvalidUserId(), std::move(client), - flags, + window_server_->EmbedAtWindow(window, InvalidUserId(), + std::move(window_tree_client), flags, base::WrapUnique(new DefaultAccessPolicy)); + client()->OnFrameSinkIdAllocated(window_id.id, window->frame_sink_id()); return true; } @@ -2075,6 +2076,10 @@ window_server_->WindowManagerSentBogusMessage(); window = nullptr; } + if (window) { + client()->OnFrameSinkIdAllocated(transport_window_id, + window->frame_sink_id()); + } window_server_->WindowManagerCreatedTopLevelWindow(this, change_id, window); }
diff --git a/services/ui/ws/window_tree.h b/services/ui/ws/window_tree.h index 4a03b18..756c155 100644 --- a/services/ui/ws/window_tree.h +++ b/services/ui/ws/window_tree.h
@@ -180,7 +180,7 @@ bool SetWindowOpacity(const ClientWindowId& window_id, float opacity); bool SetFocus(const ClientWindowId& window_id); bool Embed(const ClientWindowId& window_id, - mojom::WindowTreeClientPtr client, + mojom::WindowTreeClientPtr window_tree_client, uint32_t flags); void DispatchInputEvent(ServerWindow* target, const ui::Event& event);
diff --git a/services/ui/ws/window_tree_client_unittest.cc b/services/ui/ws/window_tree_client_unittest.cc index eb2425f..cdfe5ce 100644 --- a/services/ui/ws/window_tree_client_unittest.cc +++ b/services/ui/ws/window_tree_client_unittest.cc
@@ -298,6 +298,8 @@ Id old_capture_window_id) override { tracker()->OnCaptureChanged(new_capture_window_id, old_capture_window_id); } + void OnFrameSinkIdAllocated(Id window_id, + const cc::FrameSinkId& frame_sink_id) override {} void OnTopLevelCreated(uint32_t change_id, mojom::WindowDataPtr data, int64_t display_id,
diff --git a/services/ui/ws/window_tree_unittest.cc b/services/ui/ws/window_tree_unittest.cc index be17bc3..df3860e 100644 --- a/services/ui/ws/window_tree_unittest.cc +++ b/services/ui/ws/window_tree_unittest.cc
@@ -664,6 +664,34 @@ ChangesToDescription1(*wm_client()->tracker()->changes())[0]); } +// Establish client, call Embed() in WM, make sure to get FrameSinkId. +TEST_F(WindowTreeTest, Embed) { + const ClientWindowId embed_window_id = BuildClientWindowId(wm_tree(), 1); + EXPECT_TRUE( + wm_tree()->NewWindow(embed_window_id, ServerWindow::Properties())); + ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id); + ASSERT_TRUE(embed_window); + const ClientWindowId wm_root_id = FirstRootId(wm_tree()); + EXPECT_TRUE(wm_tree()->AddWindow(wm_root_id, embed_window_id)); + ServerWindow* wm_root = FirstRoot(wm_tree()); + ASSERT_TRUE(wm_root); + mojom::WindowTreeClientPtr client; + mojom::WindowTreeClientRequest client_request(&client); + wm_client()->Bind(std::move(client_request)); + const uint32_t embed_flags = 0; + wm_tree()->Embed(embed_window_id, std::move(client), embed_flags); + ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()) + << SingleChangeToDescription(*wm_client()->tracker()->changes()); + // The window manager should be told about the FrameSinkId of the embedded + // window. + EXPECT_EQ( + base::StringPrintf( + "OnFrameSinkIdAllocated window=%s %s", + WindowIdToString(WindowIdFromTransportId(embed_window_id.id)).c_str(), + embed_window->frame_sink_id().ToString().c_str()), + SingleChangeToDescription(*wm_client()->tracker()->changes())); +} + // Establish client, call NewTopLevelWindow(), make sure get id, and make // sure client paused. TEST_F(WindowTreeTest, NewTopLevelWindow) { @@ -700,9 +728,20 @@ child_binding->client()->tracker()->changes()->clear(); static_cast<mojom::WindowManagerClient*>(wm_tree()) ->OnWmCreatedTopLevelWindow(wm_change_id, embed_window_id2.id); - EXPECT_FALSE(child_binding->is_paused()); + ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id2); ASSERT_TRUE(embed_window); + ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()) + << SingleChangeToDescription(*wm_client()->tracker()->changes()); + // The window manager should be told about the FrameSinkId of the embedded + // window. + EXPECT_EQ(base::StringPrintf( + "OnFrameSinkIdAllocated window=%s %s", + WindowIdToString(WindowIdFromTransportId(embed_window_id2.id)) + .c_str(), + embed_window->frame_sink_id().ToString().c_str()), + SingleChangeToDescription(*wm_client()->tracker()->changes())); + EXPECT_FALSE(child_binding->is_paused()); // TODO(fsamuel): Currently the FrameSinkId maps directly to the server's // window ID. This is likely bad from a security perspective and should be // fixed.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 356de3d1..e1974de 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -556,21 +556,6 @@ ] } ], - "DisableFirstRunAutoImport": [ - { - "platforms": [ - "win" - ], - "experiments": [ - { - "name": "AutoImportDisabled", - "enable_features": [ - "DisableFirstRunAutoImport" - ] - } - ] - } - ], "DisallowFetchForDocWrittenScriptsInMainFrame": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index a0c3ee5c..4c3e22f 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -125,9 +125,6 @@ # A real bug with a Skia assert crbug.com/671048 virtual/color_space/fast/canvas/color-space/display_linear-rgb.html [ Pass Failure Crash ] -crbug.com/683339 paint/invalidation/paged-with-overflowing-block-rl.html [ Failure ] -crbug.com/683339 virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl.html [ Failure ] - crbug.com/701800 [ Win7 ] virtual/disable-spinvalidation/compositing/perpendicular-layer-sorting.html [ Pass Failure ] crbug.com/702006 paint/invalidation/compositing/scrolling-neg-z-index-descendants-should-cause-repaint.html [ Failure ] @@ -815,8 +812,6 @@ crbug.com/520188 [ Win ] http/tests/local/fileapi/file-last-modified-after-delete.html [ Failure Pass ] crbug.com/520188 [ Win ] virtual/mojo-loading/http/tests/local/fileapi/file-last-modified-after-delete.html [ Failure Pass ] crbug.com/520611 [ Debug ] fast/filesystem/workers/file-writer-events-shared-worker.html [ Failure Pass ] -crbug.com/520613 http/tests/cache/freshness-header.html [ Failure Pass ] -crbug.com/520613 virtual/mojo-loading/http/tests/cache/freshness-header.html [ Failure Pass ] crbug.com/520194 http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-overridesexpires.html [ Failure Pass ] crbug.com/520194 virtual/mojo-loading/http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-overridesexpires.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/http/tests/cache/freshness-header.html b/third_party/WebKit/LayoutTests/http/tests/cache/freshness-header.html deleted file mode 100644 index f0332d0..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cache/freshness-header.html +++ /dev/null
@@ -1,31 +0,0 @@ -<!DOCTYPE html> -<script src="/js-test-resources/js-test.js"></script> -<script> -description("Resource-Freshness header is sent when a revalidation request is initiated by the Blink memory cache within the stale-while-revalidate window."); - -var resourceFreshnessHeader; -function report(value) { - resourceFreshnessHeader = value; -} - -window.jsTestIsAsync = true; - -window.onload = function () { - // We set the timeout to 500 msec here because we expect age=1 in the - // ResourceFreshness header if the age is [0.5, 1.5) seconds. - setTimeout( - function() { - var script = document.createElement("script"); - script.src = "resources/stale-while-revalidate.php"; - script.onload = function() { - shouldBeEqualToString( - 'resourceFreshnessHeader', - 'max-age=0,stale-while-revalidate=1,age=1'); - finishJSTest(); - }; - document.body.appendChild(script); - }, - 500); -}; -</script> -<script src="resources/stale-while-revalidate.php"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cache/resources/stale-while-revalidate.php b/third_party/WebKit/LayoutTests/http/tests/cache/resources/stale-while-revalidate.php deleted file mode 100644 index cb7fd72..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cache/resources/stale-while-revalidate.php +++ /dev/null
@@ -1,8 +0,0 @@ -<?php -$last_modified = gmdate(DATE_RFC1123, time() - 1); - -header('Cache-Control: private, max-age=0, stale-while-revalidate=1'); -header('Last-Modified: ' . $last_modified); -header('Content-Type: application/javascript'); -echo('report("' . $_SERVER['HTTP_RESOURCE_FRESHNESS'] . '");'); -?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-test.js index 219cfb2..4072611 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/appcache/appcache-test.js
@@ -81,7 +81,7 @@ InspectorTest.dumpApplicationCacheTree = function() { InspectorTest.addResult("Dumping application cache tree:"); - var applicationCacheTreeElement = UI.panels.resources.applicationCacheListTreeElement; + var applicationCacheTreeElement = UI.panels.resources._sidebar.applicationCacheListTreeElement; if (!applicationCacheTreeElement.childCount()) { InspectorTest.addResult(" (empty)"); return; @@ -127,7 +127,7 @@ InspectorTest.dumpApplicationCacheModel = function() { InspectorTest.addResult("Dumping application cache model:"); - var model = UI.panels.resources._applicationCacheModel; + var model = UI.panels.resources._sidebar._applicationCacheModel; var frameIds = []; for (var frameId in model._manifestURLsByFrame) @@ -154,8 +154,8 @@ InspectorTest.waitForFrameManifestURLAndStatus = function(frameId, manifestURL, status, callback) { - var frameManifestStatus = UI.panels.resources._applicationCacheModel.frameManifestStatus(frameId); - var frameManifestURL = UI.panels.resources._applicationCacheModel.frameManifestURL(frameId); + var frameManifestStatus = UI.panels.resources._sidebar._applicationCacheModel.frameManifestStatus(frameId); + var frameManifestURL = UI.panels.resources._sidebar._applicationCacheModel.frameManifestURL(frameId); if (frameManifestStatus === status && frameManifestURL.indexOf(manifestURL) !== -1) { callback(); return;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-storage-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-storage-test.js index 1f6c7cb3..46fd8ae 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-storage-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-storage-test.js
@@ -7,9 +7,9 @@ InspectorTest.dumpCacheTree = function() { - UI.panels.resources.cacheStorageListTreeElement.expand(); + UI.panels.resources._sidebar.cacheStorageListTreeElement.expand(); InspectorTest.addResult("Dumping CacheStorage tree:"); - var cachesTreeElement = UI.panels.resources.cacheStorageListTreeElement; + var cachesTreeElement = UI.panels.resources._sidebar.cacheStorageListTreeElement; var promise = new Promise(function(resolve, reject) { InspectorTest.addSnifferPromise(SDK.ServiceWorkerCacheModel.prototype, "_updateCacheNames").then(crawlCacheTree).catch(reject); @@ -65,20 +65,20 @@ } } }); - UI.panels.resources.cacheStorageListTreeElement._refreshCaches(); + UI.panels.resources._sidebar.cacheStorageListTreeElement._refreshCaches(); return promise; } // If optionalEntry is not specified, then the whole cache is deleted. InspectorTest.deleteCacheFromInspector = function(cacheName, optionalEntry) { - UI.panels.resources.cacheStorageListTreeElement.expand(); + UI.panels.resources._sidebar.cacheStorageListTreeElement.expand(); if (optionalEntry) { InspectorTest.addResult("Deleting CacheStorage entry " + optionalEntry + " in cache " + cacheName); } else { InspectorTest.addResult("Deleting CacheStorage cache " + cacheName); } - var cachesTreeElement = UI.panels.resources.cacheStorageListTreeElement; + var cachesTreeElement = UI.panels.resources._sidebar.cacheStorageListTreeElement; var promise = new Promise(function(resolve, reject) { InspectorTest.addSnifferPromise(SDK.ServiceWorkerCacheModel.prototype, "_updateCacheNames") .then(function() { @@ -124,7 +124,7 @@ reject("Error: Could not find CacheStorage cache " + cacheName); }).catch(reject); }); - UI.panels.resources.cacheStorageListTreeElement._refreshCaches(); + UI.panels.resources._sidebar.cacheStorageListTreeElement._refreshCaches(); return promise; }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/indexeddb/indexeddb-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/indexeddb/indexeddb-test.js index 9a85f61..9547f4a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/indexeddb/indexeddb-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/indexeddb/indexeddb-test.js
@@ -4,7 +4,7 @@ InspectorTest.dumpIndexedDBTree = function() { InspectorTest.addResult("Dumping IndexedDB tree:"); - var indexedDBTreeElement = UI.panels.resources.indexedDBListTreeElement; + var indexedDBTreeElement = UI.panels.resources._sidebar.indexedDBListTreeElement; if (!indexedDBTreeElement.childCount()) { InspectorTest.addResult(" (empty)"); return;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/indexeddb/resources-panel.html b/third_party/WebKit/LayoutTests/http/tests/inspector/indexeddb/resources-panel.html index 4c28029..f5dd2bdc 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/indexeddb/resources-panel.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/indexeddb/resources-panel.html
@@ -70,7 +70,7 @@ UI.viewManager.showView("resources"); InspectorTest.addResult("Expanded IndexedDB tree element."); - UI.panels.resources.indexedDBListTreeElement.expand(); + UI.panels.resources._sidebar.indexedDBListTreeElement.expand(); InspectorTest.dumpIndexedDBTree(); InspectorTest.addResult("Created database."); createDatabase(databaseCreated); @@ -79,7 +79,7 @@ { indexedDBModel = InspectorTest.indexedDBModel(); indexedDBModel.addEventListener(Resources.IndexedDBModel.Events.DatabaseLoaded, databaseLoaded); - UI.panels.resources.indexedDBListTreeElement.refreshIndexedDB(); + UI.panels.resources._sidebar.indexedDBListTreeElement.refreshIndexedDB(); } function databaseLoaded() @@ -106,14 +106,14 @@ function databaseDeleted() { - UI.panels.resources.indexedDBListTreeElement.refreshIndexedDB(); + UI.panels.resources._sidebar.indexedDBListTreeElement.refreshIndexedDB(); InspectorTest.addSniffer(Resources.IndexedDBModel.prototype, "_updateOriginDatabaseNames", databaseNamesLoadedAfterDeleting, false); } function databaseNamesLoadedAfterDeleting() { InspectorTest.dumpIndexedDBTree(); - UI.panels.resources.indexedDBListTreeElement.collapse(); + UI.panels.resources._sidebar.indexedDBListTreeElement.collapse(); InspectorTest.completeTest(); } }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-test.js index 31659ff..7382307c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/resource-tree/resource-tree-test.js
@@ -64,7 +64,7 @@ dump(children[i], prefix + " "); } - dump(UI.panels.resources._resourcesSection._treeElement, ""); + dump(UI.panels.resources._sidebar._resourcesSection._treeElement, ""); if (!InspectorTest._testSourceNavigator) { InspectorTest._testSourceNavigator = new Sources.SourcesNavigatorView(); InspectorTest._testSourceNavigator.show(UI.inspectorView.element);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html index ac59b8e..102e0f3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html
@@ -90,7 +90,7 @@ InspectorTest.deleteServiceWorkerRegistration(scope); InspectorTest.completeTest(); }); - UI.panels.resources.serviceWorkersTreeElement.select(); + UI.panels.resources._sidebar.serviceWorkersTreeElement.select(); InspectorTest.registerServiceWorker(scriptURL, scope); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view.html b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view.html index 8f4aec5b..a553528b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-view.html
@@ -42,7 +42,7 @@ } InspectorTest.addResult("Select ServiceWorkers tree element."); - UI.panels.resources.serviceWorkersTreeElement.select(); + UI.panels.resources._sidebar.serviceWorkersTreeElement.select(); InspectorTest.addResult("Register ServiceWorker for scope1"); InspectorTest.registerServiceWorker(scriptURL, scope1); }
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/resolve-alien-node.html b/third_party/WebKit/LayoutTests/inspector/elements/resolve-alien-node.html index c33ff51d8..daee268c 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/resolve-alien-node.html +++ b/third_party/WebKit/LayoutTests/inspector/elements/resolve-alien-node.html
@@ -10,7 +10,7 @@ function step1(error, result, exceptionDetails) { var spanWrapper = InspectorTest.runtimeModel.createRemoteObject(result); - InspectorTest.domModel.pushObjectAsNodeToFrontend(spanWrapper, step2); + InspectorTest.domModel.pushObjectAsNodeToFrontend(spanWrapper).then(step2); } function step2(node)
diff --git a/third_party/WebKit/LayoutTests/inspector/extensions/extensions-panel.html b/third_party/WebKit/LayoutTests/inspector/extensions/extensions-panel.html index 78c6d05..45532d9 100644 --- a/third_party/WebKit/LayoutTests/inspector/extensions/extensions-panel.html +++ b/third_party/WebKit/LayoutTests/inspector/extensions/extensions-panel.html
@@ -92,7 +92,7 @@ } InspectorTest.recordNetwork(); InspectorTest.addSniffer(UI.panels.sources, "showUILocation", showUILocationHook, true); - InspectorTest.addSniffer(UI.panels.resources, "showResource", showResourceHook, true); + InspectorTest.addSniffer(UI.panels.resources._sidebar, "showResource", showResourceHook, true); InspectorTest.addSniffer(UI.panels.network, "revealAndHighlightRequest", showRequestHook, true); function showUILocationHook(uiLocation)
diff --git a/third_party/WebKit/LayoutTests/inspector/reveal-objects.html b/third_party/WebKit/LayoutTests/inspector/reveal-objects.html index 5437ac9..7f2480dc 100644 --- a/third_party/WebKit/LayoutTests/inspector/reveal-objects.html +++ b/third_party/WebKit/LayoutTests/inspector/reveal-objects.html
@@ -99,7 +99,7 @@ { InspectorTest.addSniffer(Elements.ElementsPanel.prototype, "revealAndSelectNode", nodeRevealed, true); InspectorTest.addSniffer(Sources.SourcesPanel.prototype, "showUILocation", uiLocationRevealed, true); - InspectorTest.addSniffer(Resources.ResourcesPanel.prototype, "showResource", resourceRevealed, true); + InspectorTest.addSniffer(Resources.ApplicationPanelSidebar.prototype, "showResource", resourceRevealed, true); InspectorTest.addSniffer(Network.NetworkPanel.prototype, "revealAndHighlightRequest", revealed, true); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/source-frame.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/source-frame.html index 2b0d545..7767684 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/source-frame.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/source-frame.html
@@ -60,7 +60,7 @@ function visit(resource) { if (resource.url.indexOf("debugger-test.js") !== -1) { - UI.panels.resources.showResource(resource, 1); + UI.panels.resources._sidebar.showResource(resource, 1); return true; } }
diff --git a/third_party/WebKit/LayoutTests/inspector/storage-panel-dom-storage-update.html b/third_party/WebKit/LayoutTests/inspector/storage-panel-dom-storage-update.html index d92f55b..88661bc 100644 --- a/third_party/WebKit/LayoutTests/inspector/storage-panel-dom-storage-update.html +++ b/third_party/WebKit/LayoutTests/inspector/storage-panel-dom-storage-update.html
@@ -66,7 +66,7 @@ InspectorTest.assertTrue(!!storage, "Local storage not found."); - UI.panels.resources._showDOMStorage(storage); + UI.panels.resources.showDOMStorage(storage); view = UI.panels.resources._domStorageView; InspectorTest.addSniffer(view, "_showDOMStorageItems", viewUpdated); },
diff --git a/third_party/WebKit/LayoutTests/inspector/storage-panel-dom-storage.html b/third_party/WebKit/LayoutTests/inspector/storage-panel-dom-storage.html index 3500e71..503eb707 100644 --- a/third_party/WebKit/LayoutTests/inspector/storage-panel-dom-storage.html +++ b/third_party/WebKit/LayoutTests/inspector/storage-panel-dom-storage.html
@@ -46,7 +46,7 @@ InspectorTest.completeTest(); return; } - UI.panels.resources._showDOMStorage(storage); + UI.panels.resources.showDOMStorage(storage); InspectorTest.addResult("Did show: " + name(storage)); InspectorTest.deprecatedRunAfterPendingDispatches(function() { InspectorTest.addResult(name(storage) + " content: ");
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/paged-with-overflowing-block-rl-expected.png index f60842a..be9624a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/paged-with-overflowing-block-rl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png new file mode 100644 index 0000000..be9624a --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/paged-with-overflowing-block-rl-expected.png index e30876e..a0553a3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/paged-with-overflowing-block-rl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png new file mode 100644 index 0000000..a0553a3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/paged-with-overflowing-block-rl-expected.png index 53fd21f0..857d8c6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/paged-with-overflowing-block-rl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png new file mode 100644 index 0000000..857d8c6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/paged-with-overflowing-block-rl-expected.png index ccd6acf6..1381b793 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/paged-with-overflowing-block-rl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png new file mode 100644 index 0000000..1381b793 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html index acfd67b..8e3a8232 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html
@@ -6,105 +6,149 @@ <html> <head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> +<script src="../resources/audit.js"></script> </head> <body> <script> +let audit = Audit.createTaskRunner(); -window.onload = init; +let sampleRate = 44100.0; +let numberOfNotes = 60; // play over a 5 octave range +let noteDuration = 0.025; +let noteSpacing = + noteDuration + 0.005; // leave 5ms of silence between each "note" +let lengthInSeconds = numberOfNotes * noteSpacing; -var sampleRate = 44100.0; -var numberOfNotes = 60; // play over a 5 octave range -var noteDuration = 0.025; -var noteSpacing = noteDuration + 0.005; // leave 5ms of silence between each "note" -var lengthInSeconds = numberOfNotes * noteSpacing; - -var context = 0; -var buffer = 0; +let context = 0; +let expectedAudio; function createTestBuffer(frequency, sampleRate) { - // Create a buffer containing two periods at this frequency. - // The 1st half is a pure sine wave period scaled by a linear ramp from 0 -> 1. - // The 2nd half of the buffer corresponds exactly to one pure sine wave period. - var onePeriodDuration = 1 / frequency; - var sampleFrameLength = 2 * onePeriodDuration * sampleRate; + // Create a buffer containing two periods at this frequency. + // The 1st half is a pure sine wave period scaled by a linear ramp from 0 -> + // 1. The 2nd half of the buffer corresponds exactly to one pure sine wave + // period. + let onePeriodDuration = 1 / frequency; + let sampleFrameLength = 2 * onePeriodDuration * sampleRate; - var audioBuffer = context.createBuffer(1, sampleFrameLength, sampleRate); + let audioBuffer = context.createBuffer(1, sampleFrameLength, sampleRate); - var n = audioBuffer.length; - var channelData = audioBuffer.getChannelData(0); + let n = audioBuffer.length; + let channelData = audioBuffer.getChannelData(0); - for (var i = 0; i < n; ++i) { - var sample = Math.sin(frequency * 2.0*Math.PI * i / sampleRate); + for (let i = 0; i < n; ++i) { + let sample = Math.sin(frequency * 2.0 * Math.PI * i / sampleRate); - // Linear ramp from 0 -> 1 for the first period. - // Stay at 1 for the 2nd period. - var scale = i < n / 2 ? i / (n / 2) : 1; - sample *= scale; + // Linear ramp from 0 -> 1 for the first period. + // Stay at 1 for the 2nd period. + let scale = i < n / 2 ? i / (n / 2) : 1; + sample *= scale; - channelData[i] = sample; - } + channelData[i] = sample; + } - return audioBuffer; + return audioBuffer; } -function playNote(time, duration, playbackRate) { - var source = context.createBufferSource(); - source.buffer = buffer; - source.playbackRate.value = playbackRate; +function playNote(buffer, time, duration, playbackRate) { + let source = context.createBufferSource(); + source.buffer = buffer; + source.playbackRate.value = playbackRate; - var gainNode = context.createGain(); - source.connect(gainNode); - gainNode.connect(context.destination); + let gainNode = context.createGain(); + source.connect(gainNode); + gainNode.connect(context.destination); - // Loop the 2nd half of the buffer. - // We should be able to hear any problems as glitches if the looping incorrectly indexes to - // anywhere outside of the desired loop-points, since only the 2nd half is a perfect sine-wave cycle, - // while the 1st half of the buffer contains a linear ramp of a sine-wave cycle. - source.loop = true; - source.loopStart = 0.5 * buffer.duration; - source.loopEnd = buffer.duration; + // Loop the 2nd half of the buffer. + // We should be able to hear any problems as glitches if the looping + // incorrectly indexes to anywhere outside of the desired loop-points, since + // only the 2nd half is a perfect sine-wave cycle, while the 1st half of the + // buffer contains a linear ramp of a sine-wave cycle. + source.loop = true; + source.loopStart = 0.5 * buffer.duration; + source.loopEnd = buffer.duration; - // Play for the given duration. - source.start(time); - source.stop(time + duration); + // Play for the given duration. + source.start(time); + source.stop(time + duration); - // Apply a quick linear fade-out to avoid a click at the end of the note. - gainNode.gain.value = 1; - gainNode.gain.setValueAtTime(1, time + duration - 0.005); - gainNode.gain.linearRampToValueAtTime(0, time + duration); + // Apply a quick linear fade-out to avoid a click at the end of the note. + gainNode.gain.value = 1; + gainNode.gain.setValueAtTime(1, time + duration - 0.005); + gainNode.gain.linearRampToValueAtTime(0, time + duration); } -function init() { - if (!window.testRunner) - return; +audit.define( + {label: 'initialize', description: 'Set up context and expected results'}, + (task, should) => { + // Create offline audio context. + should( + () => {context = new OfflineAudioContext( + 2, sampleRate * lengthInSeconds, sampleRate)}, + 'Creating context for testing') + .notThrow(); - // Create offline audio context. - context = new OfflineAudioContext(2, sampleRate * lengthInSeconds, sampleRate); + should( + Audit.loadFileFromUrl('audiobuffersource-loop-points-expected.wav') + .then(arrayBuffer => { + context.decodeAudioData(arrayBuffer).then(audioBuffer => { + expectedAudio = audioBuffer; + }); + }), + 'Fetching expected audio') + .beResolved() + .then(() => task.done()); + }); - // Create the test buffer. - // We'll loop this with the loop-points set for the 2nd half of this buffer. - buffer = createTestBuffer(440.0, sampleRate); +audit.define( + { + label: 'test', + description: 'Test loop points and compare with expected results' + }, + (task, should) => { + // Create the test buffer. + // We'll loop this with the loop-points set for the 2nd half of this + // buffer. + let buffer = createTestBuffer(440.0, sampleRate); - // Play all the notes as a chromatic scale. - for (var i = 0; i < numberOfNotes; ++i) { - var time = i * noteSpacing; - var semitone = i - numberOfNotes/2; // start three octaves down + // Play all the notes as a chromatic scale. + for (let i = 0; i < numberOfNotes; ++i) { + let time = i * noteSpacing; + // start three octaves down + let semitone = i - numberOfNotes / 2; // Convert from semitone to rate. - var playbackRate = Math.pow(2, semitone / 12); + let playbackRate = Math.pow(2, semitone / 12); - playNote(time, noteDuration, playbackRate); - } + playNote(buffer, time, noteDuration, playbackRate); + } - context.oncomplete = finishAudioTest; - context.startRendering(); + context.startRendering() + .then(renderedAudio => { + // Compute a threshold based on the maximum error, |maxUlp|, in ULP. + // This is experimentally determined. Assuming that the reference + // file is a 16-bit wav file, the max values in the wave file + // are +/- 32768. + let maxUlp = 0.9999; + let threshold = maxUlp / 32768; - testRunner.waitUntilDone(); -} + for (let k = 0; k < renderedAudio.numberOfChannels; ++k) { + should( + renderedAudio.getChannelData(k), + 'Rendered audio for channel ' + k) + .beCloseToArray( + expectedAudio.getChannelData(k), + {absoluteThreshold: threshold}); + } + }) + .then(() => task.done()); + }); + +audit.run(); </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-multi-channels.html b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-multi-channels.html index 8fed30e..4139d36 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-multi-channels.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-multi-channels.html
@@ -6,38 +6,72 @@ <html> <head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> -<script type="text/javascript" src="../resources/mix-testing.js"></script> +<script src="../resources/audit.js"></script> +<script src="../resources/mix-testing.js"></script> </head> <body> <script> +let audit = Audit.createTaskRunner(); +let context; +let expectedAudio; + +audit.define('initialize', (task, should) => { + // Create offline audio context + let sampleRate = 44100.0; + should(() => { + context = + new OfflineAudioContext(6, sampleRate * toneLengthSeconds, sampleRate); + }, 'Creating context for testing').notThrow(); + should( + Audit.loadFileFromUrl('audiobuffersource-multi-channels-expected.wav') + .then(arrayBuffer => { + context.decodeAudioData(arrayBuffer).then(audioBuffer => { + expectedAudio = audioBuffer; + }); + }), + 'Fetching expected audio') + .beResolved() + .then(() => task.done()); -function runTest() { - if (!window.testRunner) - return; +}); - testRunner.waitUntilDone(); +audit.define( + {label: 'test', description: 'AudioBufferSource with 5.1 buffer'}, + (task, should) => { + let toneBuffer = createToneBuffer(context, 440, toneLengthSeconds, 6); - window.jsTestAsync = true; + let source = context.createBufferSource(); + source.buffer = toneBuffer; - // Create offline audio context - var sampleRate = 44100.0; - var context = new OfflineAudioContext(6, sampleRate * toneLengthSeconds, sampleRate); - var toneBuffer = createToneBuffer(context, 440, toneLengthSeconds, 6); + source.connect(context.destination); + source.start(0); - var source = context.createBufferSource(); - source.buffer = toneBuffer; + context.startRendering() + .then(renderedAudio => { + // Compute a threshold based on the maximum error, |maxUlp|, in ULP. + // This is experimentally determined. Assuming that the reference + // file is a 16-bit wav file, the max values in the wave file + // are +/- 32768. + let maxUlp = 1; + let threshold = maxUlp / 32768; - source.connect(context.destination); - source.start(0); + for (let k = 0; k < renderedAudio.numberOfChannels; ++k) { + should( + renderedAudio.getChannelData(k), + 'Rendered audio for channel ' + k) + .beCloseToArray( + expectedAudio.getChannelData(k), + {absoluteThreshold: threshold}); + } + }) + .then(() => task.done()); + }); - context.oncomplete = finishAudioTest; - context.startRendering(); -} - -runTest(); +audit.run(); </script> </body>
diff --git a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp index ebe6007f..66172b83 100644 --- a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp
@@ -57,6 +57,10 @@ if (layer.stackingNode()->isStacked()) return m_compositingStackingContext; + // TODO(wangxianzhu, chrishtr): This is incorrect if m_compositingAncestor + // is inline and there is any non-layer floating object between layer and + // m_compositingAncestor. Should use the logic in PaintLayer:: + // containingLayer(). if (layer.layoutObject().isFloatingWithNonContainingBlockParent()) return layer.enclosingLayerWithCompositedLayerMapping(ExcludeSelf);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp index abd609c8f6..4bf93ca 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -870,8 +870,10 @@ *skippedAncestor = false; LayoutObject& layoutObject = this->layoutObject(); - if (layoutObject.isColumnSpanAll() || - layoutObject.isFloatingWithNonContainingBlockParent()) { + // Column span need to find the containing layer through its containing block. + // TODO(wangxianzhu): This can be combined with the loop handing possible + // floating objects. + if (layoutObject.isColumnSpanAll()) { Optional<LayoutObject::AncestorSkipInfo> skipInfo; if (skippedAncestor) skipInfo.emplace(&ancestor->layoutObject()); @@ -899,7 +901,28 @@ return curr; } - return parent(); + // If the parent layer is not a block, there might be floating objects + // between this layer (included) and parent layer which need to escape the + // inline parent to find the actual containing layer through the containing + // block chain. + if (!parent() || parent()->layoutObject().isLayoutBlock()) + return parent(); + + // This is a universal approach to find containing layer, but is slower than + // the earlier code. + Optional<LayoutObject::AncestorSkipInfo> skipInfo; + if (skippedAncestor) + skipInfo.emplace(&ancestor->layoutObject()); + auto* object = &layoutObject; + while (auto* container = + object->container(skippedAncestor ? &*skipInfo : nullptr)) { + if (skippedAncestor && skipInfo->ancestorSkipped()) + *skippedAncestor = true; + if (container->hasLayer()) + return toLayoutBoxModelObject(container)->layer(); + object = container; + } + return nullptr; } PaintLayer* PaintLayer::enclosingTransformedAncestor() const {
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp index aa63b15..8165be0 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -76,10 +76,7 @@ const EffectPaintPropertyNode* effect = layoutObject.paintProperties()->effect(); - const TransformPaintPropertyNode* transform = - layoutObject.paintProperties()->transform(); - if ((effect && effect->requiresCompositingForAnimation()) || - (transform && transform->requiresCompositingForAnimation())) { + if (effect && effect->requiresCompositingForAnimation()) { return false; } }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.h b/third_party/WebKit/Source/core/paint/PaintLayerPainter.h index 4a245c4..258912a 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.h +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.h
@@ -157,7 +157,7 @@ FRIEND_TEST_ALL_PREFIXES(PaintLayerPainterTest, DoPaintWithEffectAnimationZeroOpacity); FRIEND_TEST_ALL_PREFIXES(PaintLayerPainterTest, - DoPaintWithTransformAnimationZeroOpacity); + DoNotPaintWithTransformAnimationZeroOpacity); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp index 69ea1ba..23abda1 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
@@ -1083,7 +1083,7 @@ PaintLayerPainter(*targetLayer).paintedOutputInvisible(paintingInfo)); } -TEST_P(PaintLayerPainterTest, DoPaintWithTransformAnimationZeroOpacity) { +TEST_P(PaintLayerPainterTest, DoNotPaintWithTransformAnimationZeroOpacity) { setBodyInnerHTML( "<style> " "div#target { " @@ -1101,8 +1101,13 @@ toLayoutBox(getLayoutObjectByElementId("target"))->layer(); PaintLayerPaintingInfo paintingInfo(nullptr, LayoutRect(), GlobalPaintNormalPhase, LayoutSize()); - EXPECT_FALSE( - PaintLayerPainter(*targetLayer).paintedOutputInvisible(paintingInfo)); + if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { + EXPECT_TRUE( + PaintLayerPainter(*targetLayer).paintedOutputInvisible(paintingInfo)); + } else { + EXPECT_FALSE( + PaintLayerPainter(*targetLayer).paintedOutputInvisible(paintingInfo)); + } } } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerTest.cpp index d5b41edc..2f55f10b 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerTest.cpp
@@ -649,6 +649,94 @@ document().layoutView()->layer())); } +TEST_P(PaintLayerTest, FloatLayerUnderFloatUnderInlineLayer) { + setBodyInnerHTML( + "<style>body {margin: 0}</style>" + "<span id='span' style='position: relative; top: 100px; left: 100px'>" + " <div style='float: left; margin: 33px'>" + " <div id='floating'" + " style='float: left; position: relative; top: 50px; left: 50px'>" + " </div>" + " </div>" + "</span>"); + + PaintLayer* floating = + toLayoutBoxModelObject(getLayoutObjectByElementId("floating"))->layer(); + PaintLayer* span = + toLayoutBoxModelObject(getLayoutObjectByElementId("span"))->layer(); + + EXPECT_EQ(span, floating->parent()); + EXPECT_EQ(span->parent(), floating->containingLayer()); + + EXPECT_EQ(LayoutPoint(83, 83), floating->location()); + EXPECT_EQ(LayoutPoint(100, 100), span->location()); + EXPECT_EQ(LayoutPoint(-17, -17), floating->visualOffsetFromAncestor(span)); + EXPECT_EQ(LayoutPoint(83, 83), floating->visualOffsetFromAncestor( + document().layoutView()->layer())); +} + +TEST_P(PaintLayerTest, FloatLayerUnderFloatLayerUnderInlineLayer) { + setBodyInnerHTML( + "<style>body {margin: 0}</style>" + "<span id='span' style='position: relative; top: 100px; left: 100px'>" + " <div id='floatingParent'" + " style='float: left; position: relative; margin: 33px'>" + " <div id='floating'" + " style='float: left; position: relative; top: 50px; left: 50px'>" + " </div>" + " </div>" + "</span>"); + + PaintLayer* floating = + toLayoutBoxModelObject(getLayoutObjectByElementId("floating"))->layer(); + PaintLayer* floatingParent = + toLayoutBoxModelObject(getLayoutObjectByElementId("floatingParent")) + ->layer(); + PaintLayer* span = + toLayoutBoxModelObject(getLayoutObjectByElementId("span"))->layer(); + + EXPECT_EQ(floatingParent, floating->parent()); + EXPECT_EQ(floatingParent, floating->containingLayer()); + EXPECT_EQ(span, floatingParent->parent()); + EXPECT_EQ(span->parent(), floatingParent->containingLayer()); + + EXPECT_EQ(LayoutPoint(50, 50), floating->location()); + EXPECT_EQ(LayoutPoint(33, 33), floatingParent->location()); + EXPECT_EQ(LayoutPoint(100, 100), span->location()); + EXPECT_EQ(LayoutPoint(-17, -17), floating->visualOffsetFromAncestor(span)); + EXPECT_EQ(LayoutPoint(-67, -67), + floatingParent->visualOffsetFromAncestor(span)); + EXPECT_EQ(LayoutPoint(83, 83), floating->visualOffsetFromAncestor( + document().layoutView()->layer())); +} + +TEST_P(PaintLayerTest, LayerUnderFloatUnderInlineLayer) { + setBodyInnerHTML( + "<style>body {margin: 0}</style>" + "<span id='span' style='position: relative; top: 100px; left: 100px'>" + " <div style='float: left; margin: 33px'>" + " <div>" + " <div id='child' style='position: relative; top: 50px; left: 50px'>" + " </div>" + " </div>" + " </div>" + "</span>"); + + PaintLayer* child = + toLayoutBoxModelObject(getLayoutObjectByElementId("child"))->layer(); + PaintLayer* span = + toLayoutBoxModelObject(getLayoutObjectByElementId("span"))->layer(); + + EXPECT_EQ(span, child->parent()); + EXPECT_EQ(span->parent(), child->containingLayer()); + + EXPECT_EQ(LayoutPoint(83, 83), child->location()); + EXPECT_EQ(LayoutPoint(100, 100), span->location()); + EXPECT_EQ(LayoutPoint(-17, -17), child->visualOffsetFromAncestor(span)); + EXPECT_EQ(LayoutPoint(83, 83), + child->visualOffsetFromAncestor(document().layoutView()->layer())); +} + TEST_P(PaintLayerTest, CompositingContainerFloatingIframe) { enableCompositing(); setBodyInnerHTML(
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn index 849a8bec..c0de0209 100644 --- a/third_party/WebKit/Source/devtools/BUILD.gn +++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -406,6 +406,7 @@ "front_end/quick_open/module.json", "front_end/resources/ApplicationCacheModel.js", "front_end/resources/ApplicationCacheItemsView.js", + "front_end/resources/ApplicationPanelSidebar.js", "front_end/resources/appManifestView.css", "front_end/resources/AppManifestView.js", "front_end/resources/clearStorageView.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/audits/AuditExtensionCategory.js b/third_party/WebKit/Source/devtools/front_end/audits/AuditExtensionCategory.js index e6e54d2..e3c8e54 100644 --- a/third_party/WebKit/Source/devtools/front_end/audits/AuditExtensionCategory.js +++ b/third_party/WebKit/Source/devtools/front_end/audits/AuditExtensionCategory.js
@@ -209,22 +209,27 @@ */ node: function(expression, evaluateOptions) { var parentElement = createElement('div'); - this.evaluate(expression, evaluateOptions, onEvaluate); + this.evaluate(expression, evaluateOptions, async remoteObject => { + await append(remoteObject); + remoteObject.release(); + }); + return parentElement; /** * @param {!SDK.RemoteObject} remoteObject */ - function onEvaluate(remoteObject) { - Common.Renderer.renderPromise(remoteObject).then(appendRenderer).then(remoteObject.release.bind(remoteObject)); - - /** - * @param {!Element} element - */ - function appendRenderer(element) { - parentElement.appendChild(element); - } + async function append(remoteObject) { + if (!remoteObject.isNode()) + return; + var domModel = SDK.DOMModel.fromTarget(remoteObject.runtimeModel().target()); + if (!domModel) + return; + var node = await domModel.pushObjectAsNodeToFrontend(remoteObject); + if (!node) + return; + var element = await Common.Renderer.renderPromise(/** @type {!SDK.DOMNode} */ (node)); + parentElement.appendChild(element); } - return parentElement; } };
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js index 9d89be4e..233338b4 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
@@ -483,10 +483,12 @@ case 'promise': case 'proxy': case 'set': + case 'weakmap': + case 'weakset': element = this._formatParameterAsObject(output, includePreview); break; case 'node': - element = this._formatParameterAsNode(output); + element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false); break; case 'string': element = this._formatParameterAsString(output); @@ -598,29 +600,27 @@ } /** - * @param {!SDK.RemoteObject} object + * @param {!SDK.RemoteObject} remoteObject * @return {!Element} */ - _formatParameterAsNode(object) { + _formatParameterAsNode(remoteObject) { var result = createElement('span'); - Common.Renderer.renderPromise(object).then(appendRenderer.bind(this), failedToRender.bind(this)); + + var domModel = SDK.DOMModel.fromTarget(remoteObject.runtimeModel().target()); + if (!domModel) + return result; + domModel.pushObjectAsNodeToFrontend(remoteObject).then(node => { + if (!node) { + result.appendChild(this._formatParameterAsObject(remoteObject, false)); + return; + } + Common.Renderer.renderPromise(node).then(rendererElement => { + result.appendChild(rendererElement); + this._formattedParameterAsNodeForTest(); + }); + }); + return result; - - /** - * @param {!Element} rendererElement - * @this {Console.ConsoleViewMessage} - */ - function appendRenderer(rendererElement) { - result.appendChild(rendererElement); - this._formattedParameterAsNodeForTest(); - } - - /** - * @this {Console.ConsoleViewMessage} - */ - function failedToRender() { - result.appendChild(this._formatParameterAsObject(object, false)); - } } _formattedParameterAsNodeForTest() {
diff --git a/third_party/WebKit/Source/devtools/front_end/cookie_table/CookiesTable.js b/third_party/WebKit/Source/devtools/front_end/cookie_table/CookiesTable.js index 4bb51710..adf3439 100644 --- a/third_party/WebKit/Source/devtools/front_end/cookie_table/CookiesTable.js +++ b/third_party/WebKit/Source/devtools/front_end/cookie_table/CookiesTable.js
@@ -161,10 +161,13 @@ /** * @param {{current: ?SDK.Cookie, neighbor: ?SDK.Cookie}} selectionCookies - * @param {!Array<!SDK.Cookie>} cookies + * @param {?Array<!SDK.Cookie>} cookies * @return {?SDK.Cookie} */ _findSelectedCookie(selectionCookies, cookies) { + if (!cookies) + return null; + var current = selectionCookies.current; var foundCurrent = cookies.find(cookie => this._isSameCookie(cookie, current)); if (foundCurrent)
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js b/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js index fb51c77..619cf46 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js
@@ -41,6 +41,10 @@ if (!isEnterKey(event)) return; + if (this._prompt.acceptAutoComplete()) { + event.consume(true); + return; + } var node = UI.context.flavor(SDK.DOMNode); if (!node) return;
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js index b095335..c5acf146 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -1017,7 +1017,7 @@ } else if (node instanceof SDK.RemoteObject) { var domModel = SDK.DOMModel.fromTarget(/** @type {!SDK.RemoteObject} */ (node).runtimeModel().target()); if (domModel) - domModel.pushObjectAsNodeToFrontend(node, onNodeResolved); + domModel.pushObjectAsNodeToFrontend(node).then(onNodeResolved); else reject(new Error('Could not resolve a node to reveal.')); } else {
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js index 3fe0a40..7a3040d 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
@@ -1583,19 +1583,13 @@ * @param {function(!Error)} reject */ function renderPromise(resolve, reject) { - if (object instanceof SDK.DOMNode) { + if (object instanceof SDK.DOMNode) onNodeResolved(/** @type {!SDK.DOMNode} */ (object)); - } else if (object instanceof SDK.DeferredDOMNode) { + else if (object instanceof SDK.DeferredDOMNode) (/** @type {!SDK.DeferredDOMNode} */ (object)).resolve(onNodeResolved); - } else if (object instanceof SDK.RemoteObject) { - var domModel = SDK.DOMModel.fromTarget((/** @type {!SDK.RemoteObject} */ (object)).runtimeModel().target()); - if (domModel) - domModel.pushObjectAsNodeToFrontend(object, onNodeResolved); - else - reject(new Error('No dom model for given JS object target found.')); - } else { + else reject(new Error('Can\'t reveal not a node.')); - } + /** * @param {?SDK.DOMNode} node
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/module.json b/third_party/WebKit/Source/devtools/front_end/elements/module.json index 4993b21..11b7c4d 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/module.json +++ b/third_party/WebKit/Source/devtools/front_end/elements/module.json
@@ -21,7 +21,7 @@ "type": "@Common.Renderer", "contextTypes": [ "SDK.DOMNode", - "SDK.RemoteObject" + "SDK.DeferredDOMNode" ], "className": "Elements.ElementsTreeOutline.Renderer" },
diff --git a/third_party/WebKit/Source/devtools/front_end/host/Platform.js b/third_party/WebKit/Source/devtools/front_end/host/Platform.js index 387d989..1317d42 100644 --- a/third_party/WebKit/Source/devtools/front_end/host/Platform.js +++ b/third_party/WebKit/Source/devtools/front_end/host/Platform.js
@@ -71,7 +71,7 @@ return Host._fontFamily; switch (Host.platform()) { case 'linux': - Host._fontFamily = 'Ubuntu, Arial, sans-serif'; + Host._fontFamily = 'Roboto, Ubuntu, Arial, sans-serif'; break; case 'mac': Host._fontFamily = '\'Lucida Grande\', sans-serif';
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js b/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js new file mode 100644 index 0000000..4836c57 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js
@@ -0,0 +1,1654 @@ +/* + * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2009 Joseph Pecoraro + * Copyright (C) 2013 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @implements {SDK.TargetManager.Observer} + * @unrestricted + */ +Resources.ApplicationPanelSidebar = class extends UI.VBox { + /** + * @param {!Resources.ResourcesPanel} panel + */ + constructor(panel) { + super(); + + this._panel = panel; + + this._sidebarTree = new UI.TreeOutlineInShadow(); + this._sidebarTree.element.classList.add('resources-sidebar'); + this._sidebarTree.registerRequiredCSS('resources/resourcesSidebar.css'); + this._sidebarTree.element.classList.add('filter-all'); + this.contentElement.appendChild(this._sidebarTree.element); + + this._applicationTreeElement = this._addSidebarSection(Common.UIString('Application')); + this._manifestTreeElement = new Resources.AppManifestTreeElement(panel); + this._applicationTreeElement.appendChild(this._manifestTreeElement); + this.serviceWorkersTreeElement = new Resources.ServiceWorkersTreeElement(panel); + this._applicationTreeElement.appendChild(this.serviceWorkersTreeElement); + var clearStorageTreeElement = new Resources.ClearStorageTreeElement(panel); + this._applicationTreeElement.appendChild(clearStorageTreeElement); + + var storageTreeElement = this._addSidebarSection(Common.UIString('Storage')); + this.localStorageListTreeElement = + new Resources.StorageCategoryTreeElement(panel, Common.UIString('Local Storage'), 'LocalStorage'); + var localStorageIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); + this.localStorageListTreeElement.setLeadingIcons([localStorageIcon]); + + storageTreeElement.appendChild(this.localStorageListTreeElement); + this.sessionStorageListTreeElement = + new Resources.StorageCategoryTreeElement(panel, Common.UIString('Session Storage'), 'SessionStorage'); + var sessionStorageIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); + this.sessionStorageListTreeElement.setLeadingIcons([sessionStorageIcon]); + + storageTreeElement.appendChild(this.sessionStorageListTreeElement); + this.indexedDBListTreeElement = new Resources.IndexedDBTreeElement(panel); + storageTreeElement.appendChild(this.indexedDBListTreeElement); + this.databasesListTreeElement = + new Resources.StorageCategoryTreeElement(panel, Common.UIString('Web SQL'), 'Databases'); + var databaseIcon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); + this.databasesListTreeElement.setLeadingIcons([databaseIcon]); + + storageTreeElement.appendChild(this.databasesListTreeElement); + this.cookieListTreeElement = new Resources.StorageCategoryTreeElement(panel, Common.UIString('Cookies'), 'Cookies'); + var cookieIcon = UI.Icon.create('mediumicon-cookie', 'resource-tree-item'); + this.cookieListTreeElement.setLeadingIcons([cookieIcon]); + storageTreeElement.appendChild(this.cookieListTreeElement); + + var cacheTreeElement = this._addSidebarSection(Common.UIString('Cache')); + this.cacheStorageListTreeElement = new Resources.ServiceWorkerCacheTreeElement(panel); + cacheTreeElement.appendChild(this.cacheStorageListTreeElement); + this.applicationCacheListTreeElement = + new Resources.StorageCategoryTreeElement(panel, Common.UIString('Application Cache'), 'ApplicationCache'); + var applicationCacheIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); + this.applicationCacheListTreeElement.setLeadingIcons([applicationCacheIcon]); + + cacheTreeElement.appendChild(this.applicationCacheListTreeElement); + + this._resourcesSection = new Resources.ResourcesSection(panel, this._addSidebarSection(Common.UIString('Frames'))); + + /** @type {!Map.<!Resources.Database, !Object.<string, !Resources.DatabaseTableView>>} */ + this._databaseTableViews = new Map(); + /** @type {!Map.<!Resources.Database, !Resources.DatabaseQueryView>} */ + this._databaseQueryViews = new Map(); + /** @type {!Map.<!Resources.Database, !Resources.DatabaseTreeElement>} */ + this._databaseTreeElements = new Map(); + /** @type {!Map.<!Resources.DOMStorage, !Resources.DOMStorageTreeElement>} */ + this._domStorageTreeElements = new Map(); + /** @type {!Object.<string, boolean>} */ + this._domains = {}; + + this._sidebarTree.contentElement.addEventListener('mousemove', this._onmousemove.bind(this), false); + this._sidebarTree.contentElement.addEventListener('mouseleave', this._onmouseleave.bind(this), false); + + SDK.targetManager.observeTargets(this); + SDK.targetManager.addModelListener( + SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.FrameNavigated, this._frameNavigated, this); + } + + /** + * @param {string} title + * @return {!UI.TreeElement} + */ + _addSidebarSection(title) { + var treeElement = new UI.TreeElement(title, true); + treeElement.listItemElement.classList.add('storage-group-list-item'); + treeElement.setCollapsible(false); + treeElement.selectable = false; + this._sidebarTree.appendChild(treeElement); + return treeElement; + } + + /** + * @override + * @param {!SDK.Target} target + */ + targetAdded(target) { + if (this._target) + return; + this._target = target; + this._databaseModel = Resources.DatabaseModel.fromTarget(target); + + this._databaseModel.on(Resources.DatabaseModel.DatabaseAddedEvent, this._databaseAdded, this); + this._databaseModel.on(Resources.DatabaseModel.DatabasesRemovedEvent, this._resetWebSQL, this); + + var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); + if (!resourceTreeModel) + return; + + if (resourceTreeModel.cachedResourcesLoaded()) + this._initialize(); + + resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._initialize, this); + resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this); + } + + /** + * @override + * @param {!SDK.Target} target + */ + targetRemoved(target) { + if (target !== this._target) + return; + delete this._target; + + var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); + if (resourceTreeModel) { + resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._initialize, this); + resourceTreeModel.removeEventListener( + SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this); + } + this._databaseModel.off(Resources.DatabaseModel.DatabaseAddedEvent, this._databaseAdded, this); + this._databaseModel.off(Resources.DatabaseModel.DatabasesRemovedEvent, this._resetWebSQL, this); + + this._resetWithFrames(); + } + + /** + * @override + */ + focus() { + this._sidebarTree.focus(); + } + + _initialize() { + for (var frame of SDK.ResourceTreeModel.frames()) + this._addCookieDocument(frame); + this._databaseModel.enable(); + + var indexedDBModel = Resources.IndexedDBModel.fromTarget(this._target); + if (indexedDBModel) + indexedDBModel.enable(); + + var cacheStorageModel = SDK.ServiceWorkerCacheModel.fromTarget(this._target); + if (cacheStorageModel) + cacheStorageModel.enable(); + var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(this._target); + if (resourceTreeModel) + this._populateApplicationCacheTree(resourceTreeModel); + var domStorageModel = Resources.DOMStorageModel.fromTarget(this._target); + if (domStorageModel) + this._populateDOMStorageTree(domStorageModel); + this.indexedDBListTreeElement._initialize(); + var serviceWorkerCacheModel = SDK.ServiceWorkerCacheModel.fromTarget(this._target); + this.cacheStorageListTreeElement._initialize(serviceWorkerCacheModel); + this._initDefaultSelection(); + } + + _initDefaultSelection() { + var itemURL = this._panel.lastSelectedItemURL(); + if (itemURL) { + var rootElement = this._sidebarTree.rootElement(); + for (var treeElement = rootElement.firstChild(); treeElement; + treeElement = treeElement.traverseNextTreeElement(false, rootElement, true)) { + if (treeElement.itemURL === itemURL) { + treeElement.revealAndSelect(true); + return; + } + } + } + this._manifestTreeElement.select(); + } + + _resetWithFrames() { + this._resourcesSection.reset(); + this._reset(); + } + + _resetWebSQL() { + var queryViews = this._databaseQueryViews.valuesArray(); + for (var i = 0; i < queryViews.length; ++i) { + queryViews[i].removeEventListener( + Resources.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this); + } + this._databaseTableViews.clear(); + this._databaseQueryViews.clear(); + this._databaseTreeElements.clear(); + this.databasesListTreeElement.removeChildren(); + this.databasesListTreeElement.setExpandable(false); + } + + _resetDOMStorage() { + this._domStorageTreeElements.clear(); + this.localStorageListTreeElement.removeChildren(); + this.sessionStorageListTreeElement.removeChildren(); + } + + _resetCookies() { + this.cookieListTreeElement.removeChildren(); + } + + _resetCacheStorage() { + this.cacheStorageListTreeElement.removeChildren(); + this.cacheStorageListTreeElement.setExpandable(false); + } + + _resetAppCache() { + for (var frameId of Object.keys(this._applicationCacheFrameElements)) + this._applicationCacheFrameManifestRemoved({data: frameId}); + this.applicationCacheListTreeElement.setExpandable(false); + } + + _reset() { + this._domains = {}; + this._resetWebSQL(); + this._resetDOMStorage(); + this._resetCookies(); + this._resetCacheStorage(); + // No need to this._resetAppCache. + + this._panel.resetView(); + + if (this._sidebarTree.selectedTreeElement) + this._sidebarTree.selectedTreeElement.deselect(); + } + + _frameNavigated(event) { + var frame = event.data; + + if (!frame.parentFrame) + this._reset(); + + var applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frame.id]; + if (applicationCacheFrameTreeElement) + applicationCacheFrameTreeElement.frameNavigated(frame); + this._addCookieDocument(frame); + } + + /** + * @param {!Resources.DatabaseModel.DatabaseAddedEvent} event + */ + _databaseAdded(event) { + var databaseTreeElement = new Resources.DatabaseTreeElement(this, event.database); + this._databaseTreeElements.set(event.database, databaseTreeElement); + this.databasesListTreeElement.appendChild(databaseTreeElement); + } + + /** + * @param {!SDK.ResourceTreeFrame} frame + */ + _addCookieDocument(frame) { + var parsedURL = frame.url.asParsedURL(); + if (!parsedURL || (parsedURL.scheme !== 'http' && parsedURL.scheme !== 'https' && parsedURL.scheme !== 'file')) + return; + + var domain = parsedURL.securityOrigin(); + if (!this._domains[domain]) { + this._domains[domain] = true; + var cookieDomainTreeElement = new Resources.CookieTreeElement(this._panel, frame, domain); + this.cookieListTreeElement.appendChild(cookieDomainTreeElement); + } + } + + /** + * @param {!Common.Event} event + */ + _domStorageAdded(event) { + var domStorage = /** @type {!Resources.DOMStorage} */ (event.data); + this._addDOMStorage(domStorage); + } + + /** + * @param {!Resources.DOMStorage} domStorage + */ + _addDOMStorage(domStorage) { + console.assert(!this._domStorageTreeElements.get(domStorage)); + + var domStorageTreeElement = new Resources.DOMStorageTreeElement(this._panel, domStorage); + this._domStorageTreeElements.set(domStorage, domStorageTreeElement); + if (domStorage.isLocalStorage) + this.localStorageListTreeElement.appendChild(domStorageTreeElement); + else + this.sessionStorageListTreeElement.appendChild(domStorageTreeElement); + } + + /** + * @param {!Common.Event} event + */ + _domStorageRemoved(event) { + var domStorage = /** @type {!Resources.DOMStorage} */ (event.data); + this._removeDOMStorage(domStorage); + } + + /** + * @param {!Resources.DOMStorage} domStorage + */ + _removeDOMStorage(domStorage) { + var treeElement = this._domStorageTreeElements.get(domStorage); + if (!treeElement) + return; + var wasSelected = treeElement.selected; + var parentListTreeElement = treeElement.parent; + parentListTreeElement.removeChild(treeElement); + if (wasSelected) + parentListTreeElement.select(); + this._domStorageTreeElements.remove(domStorage); + } + + /** + * @param {!Resources.Database} database + */ + selectDatabase(database) { + if (database) { + this._showDatabase(database); + this._databaseTreeElements.get(database).select(); + } + } + + /** + * @param {!SDK.Resource} resource + * @param {number=} line + * @param {number=} column + * @return {boolean} + */ + showResource(resource, line, column) { + var resourceTreeElement = Resources.FrameResourceTreeElement.forResource(resource); + if (resourceTreeElement) + resourceTreeElement.revealAndSelect(true); + + if (typeof line === 'number') { + var resourceSourceFrame = this._resourceSourceFrameViewForResource(resource); + if (resourceSourceFrame) + resourceSourceFrame.revealPosition(line, column, true); + } + return true; + } + + /** + * @param {!SDK.Resource} resource + * @return {?SourceFrame.ResourceSourceFrame} + */ + _resourceSourceFrameViewForResource(resource) { + var resourceView = Resources.FrameResourceTreeElement.resourceViewForResource(resource); + if (resourceView && resourceView instanceof SourceFrame.ResourceSourceFrame) + return /** @type {!SourceFrame.ResourceSourceFrame} */ (resourceView); + return null; + } + + /** + * @param {!Resources.Database} database + * @param {string=} tableName + */ + _showDatabase(database, tableName) { + if (!database) + return; + + var view; + if (tableName) { + var tableViews = this._databaseTableViews.get(database); + if (!tableViews) { + tableViews = /** @type {!Object.<string, !Resources.DatabaseTableView>} */ ({}); + this._databaseTableViews.set(database, tableViews); + } + view = tableViews[tableName]; + if (!view) { + view = new Resources.DatabaseTableView(database, tableName); + tableViews[tableName] = view; + } + } else { + view = this._databaseQueryViews.get(database); + if (!view) { + view = new Resources.DatabaseQueryView(database); + this._databaseQueryViews.set(database, view); + view.addEventListener(Resources.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this); + } + } + + this._innerShowView(view); + } + + _showApplicationCache(frameId) { + if (!this._applicationCacheViews[frameId]) { + this._applicationCacheViews[frameId] = + new Resources.ApplicationCacheItemsView(this._applicationCacheModel, frameId); + } + + this._innerShowView(this._applicationCacheViews[frameId]); + } + + /** + * @param {!UI.Widget} view + */ + showFileSystem(view) { + this._innerShowView(view); + } + + _innerShowView(view) { + this._panel.showView(view); + } + + _updateDatabaseTables(event) { + var database = event.data; + + if (!database) + return; + + var databasesTreeElement = this._databaseTreeElements.get(database); + if (!databasesTreeElement) + return; + + databasesTreeElement.invalidateChildren(); + var tableViews = this._databaseTableViews.get(database); + + if (!tableViews) + return; + + var tableNamesHash = {}; + var panel = this._panel; + function tableNamesCallback(tableNames) { + var tableNamesLength = tableNames.length; + for (var i = 0; i < tableNamesLength; ++i) + tableNamesHash[tableNames[i]] = true; + + for (var tableName in tableViews) { + if (!(tableName in tableNamesHash)) { + if (panel.visibleView === tableViews[tableName]) + panel.showView(null); + delete tableViews[tableName]; + } + } + } + database.getTableNames(tableNamesCallback); + } + + /** + * @param {!Resources.DOMStorageModel} domStorageModel + */ + _populateDOMStorageTree(domStorageModel) { + domStorageModel.enable(); + domStorageModel.storages().forEach(this._addDOMStorage.bind(this)); + domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); + domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this); + } + + /** + * @param {!SDK.ResourceTreeModel} resourceTreeModel + */ + _populateApplicationCacheTree(resourceTreeModel) { + this._applicationCacheModel = Resources.ApplicationCacheModel.fromTarget(this._target); + + this._applicationCacheViews = {}; + this._applicationCacheFrameElements = {}; + this._applicationCacheManifestElements = {}; + + this._applicationCacheModel.addEventListener( + Resources.ApplicationCacheModel.Events.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this); + this._applicationCacheModel.addEventListener( + Resources.ApplicationCacheModel.Events.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this); + this._applicationCacheModel.addEventListener( + Resources.ApplicationCacheModel.Events.FrameManifestsReset, this._resetAppCache, this); + + this._applicationCacheModel.addEventListener( + Resources.ApplicationCacheModel.Events.FrameManifestStatusUpdated, + this._applicationCacheFrameManifestStatusChanged, this); + this._applicationCacheModel.addEventListener( + Resources.ApplicationCacheModel.Events.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this); + } + + _applicationCacheFrameManifestAdded(event) { + var frameId = event.data; + var manifestURL = this._applicationCacheModel.frameManifestURL(frameId); + + var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]; + if (!manifestTreeElement) { + manifestTreeElement = new Resources.ApplicationCacheManifestTreeElement(this._panel, manifestURL); + this.applicationCacheListTreeElement.appendChild(manifestTreeElement); + this._applicationCacheManifestElements[manifestURL] = manifestTreeElement; + } + + var model = SDK.ResourceTreeModel.fromTarget(this._target); + var frameTreeElement = new Resources.ApplicationCacheFrameTreeElement(this, model.frameForId(frameId), manifestURL); + manifestTreeElement.appendChild(frameTreeElement); + manifestTreeElement.expand(); + this._applicationCacheFrameElements[frameId] = frameTreeElement; + } + + _applicationCacheFrameManifestRemoved(event) { + var frameId = event.data; + var frameTreeElement = this._applicationCacheFrameElements[frameId]; + if (!frameTreeElement) + return; + + var manifestURL = frameTreeElement.manifestURL; + delete this._applicationCacheFrameElements[frameId]; + delete this._applicationCacheViews[frameId]; + frameTreeElement.parent.removeChild(frameTreeElement); + + var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]; + if (manifestTreeElement.childCount()) + return; + + delete this._applicationCacheManifestElements[manifestURL]; + manifestTreeElement.parent.removeChild(manifestTreeElement); + } + + _applicationCacheFrameManifestStatusChanged(event) { + var frameId = event.data; + var status = this._applicationCacheModel.frameManifestStatus(frameId); + + if (this._applicationCacheViews[frameId]) + this._applicationCacheViews[frameId].updateStatus(status); + } + + _applicationCacheNetworkStateChanged(event) { + var isNowOnline = event.data; + + for (var manifestURL in this._applicationCacheViews) + this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline); + } + + showView(view) { + if (view) + this.showResource(view.resource); + } + + _onmousemove(event) { + var nodeUnderMouse = event.target; + if (!nodeUnderMouse) + return; + + var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName('li'); + if (!listNode) + return; + + var element = listNode.treeElement; + if (this._previousHoveredElement === element) + return; + + if (this._previousHoveredElement) { + this._previousHoveredElement.hovered = false; + delete this._previousHoveredElement; + } + + if (element instanceof Resources.FrameTreeElement) { + this._previousHoveredElement = element; + element.hovered = true; + } + } + + _onmouseleave(event) { + if (this._previousHoveredElement) { + this._previousHoveredElement.hovered = false; + delete this._previousHoveredElement; + } + } +}; + +/** + * @unrestricted + */ +Resources.BaseStorageTreeElement = class extends UI.TreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + * @param {string} title + * @param {boolean} expandable + */ + constructor(storagePanel, title, expandable) { + super(title, expandable); + this._storagePanel = storagePanel; + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + if (!selectedByUser) + return false; + var itemURL = this.itemURL; + if (itemURL) + this._storagePanel.setLastSelectedItemURL(itemURL); + return false; + } + + /** + * @protected + * @param {?UI.Widget} view + */ + showView(view) { + this._storagePanel.showView(view); + } +}; + +Resources.StorageCategoryTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + * @param {string} categoryName + * @param {string} settingsKey + */ + constructor(storagePanel, categoryName, settingsKey) { + super(storagePanel, categoryName, false); + this._expandedSetting = + Common.settings.createSetting('resources' + settingsKey + 'Expanded', settingsKey === 'Frames'); + this._categoryName = categoryName; + } + + + get itemURL() { + return 'category://' + this._categoryName; + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + this._storagePanel.showCategoryView(this._categoryName); + return false; + } + + /** + * @override + */ + onattach() { + super.onattach(); + if (this._expandedSetting.get()) + this.expand(); + } + + /** + * @override + */ + onexpand() { + this._expandedSetting.set(true); + } + + /** + * @override + */ + oncollapse() { + this._expandedSetting.set(false); + } +}; + +/** + * @unrestricted + */ +Resources.DatabaseTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ApplicationPanelSidebar} sidebar + * @param {!Resources.Database} database + */ + constructor(sidebar, database) { + super(sidebar._panel, database.name, true); + this._sidebar = sidebar; + this._database = database; + + var icon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + get itemURL() { + return 'database://' + encodeURI(this._database.name); + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + this._sidebar._showDatabase(this._database); + return false; + } + + /** + * @override + */ + onexpand() { + this._updateChildren(); + } + + _updateChildren() { + this.removeChildren(); + + /** + * @param {!Array.<string>} tableNames + * @this {Resources.DatabaseTreeElement} + */ + function tableNamesCallback(tableNames) { + var tableNamesLength = tableNames.length; + for (var i = 0; i < tableNamesLength; ++i) + this.appendChild(new Resources.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i])); + } + this._database.getTableNames(tableNamesCallback.bind(this)); + } +}; + +/** + * @unrestricted + */ +Resources.DatabaseTableTreeElement = class extends Resources.BaseStorageTreeElement { + constructor(sidebar, database, tableName) { + super(sidebar._panel, tableName, false); + this._sidebar = sidebar; + this._database = database; + this._tableName = tableName; + var icon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + get itemURL() { + return 'database://' + encodeURI(this._database.name) + '/' + encodeURI(this._tableName); + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + this._sidebar._showDatabase(this._database, this._tableName); + return false; + } +}; + +/** + * @unrestricted + */ +Resources.ServiceWorkerCacheTreeElement = class extends Resources.StorageCategoryTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + */ + constructor(storagePanel) { + super(storagePanel, Common.UIString('Cache Storage'), 'CacheStorage'); + var icon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); + this.setLeadingIcons([icon]); + /** @type {?SDK.ServiceWorkerCacheModel} */ + this._swCacheModel = null; + } + + /** + * @param {?SDK.ServiceWorkerCacheModel} model + */ + _initialize(model) { + /** @type {!Array.<!Resources.SWCacheTreeElement>} */ + this._swCacheTreeElements = []; + this._swCacheModel = model; + if (model) { + for (var cache of model.caches()) + this._addCache(model, cache); + } + SDK.targetManager.addModelListener( + SDK.ServiceWorkerCacheModel, SDK.ServiceWorkerCacheModel.Events.CacheAdded, this._cacheAdded, this); + SDK.targetManager.addModelListener( + SDK.ServiceWorkerCacheModel, SDK.ServiceWorkerCacheModel.Events.CacheRemoved, this._cacheRemoved, this); + } + + /** + * @override + */ + onattach() { + super.onattach(); + this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); + } + + _handleContextMenuEvent(event) { + var contextMenu = new UI.ContextMenu(event); + contextMenu.appendItem(Common.UIString('Refresh Caches'), this._refreshCaches.bind(this)); + contextMenu.show(); + } + + _refreshCaches() { + if (this._swCacheModel) + this._swCacheModel.refreshCacheNames(); + } + + /** + * @param {!Common.Event} event + */ + _cacheAdded(event) { + var cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache); + var model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model); + this._addCache(model, cache); + } + + /** + * @param {!SDK.ServiceWorkerCacheModel} model + * @param {!SDK.ServiceWorkerCacheModel.Cache} cache + */ + _addCache(model, cache) { + var swCacheTreeElement = new Resources.SWCacheTreeElement(this._storagePanel, model, cache); + this._swCacheTreeElements.push(swCacheTreeElement); + this.appendChild(swCacheTreeElement); + } + + /** + * @param {!Common.Event} event + */ + _cacheRemoved(event) { + var cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache); + var model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model); + + var swCacheTreeElement = this._cacheTreeElement(model, cache); + if (!swCacheTreeElement) + return; + + swCacheTreeElement.clear(); + this.removeChild(swCacheTreeElement); + this._swCacheTreeElements.remove(swCacheTreeElement); + } + + /** + * @param {!SDK.ServiceWorkerCacheModel} model + * @param {!SDK.ServiceWorkerCacheModel.Cache} cache + * @return {?Resources.SWCacheTreeElement} + */ + _cacheTreeElement(model, cache) { + var index = -1; + for (var i = 0; i < this._swCacheTreeElements.length; ++i) { + if (this._swCacheTreeElements[i]._cache.equals(cache) && this._swCacheTreeElements[i]._model === model) { + index = i; + break; + } + } + if (index !== -1) + return this._swCacheTreeElements[i]; + return null; + } +}; + +/** + * @unrestricted + */ +Resources.SWCacheTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + * @param {!SDK.ServiceWorkerCacheModel} model + * @param {!SDK.ServiceWorkerCacheModel.Cache} cache + */ + constructor(storagePanel, model, cache) { + super(storagePanel, cache.cacheName + ' - ' + cache.securityOrigin, false); + this._model = model; + this._cache = cache; + var icon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + get itemURL() { + // I don't think this will work at all. + return 'cache://' + this._cache.cacheId; + } + + /** + * @override + */ + onattach() { + super.onattach(); + this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); + } + + _handleContextMenuEvent(event) { + var contextMenu = new UI.ContextMenu(event); + contextMenu.appendItem(Common.UIString('Delete'), this._clearCache.bind(this)); + contextMenu.show(); + } + + _clearCache() { + this._model.deleteCache(this._cache); + } + + /** + * @param {!SDK.ServiceWorkerCacheModel.Cache} cache + */ + update(cache) { + this._cache = cache; + if (this._view) + this._view.update(cache); + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + if (!this._view) + this._view = new Resources.ServiceWorkerCacheView(this._model, this._cache); + + this.showView(this._view); + return false; + } + + clear() { + if (this._view) + this._view.clear(); + } +}; + +/** + * @unrestricted + */ +Resources.ServiceWorkersTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + */ + constructor(storagePanel) { + super(storagePanel, Common.UIString('Service Workers'), false); + var icon = UI.Icon.create('mediumicon-service-worker', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + /** + * @return {string} + */ + get itemURL() { + return 'service-workers://'; + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + if (!this._view) + this._view = new Resources.ServiceWorkersView(); + this.showView(this._view); + return false; + } +}; + +/** + * @unrestricted + */ +Resources.AppManifestTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + */ + constructor(storagePanel) { + super(storagePanel, Common.UIString('Manifest'), false); + var icon = UI.Icon.create('mediumicon-manifest', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + /** + * @return {string} + */ + get itemURL() { + return 'manifest://'; + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + if (!this._view) + this._view = new Resources.AppManifestView(); + this.showView(this._view); + return false; + } +}; + +/** + * @unrestricted + */ +Resources.ClearStorageTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + */ + constructor(storagePanel) { + super(storagePanel, Common.UIString('Clear storage'), false); + var icon = UI.Icon.create('mediumicon-clear-storage', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + /** + * @return {string} + */ + get itemURL() { + return 'clear-storage://'; + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + if (!this._view) + this._view = new Resources.ClearStorageView(); + this.showView(this._view); + return false; + } +}; + +/** + * @unrestricted + */ +Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + */ + constructor(storagePanel) { + super(storagePanel, Common.UIString('IndexedDB'), 'IndexedDB'); + var icon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + _initialize() { + SDK.targetManager.addModelListener( + Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseAdded, this._indexedDBAdded, this); + SDK.targetManager.addModelListener( + Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseRemoved, this._indexedDBRemoved, this); + SDK.targetManager.addModelListener( + Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseLoaded, this._indexedDBLoaded, this); + /** @type {!Array.<!Resources.IDBDatabaseTreeElement>} */ + this._idbDatabaseTreeElements = []; + + var targets = SDK.targetManager.targets(SDK.Target.Capability.Browser); + for (var i = 0; i < targets.length; ++i) { + var indexedDBModel = Resources.IndexedDBModel.fromTarget(targets[i]); + var databases = indexedDBModel.databases(); + for (var j = 0; j < databases.length; ++j) + this._addIndexedDB(indexedDBModel, databases[j]); + } + } + + /** + * @override + */ + onattach() { + super.onattach(); + this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); + } + + _handleContextMenuEvent(event) { + var contextMenu = new UI.ContextMenu(event); + contextMenu.appendItem(Common.UIString('Refresh IndexedDB'), this.refreshIndexedDB.bind(this)); + contextMenu.show(); + } + + refreshIndexedDB() { + var targets = SDK.targetManager.targets(SDK.Target.Capability.Browser); + for (var i = 0; i < targets.length; ++i) + Resources.IndexedDBModel.fromTarget(targets[i]).refreshDatabaseNames(); + } + + /** + * @param {!Common.Event} event + */ + _indexedDBAdded(event) { + var databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId); + var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model); + this._addIndexedDB(model, databaseId); + } + + /** + * @param {!Resources.IndexedDBModel} model + * @param {!Resources.IndexedDBModel.DatabaseId} databaseId + */ + _addIndexedDB(model, databaseId) { + var idbDatabaseTreeElement = new Resources.IDBDatabaseTreeElement(this._storagePanel, model, databaseId); + this._idbDatabaseTreeElements.push(idbDatabaseTreeElement); + this.appendChild(idbDatabaseTreeElement); + model.refreshDatabase(databaseId); + } + + /** + * @param {!Common.Event} event + */ + _indexedDBRemoved(event) { + var databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId); + var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model); + + var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId); + if (!idbDatabaseTreeElement) + return; + + idbDatabaseTreeElement.clear(); + this.removeChild(idbDatabaseTreeElement); + this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement); + } + + /** + * @param {!Common.Event} event + */ + _indexedDBLoaded(event) { + var database = /** @type {!Resources.IndexedDBModel.Database} */ (event.data.database); + var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model); + + var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, database.databaseId); + if (!idbDatabaseTreeElement) + return; + + idbDatabaseTreeElement.update(database); + } + + /** + * @param {!Resources.IndexedDBModel.DatabaseId} databaseId + * @param {!Resources.IndexedDBModel} model + * @return {?Resources.IDBDatabaseTreeElement} + */ + _idbDatabaseTreeElement(model, databaseId) { + var index = -1; + for (var i = 0; i < this._idbDatabaseTreeElements.length; ++i) { + if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId) && + this._idbDatabaseTreeElements[i]._model === model) { + index = i; + break; + } + } + if (index !== -1) + return this._idbDatabaseTreeElements[i]; + return null; + } +}; + +/** + * @unrestricted + */ +Resources.IDBDatabaseTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + * @param {!Resources.IndexedDBModel} model + * @param {!Resources.IndexedDBModel.DatabaseId} databaseId + */ + constructor(storagePanel, model, databaseId) { + super(storagePanel, databaseId.name + ' - ' + databaseId.securityOrigin, false); + this._model = model; + this._databaseId = databaseId; + this._idbObjectStoreTreeElements = {}; + var icon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + get itemURL() { + return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name; + } + + /** + * @override + */ + onattach() { + super.onattach(); + this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); + } + + _handleContextMenuEvent(event) { + var contextMenu = new UI.ContextMenu(event); + contextMenu.appendItem(Common.UIString('Refresh IndexedDB'), this._refreshIndexedDB.bind(this)); + contextMenu.show(); + } + + _refreshIndexedDB() { + this._model.refreshDatabaseNames(); + } + + /** + * @param {!Resources.IndexedDBModel.Database} database + */ + update(database) { + this._database = database; + var objectStoreNames = {}; + for (var objectStoreName in this._database.objectStores) { + var objectStore = this._database.objectStores[objectStoreName]; + objectStoreNames[objectStore.name] = true; + if (!this._idbObjectStoreTreeElements[objectStore.name]) { + var idbObjectStoreTreeElement = + new Resources.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore); + this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement; + this.appendChild(idbObjectStoreTreeElement); + } + this._idbObjectStoreTreeElements[objectStore.name].update(objectStore); + } + for (var objectStoreName in this._idbObjectStoreTreeElements) { + if (!objectStoreNames[objectStoreName]) + this._objectStoreRemoved(objectStoreName); + } + + if (this._view) + this._view.update(database); + + this._updateTooltip(); + } + + _updateTooltip() { + this.tooltip = Common.UIString('Version') + ': ' + this._database.version; + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + if (!this._view) + this._view = new Resources.IDBDatabaseView(this._model, this._database); + + this.showView(this._view); + return false; + } + + /** + * @param {string} objectStoreName + */ + _objectStoreRemoved(objectStoreName) { + var objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName]; + objectStoreTreeElement.clear(); + this.removeChild(objectStoreTreeElement); + delete this._idbObjectStoreTreeElements[objectStoreName]; + } + + clear() { + for (var objectStoreName in this._idbObjectStoreTreeElements) + this._objectStoreRemoved(objectStoreName); + } +}; + +/** + * @unrestricted + */ +Resources.IDBObjectStoreTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + * @param {!Resources.IndexedDBModel} model + * @param {!Resources.IndexedDBModel.DatabaseId} databaseId + * @param {!Resources.IndexedDBModel.ObjectStore} objectStore + */ + constructor(storagePanel, model, databaseId, objectStore) { + super(storagePanel, objectStore.name, false); + this._model = model; + this._databaseId = databaseId; + this._idbIndexTreeElements = {}; + var icon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + get itemURL() { + return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name + '/' + + this._objectStore.name; + } + + /** + * @override + */ + onattach() { + super.onattach(); + this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); + } + + _handleContextMenuEvent(event) { + var contextMenu = new UI.ContextMenu(event); + contextMenu.appendItem(Common.UIString('Clear'), this._clearObjectStore.bind(this)); + contextMenu.show(); + } + + _clearObjectStore() { + /** + * @this {Resources.IDBObjectStoreTreeElement} + */ + function callback() { + this.update(this._objectStore); + } + this._model.clearObjectStore(this._databaseId, this._objectStore.name, callback.bind(this)); + } + + /** + * @param {!Resources.IndexedDBModel.ObjectStore} objectStore + */ + update(objectStore) { + this._objectStore = objectStore; + + var indexNames = {}; + for (var indexName in this._objectStore.indexes) { + var index = this._objectStore.indexes[indexName]; + indexNames[index.name] = true; + if (!this._idbIndexTreeElements[index.name]) { + var idbIndexTreeElement = new Resources.IDBIndexTreeElement( + this._storagePanel, this._model, this._databaseId, this._objectStore, index); + this._idbIndexTreeElements[index.name] = idbIndexTreeElement; + this.appendChild(idbIndexTreeElement); + } + this._idbIndexTreeElements[index.name].update(index); + } + for (var indexName in this._idbIndexTreeElements) { + if (!indexNames[indexName]) + this._indexRemoved(indexName); + } + for (var indexName in this._idbIndexTreeElements) { + if (!indexNames[indexName]) { + this.removeChild(this._idbIndexTreeElements[indexName]); + delete this._idbIndexTreeElements[indexName]; + } + } + + if (this.childCount()) + this.expand(); + + if (this._view) + this._view.update(this._objectStore); + + this._updateTooltip(); + } + + _updateTooltip() { + var keyPathString = this._objectStore.keyPathString; + var tooltipString = keyPathString !== null ? (Common.UIString('Key path: ') + keyPathString) : ''; + if (this._objectStore.autoIncrement) + tooltipString += '\n' + Common.UIString('autoIncrement'); + this.tooltip = tooltipString; + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + if (!this._view) + this._view = new Resources.IDBDataView(this._model, this._databaseId, this._objectStore, null); + + this.showView(this._view); + return false; + } + + /** + * @param {string} indexName + */ + _indexRemoved(indexName) { + var indexTreeElement = this._idbIndexTreeElements[indexName]; + indexTreeElement.clear(); + this.removeChild(indexTreeElement); + delete this._idbIndexTreeElements[indexName]; + } + + clear() { + for (var indexName in this._idbIndexTreeElements) + this._indexRemoved(indexName); + if (this._view) + this._view.clear(); + } +}; + +/** + * @unrestricted + */ +Resources.IDBIndexTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + * @param {!Resources.IndexedDBModel} model + * @param {!Resources.IndexedDBModel.DatabaseId} databaseId + * @param {!Resources.IndexedDBModel.ObjectStore} objectStore + * @param {!Resources.IndexedDBModel.Index} index + */ + constructor(storagePanel, model, databaseId, objectStore, index) { + super(storagePanel, index.name, false); + this._model = model; + this._databaseId = databaseId; + this._objectStore = objectStore; + this._index = index; + } + + get itemURL() { + return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name + '/' + + this._objectStore.name + '/' + this._index.name; + } + + /** + * @param {!Resources.IndexedDBModel.Index} index + */ + update(index) { + this._index = index; + + if (this._view) + this._view.update(this._index); + + this._updateTooltip(); + } + + _updateTooltip() { + var tooltipLines = []; + var keyPathString = this._index.keyPathString; + tooltipLines.push(Common.UIString('Key path: ') + keyPathString); + if (this._index.unique) + tooltipLines.push(Common.UIString('unique')); + if (this._index.multiEntry) + tooltipLines.push(Common.UIString('multiEntry')); + this.tooltip = tooltipLines.join('\n'); + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + if (!this._view) + this._view = new Resources.IDBDataView(this._model, this._databaseId, this._objectStore, this._index); + + this.showView(this._view); + return false; + } + + clear() { + if (this._view) + this._view.clear(); + } +}; + +/** + * @unrestricted + */ +Resources.DOMStorageTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + * @param {!Resources.DOMStorage} domStorage + */ + constructor(storagePanel, domStorage) { + super(storagePanel, domStorage.securityOrigin ? domStorage.securityOrigin : Common.UIString('Local Files'), false); + this._domStorage = domStorage; + var icon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + get itemURL() { + return 'storage://' + this._domStorage.securityOrigin + '/' + + (this._domStorage.isLocalStorage ? 'local' : 'session'); + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + this._storagePanel.showDOMStorage(this._domStorage); + return false; + } + + /** + * @override + */ + onattach() { + super.onattach(); + this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); + } + + _handleContextMenuEvent(event) { + var contextMenu = new UI.ContextMenu(event); + contextMenu.appendItem(Common.UIString('Clear'), () => this._domStorage.clear()); + contextMenu.show(); + } +}; + +Resources.CookieTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ResourcesPanel} storagePanel + * @param {!SDK.ResourceTreeFrame} frame + * @param {string} cookieDomain + */ + constructor(storagePanel, frame, cookieDomain) { + super(storagePanel, cookieDomain ? cookieDomain : Common.UIString('Local Files'), false); + this._target = frame.target(); + this._cookieDomain = cookieDomain; + var icon = UI.Icon.create('mediumicon-cookie', 'resource-tree-item'); + this.setLeadingIcons([icon]); + } + + get itemURL() { + return 'cookies://' + this._cookieDomain; + } + + /** + * @override + */ + onattach() { + super.onattach(); + this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); + } + + /** + * @param {!Event} event + */ + _handleContextMenuEvent(event) { + var contextMenu = new UI.ContextMenu(event); + contextMenu.appendItem( + Common.UIString('Clear'), () => this._storagePanel.clearCookies(this._target, this._cookieDomain)); + contextMenu.show(); + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + this._storagePanel.showCookies(this._target, this._cookieDomain); + return false; + } +}; + +/** + * @unrestricted + */ +Resources.ApplicationCacheManifestTreeElement = class extends Resources.BaseStorageTreeElement { + constructor(storagePanel, manifestURL) { + var title = new Common.ParsedURL(manifestURL).displayName; + super(storagePanel, title, false); + this.tooltip = manifestURL; + this._manifestURL = manifestURL; + } + + get itemURL() { + return 'appcache://' + this._manifestURL; + } + + get manifestURL() { + return this._manifestURL; + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + this._storagePanel.showCategoryView(this._manifestURL); + return false; + } +}; + +/** + * @unrestricted + */ +Resources.ApplicationCacheFrameTreeElement = class extends Resources.BaseStorageTreeElement { + /** + * @param {!Resources.ApplicationPanelSidebar} sidebar + * @param {!SDK.ResourceTreeFrame} frame + * @param {string} manifestURL + */ + constructor(sidebar, frame, manifestURL) { + super(sidebar._panel, '', false); + this._sidebar = sidebar; + this._frameId = frame.id; + this._manifestURL = manifestURL; + this._refreshTitles(frame); + + var icon = UI.Icon.create('largeicon-navigator-folder', 'navigator-tree-item'); + icon.classList.add('navigator-folder-tree-item'); + this.setLeadingIcons([icon]); + } + + get itemURL() { + return 'appcache://' + this._manifestURL + '/' + encodeURI(this.titleAsText()); + } + + get frameId() { + return this._frameId; + } + + get manifestURL() { + return this._manifestURL; + } + + /** + * @param {!SDK.ResourceTreeFrame} frame + */ + _refreshTitles(frame) { + this.title = frame.displayName(); + } + + /** + * @param {!SDK.ResourceTreeFrame} frame + */ + frameNavigated(frame) { + this._refreshTitles(frame); + } + + /** + * @override + * @return {boolean} + */ + onselect(selectedByUser) { + super.onselect(selectedByUser); + this._sidebar._showApplicationCache(this._frameId); + return false; + } +}; + +/** + * @unrestricted + */ +Resources.StorageCategoryView = class extends UI.VBox { + constructor() { + super(); + + this.element.classList.add('storage-view'); + this._emptyWidget = new UI.EmptyWidget(''); + this._emptyWidget.show(this.element); + } + + setText(text) { + this._emptyWidget.text = text; + } +};
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ClearStorageView.js b/third_party/WebKit/Source/devtools/front_end/resources/ClearStorageView.js index 090a26b..7170f9a 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/ClearStorageView.js +++ b/third_party/WebKit/Source/devtools/front_end/resources/ClearStorageView.js
@@ -6,13 +6,9 @@ * @unrestricted */ Resources.ClearStorageView = class extends UI.VBox { - /** - * @param {!Resources.ResourcesPanel} resourcesPanel - */ - constructor(resourcesPanel) { + constructor() { super(true); - this._resourcesPanel = resourcesPanel; this._reportView = new UI.ReportView(Common.UIString('Clear storage')); this._reportView.registerRequiredCSS('resources/clearStorageView.css'); this._reportView.element.classList.add('clear-storage-header');
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js b/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js index e910a7e..7a67c816 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js +++ b/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
@@ -29,17 +29,15 @@ Resources.CookieItemsView = class extends Resources.StorageItemsView { /** - * @param {!Resources.CookieTreeElement} treeElement * @param {!SDK.CookieModel} model * @param {string} cookieDomain */ - constructor(treeElement, model, cookieDomain) { + constructor(model, cookieDomain) { super(Common.UIString('Cookies'), 'cookiesPanel'); this.element.classList.add('storage-view'); this._model = model; - this._treeElement = treeElement; this._cookieDomain = cookieDomain; this._totalSize = 0; @@ -89,7 +87,9 @@ if (!this._cookiesTable) { this._cookiesTable = new CookieTable.CookiesTable( - this._saveCookie.bind(this), this.refreshItems.bind(this), () => this.setCanDeleteSelected(true), + this._saveCookie.bind(this), + this.refreshItems.bind(this), + () => this.setCanDeleteSelected(!!this._cookiesTable.selectedCookie()), this._deleteCookie.bind(this)); }
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js index 22298440..e47760e0 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
@@ -1,122 +1,36 @@ -/* - * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2009 Joseph Pecoraro - * Copyright (C) 2013 Samsung Electronics. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/** - * @implements {SDK.TargetManager.Observer} - * @unrestricted - */ +// 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. + Resources.ResourcesPanel = class extends UI.PanelWithSidebar { constructor() { super('resources'); this.registerRequiredCSS('resources/resourcesPanel.css'); - this._resourcesLastSelectedItemSetting = Common.settings.createSetting('resourcesLastSelectedItem', {}); + this._resourcesLastSelectedItemSetting = Common.settings.createSetting('resourcesLastSelectedItem', ''); - this._sidebarTree = new UI.TreeOutlineInShadow(); - this._sidebarTree.element.classList.add('resources-sidebar'); - this._sidebarTree.registerRequiredCSS('resources/resourcesSidebar.css'); - this._sidebarTree.element.classList.add('filter-all'); - this.panelSidebarElement().appendChild(this._sidebarTree.element); + /** @type {?UI.Widget} */ + this.visibleView = null; - this._applicationTreeElement = this._addSidebarSection(Common.UIString('Application')); - this._manifestTreeElement = new Resources.AppManifestTreeElement(this); - this._applicationTreeElement.appendChild(this._manifestTreeElement); - this.serviceWorkersTreeElement = new Resources.ServiceWorkersTreeElement(this); - this._applicationTreeElement.appendChild(this.serviceWorkersTreeElement); - var clearStorageTreeElement = new Resources.ClearStorageTreeElement(this); - this._applicationTreeElement.appendChild(clearStorageTreeElement); - - var storageTreeElement = this._addSidebarSection(Common.UIString('Storage')); - this.localStorageListTreeElement = - new Resources.StorageCategoryTreeElement(this, Common.UIString('Local Storage'), 'LocalStorage'); - var localStorageIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); - this.localStorageListTreeElement.setLeadingIcons([localStorageIcon]); - - storageTreeElement.appendChild(this.localStorageListTreeElement); - this.sessionStorageListTreeElement = - new Resources.StorageCategoryTreeElement(this, Common.UIString('Session Storage'), 'SessionStorage'); - var sessionStorageIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); - this.sessionStorageListTreeElement.setLeadingIcons([sessionStorageIcon]); - - storageTreeElement.appendChild(this.sessionStorageListTreeElement); - this.indexedDBListTreeElement = new Resources.IndexedDBTreeElement(this); - storageTreeElement.appendChild(this.indexedDBListTreeElement); - this.databasesListTreeElement = - new Resources.StorageCategoryTreeElement(this, Common.UIString('Web SQL'), 'Databases'); - var databaseIcon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); - this.databasesListTreeElement.setLeadingIcons([databaseIcon]); - - storageTreeElement.appendChild(this.databasesListTreeElement); - this.cookieListTreeElement = new Resources.StorageCategoryTreeElement(this, Common.UIString('Cookies'), 'Cookies'); - var cookieIcon = UI.Icon.create('mediumicon-cookie', 'resource-tree-item'); - this.cookieListTreeElement.setLeadingIcons([cookieIcon]); - storageTreeElement.appendChild(this.cookieListTreeElement); - - var cacheTreeElement = this._addSidebarSection(Common.UIString('Cache')); - this.cacheStorageListTreeElement = new Resources.ServiceWorkerCacheTreeElement(this); - cacheTreeElement.appendChild(this.cacheStorageListTreeElement); - this.applicationCacheListTreeElement = - new Resources.StorageCategoryTreeElement(this, Common.UIString('Application Cache'), 'ApplicationCache'); - var applicationCacheIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); - this.applicationCacheListTreeElement.setLeadingIcons([applicationCacheIcon]); - - cacheTreeElement.appendChild(this.applicationCacheListTreeElement); - - this._resourcesSection = new Resources.ResourcesSection(this, this._addSidebarSection(Common.UIString('Frames'))); + /** @type {?Resources.StorageCategoryView} */ + this._categoryView = null; var mainContainer = new UI.VBox(); this.storageViews = mainContainer.element.createChild('div', 'vbox flex-auto'); this._storageViewToolbar = new UI.Toolbar('resources-toolbar', mainContainer.element); this.splitWidget().setMainWidget(mainContainer); - /** @type {!Map.<!Resources.Database, !Object.<string, !Resources.DatabaseTableView>>} */ - this._databaseTableViews = new Map(); - /** @type {!Map.<!Resources.Database, !Resources.DatabaseQueryView>} */ - this._databaseQueryViews = new Map(); - /** @type {!Map.<!Resources.Database, !Resources.DatabaseTreeElement>} */ - this._databaseTreeElements = new Map(); - /** @type {!Map.<!Resources.DOMStorage, !Resources.DOMStorageTreeElement>} */ - this._domStorageTreeElements = new Map(); - /** @type {!Object.<string, boolean>} */ - this._domains = {}; - /** @type {?Resources.DOMStorageItemsView} */ this._domStorageView = null; + /** @type {?Resources.CookieItemsView} */ this._cookieView = null; - this.panelSidebarElement().addEventListener('mousemove', this._onmousemove.bind(this), false); - this.panelSidebarElement().addEventListener('mouseleave', this._onmouseleave.bind(this), false); + /** @type {?UI.EmptyWidget} */ + this._emptyWidget = null; - SDK.targetManager.observeTargets(this); - SDK.targetManager.addModelListener( - SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.FrameNavigated, this._frameNavigated, this); + this._sidebar = new Resources.ApplicationPanelSidebar(this); + this._sidebar.show(this.panelSidebarElement()); } /** @@ -127,421 +41,52 @@ } /** - * @param {string} title - * @return {!UI.TreeElement} + * @param {!UI.Widget} view + * @return {boolean} */ - _addSidebarSection(title) { - var treeElement = new UI.TreeElement(title, true); - treeElement.listItemElement.classList.add('storage-group-list-item'); - treeElement.setCollapsible(false); - treeElement.selectable = false; - this._sidebarTree.appendChild(treeElement); - return treeElement; - } - - /** - * @override - * @param {!SDK.Target} target - */ - targetAdded(target) { - if (this._target) - return; - this._target = target; - this._databaseModel = Resources.DatabaseModel.fromTarget(target); - - this._databaseModel.on(Resources.DatabaseModel.DatabaseAddedEvent, this._databaseAdded, this); - this._databaseModel.on(Resources.DatabaseModel.DatabasesRemovedEvent, this._resetWebSQL, this); - - var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); - if (!resourceTreeModel) - return; - - if (resourceTreeModel.cachedResourcesLoaded()) - this._initialize(); - - resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._initialize, this); - resourceTreeModel.addEventListener( - SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this); - } - - /** - * @override - * @param {!SDK.Target} target - */ - targetRemoved(target) { - if (target !== this._target) - return; - delete this._target; - - var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); - if (resourceTreeModel) { - resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._initialize, this); - resourceTreeModel.removeEventListener( - SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this); - } - this._databaseModel.off(Resources.DatabaseModel.DatabaseAddedEvent, this._databaseAdded, this); - this._databaseModel.off(Resources.DatabaseModel.DatabasesRemovedEvent, this._resetWebSQL, this); - - this._resetWithFrames(); + static _shouldCloseOnReset(view) { + var viewClassesToClose = [ + SourceFrame.ResourceSourceFrame, SourceFrame.ImageView, SourceFrame.FontView, Resources.StorageItemsView, + Resources.DatabaseQueryView, Resources.DatabaseTableView + ]; + return viewClassesToClose.some(type => view instanceof type); } /** * @override */ focus() { - this._sidebarTree.focus(); - } - - _initialize() { - for (var frame of SDK.ResourceTreeModel.frames()) - this._addCookieDocument(frame); - this._databaseModel.enable(); - - var indexedDBModel = Resources.IndexedDBModel.fromTarget(this._target); - if (indexedDBModel) - indexedDBModel.enable(); - - var cacheStorageModel = SDK.ServiceWorkerCacheModel.fromTarget(this._target); - if (cacheStorageModel) - cacheStorageModel.enable(); - var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(this._target); - if (resourceTreeModel) - this._populateApplicationCacheTree(resourceTreeModel); - var domStorageModel = Resources.DOMStorageModel.fromTarget(this._target); - if (domStorageModel) - this._populateDOMStorageTree(domStorageModel); - this.indexedDBListTreeElement._initialize(); - this.cacheStorageListTreeElement._initialize(); - this._initDefaultSelection(); - } - - _initDefaultSelection() { - var itemURL = this._resourcesLastSelectedItemSetting.get(); - if (itemURL) { - var rootElement = this._sidebarTree.rootElement(); - for (var treeElement = rootElement.firstChild(); treeElement; - treeElement = treeElement.traverseNextTreeElement(false, rootElement, true)) { - if (treeElement.itemURL === itemURL) { - treeElement.revealAndSelect(true); - return; - } - } - } - this._manifestTreeElement.select(); - } - - _resetWithFrames() { - this._resourcesSection.reset(); - this._reset(); - } - - _resetWebSQL() { - if (this.visibleView instanceof Resources.DatabaseQueryView || - this.visibleView instanceof Resources.DatabaseTableView) { - this.visibleView.detach(); - delete this.visibleView; - } - - var queryViews = this._databaseQueryViews.valuesArray(); - for (var i = 0; i < queryViews.length; ++i) { - queryViews[i].removeEventListener( - Resources.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this); - } - this._databaseTableViews.clear(); - this._databaseQueryViews.clear(); - this._databaseTreeElements.clear(); - this.databasesListTreeElement.removeChildren(); - this.databasesListTreeElement.setExpandable(false); - } - - _resetDOMStorage() { - if (this.visibleView === this._domStorageView) { - this.visibleView.detach(); - delete this.visibleView; - } - - this._domStorageTreeElements.clear(); - this.localStorageListTreeElement.removeChildren(); - this.sessionStorageListTreeElement.removeChildren(); - } - - _resetCookies() { - if (this.visibleView instanceof Resources.CookieItemsView) { - this.visibleView.detach(); - delete this.visibleView; - } - this.cookieListTreeElement.removeChildren(); - } - - _resetCacheStorage() { - if (this.visibleView instanceof Resources.ServiceWorkerCacheView) { - this.visibleView.detach(); - delete this.visibleView; - } - this.cacheStorageListTreeElement.removeChildren(); - this.cacheStorageListTreeElement.setExpandable(false); - } - - _resetAppCache() { - for (var frameId of Object.keys(this._applicationCacheFrameElements)) - this._applicationCacheFrameManifestRemoved({data: frameId}); - this.applicationCacheListTreeElement.setExpandable(false); - } - - _reset() { - this._domains = {}; - this._resetWebSQL(); - this._resetDOMStorage(); - this._resetCookies(); - this._resetCacheStorage(); - // No need to this._resetAppCache. - - if ((this.visibleView instanceof SourceFrame.ResourceSourceFrame) || - (this.visibleView instanceof SourceFrame.ImageView) || (this.visibleView instanceof SourceFrame.FontView)) { - this.visibleView.detach(); - delete this.visibleView; - } - - this._storageViewToolbar.removeToolbarItems(); - - if (this._sidebarTree.selectedTreeElement) - this._sidebarTree.selectedTreeElement.deselect(); - } - - _frameNavigated(event) { - var frame = event.data; - - if (!frame.parentFrame) - this._reset(); - - var applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frame.id]; - if (applicationCacheFrameTreeElement) - applicationCacheFrameTreeElement.frameNavigated(frame); - this._addCookieDocument(frame); + this._sidebar.focus(); } /** - * @param {!Resources.DatabaseModel.DatabaseAddedEvent} event + * @return {string} */ - _databaseAdded(event) { - var databaseTreeElement = new Resources.DatabaseTreeElement(this, event.database); - this._databaseTreeElements.set(event.database, databaseTreeElement); - this.databasesListTreeElement.appendChild(databaseTreeElement); + lastSelectedItemURL() { + return this._resourcesLastSelectedItemSetting.get(); + } + + setLastSelectedItemURL(url) { + this._resourcesLastSelectedItemSetting.set(url); + } + + resetView() { + if (this.visibleView && Resources.ResourcesPanel._shouldCloseOnReset(this.visibleView)) + this.showView(null); } /** - * @param {!SDK.ResourceTreeFrame} frame + * @param {?UI.Widget} view */ - _addCookieDocument(frame) { - var parsedURL = frame.url.asParsedURL(); - if (!parsedURL || (parsedURL.scheme !== 'http' && parsedURL.scheme !== 'https' && parsedURL.scheme !== 'file')) - return; - - var domain = parsedURL.securityOrigin(); - if (!this._domains[domain]) { - this._domains[domain] = true; - var cookieDomainTreeElement = new Resources.CookieTreeElement(this, frame, domain); - this.cookieListTreeElement.appendChild(cookieDomainTreeElement); - } - } - - /** - * @param {!Common.Event} event - */ - _domStorageAdded(event) { - var domStorage = /** @type {!Resources.DOMStorage} */ (event.data); - this._addDOMStorage(domStorage); - } - - /** - * @param {!Resources.DOMStorage} domStorage - */ - _addDOMStorage(domStorage) { - console.assert(!this._domStorageTreeElements.get(domStorage)); - - var domStorageTreeElement = new Resources.DOMStorageTreeElement(this, domStorage); - this._domStorageTreeElements.set(domStorage, domStorageTreeElement); - if (domStorage.isLocalStorage) - this.localStorageListTreeElement.appendChild(domStorageTreeElement); - else - this.sessionStorageListTreeElement.appendChild(domStorageTreeElement); - } - - /** - * @param {!Common.Event} event - */ - _domStorageRemoved(event) { - var domStorage = /** @type {!Resources.DOMStorage} */ (event.data); - this._removeDOMStorage(domStorage); - } - - /** - * @param {!Resources.DOMStorage} domStorage - */ - _removeDOMStorage(domStorage) { - var treeElement = this._domStorageTreeElements.get(domStorage); - if (!treeElement) - return; - var wasSelected = treeElement.selected; - var parentListTreeElement = treeElement.parent; - parentListTreeElement.removeChild(treeElement); - if (wasSelected) - parentListTreeElement.select(); - this._domStorageTreeElements.remove(domStorage); - } - - /** - * @param {!Resources.Database} database - */ - selectDatabase(database) { - if (database) { - this._showDatabase(database); - this._databaseTreeElements.get(database).select(); - } - } - - /** - * @param {!Resources.DOMStorage} domStorage - */ - selectDOMStorage(domStorage) { - if (domStorage) { - this._showDOMStorage(domStorage); - this._domStorageTreeElements.get(domStorage).select(); - } - } - - /** - * @param {!SDK.Resource} resource - * @param {number=} line - * @param {number=} column - * @return {boolean} - */ - showResource(resource, line, column) { - var resourceTreeElement = Resources.FrameResourceTreeElement.forResource(resource); - if (resourceTreeElement) - resourceTreeElement.revealAndSelect(true); - - if (typeof line === 'number') { - var resourceSourceFrame = this._resourceSourceFrameViewForResource(resource); - if (resourceSourceFrame) - resourceSourceFrame.revealPosition(line, column, true); - } - return true; - } - - /** - * @param {!SDK.Resource} resource - * @return {?SourceFrame.ResourceSourceFrame} - */ - _resourceSourceFrameViewForResource(resource) { - var resourceView = Resources.FrameResourceTreeElement.resourceViewForResource(resource); - if (resourceView && resourceView instanceof SourceFrame.ResourceSourceFrame) - return /** @type {!SourceFrame.ResourceSourceFrame} */ (resourceView); - return null; - } - - /** - * @param {!Resources.Database} database - * @param {string=} tableName - */ - _showDatabase(database, tableName) { - if (!database) - return; - - var view; - if (tableName) { - var tableViews = this._databaseTableViews.get(database); - if (!tableViews) { - tableViews = /** @type {!Object.<string, !Resources.DatabaseTableView>} */ ({}); - this._databaseTableViews.set(database, tableViews); - } - view = tableViews[tableName]; - if (!view) { - view = new Resources.DatabaseTableView(database, tableName); - tableViews[tableName] = view; - } - } else { - view = this._databaseQueryViews.get(database); - if (!view) { - view = new Resources.DatabaseQueryView(database); - this._databaseQueryViews.set(database, view); - view.addEventListener(Resources.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this); - } - } - - this._innerShowView(view); - } - - /** - * @param {!Resources.DOMStorage} domStorage - */ - _showDOMStorage(domStorage) { - if (!domStorage) - return; - - if (!this._domStorageView) - this._domStorageView = new Resources.DOMStorageItemsView(domStorage); - else - this._domStorageView.setStorage(domStorage); - this._innerShowView(this._domStorageView); - } - - /** - * @param {!Resources.CookieTreeElement} treeElement - * @param {string} cookieDomain - * @param {!SDK.Target} cookieFrameTarget - */ - showCookies(treeElement, cookieDomain, cookieFrameTarget) { - var model = SDK.CookieModel.fromTarget(cookieFrameTarget); - if (!this._cookieView) - this._cookieView = new Resources.CookieItemsView(treeElement, model, cookieDomain); - else - this._cookieView.setCookiesDomain(model, cookieDomain); - this._innerShowView(this._cookieView); - } - - /** - * @param {!SDK.Target} target - * @param {string} cookieDomain - */ - _clearCookies(target, cookieDomain) { - SDK.CookieModel.fromTarget(target).clear(cookieDomain, () => { - if (this._cookieView) - this._cookieView.refreshItems(); - }); - } - - showApplicationCache(frameId) { - if (!this._applicationCacheViews[frameId]) { - this._applicationCacheViews[frameId] = - new Resources.ApplicationCacheItemsView(this._applicationCacheModel, frameId); - } - - this._innerShowView(this._applicationCacheViews[frameId]); - } - - /** - * @param {!UI.Widget} view - */ - showFileSystem(view) { - this._innerShowView(view); - } - - showCategoryView(categoryName) { - if (!this._categoryView) - this._categoryView = new Resources.StorageCategoryView(); - this._categoryView.setText(categoryName); - this._innerShowView(this._categoryView); - } - - _innerShowView(view) { + showView(view) { if (this.visibleView === view) return; if (this.visibleView) this.visibleView.detach(); - view.show(this.storageViews); + if (view) + view.show(this.storageViews); this.visibleView = view; this._storageViewToolbar.removeToolbarItems(); @@ -551,172 +96,68 @@ this._storageViewToolbar.element.classList.toggle('hidden', !toolbarItems.length); } - closeVisibleView() { - if (!this.visibleView) - return; - this.visibleView.detach(); - delete this.visibleView; - } - - _updateDatabaseTables(event) { - var database = event.data; - - if (!database) - return; - - var databasesTreeElement = this._databaseTreeElements.get(database); - if (!databasesTreeElement) - return; - - databasesTreeElement.invalidateChildren(); - var tableViews = this._databaseTableViews.get(database); - - if (!tableViews) - return; - - var tableNamesHash = {}; - var self = this; - function tableNamesCallback(tableNames) { - var tableNamesLength = tableNames.length; - for (var i = 0; i < tableNamesLength; ++i) - tableNamesHash[tableNames[i]] = true; - - for (var tableName in tableViews) { - if (!(tableName in tableNamesHash)) { - if (self.visibleView === tableViews[tableName]) - self.closeVisibleView(); - delete tableViews[tableName]; - } - } - } - database.getTableNames(tableNamesCallback); + /** + * @param {string} categoryName + */ + showCategoryView(categoryName) { + if (!this._categoryView) + this._categoryView = new Resources.StorageCategoryView(); + this._categoryView.setText(categoryName); + this.showView(this._categoryView); } /** - * @param {!Resources.DOMStorageModel} domStorageModel + * @param {!Resources.DOMStorage} domStorage */ - _populateDOMStorageTree(domStorageModel) { - domStorageModel.enable(); - domStorageModel.storages().forEach(this._addDOMStorage.bind(this)); - domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); - domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this); + showDOMStorage(domStorage) { + if (!domStorage) + return; + + if (!this._domStorageView) + this._domStorageView = new Resources.DOMStorageItemsView(domStorage); + else + this._domStorageView.setStorage(domStorage); + this.showView(this._domStorageView); } /** - * @param {!SDK.ResourceTreeModel} resourceTreeModel + * @param {!SDK.Target} cookieFrameTarget + * @param {string} cookieDomain */ - _populateApplicationCacheTree(resourceTreeModel) { - this._applicationCacheModel = Resources.ApplicationCacheModel.fromTarget(this._target); - - this._applicationCacheViews = {}; - this._applicationCacheFrameElements = {}; - this._applicationCacheManifestElements = {}; - - this._applicationCacheModel.addEventListener( - Resources.ApplicationCacheModel.Events.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this); - this._applicationCacheModel.addEventListener( - Resources.ApplicationCacheModel.Events.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this); - this._applicationCacheModel.addEventListener( - Resources.ApplicationCacheModel.Events.FrameManifestsReset, this._resetAppCache, this); - - this._applicationCacheModel.addEventListener( - Resources.ApplicationCacheModel.Events.FrameManifestStatusUpdated, - this._applicationCacheFrameManifestStatusChanged, this); - this._applicationCacheModel.addEventListener( - Resources.ApplicationCacheModel.Events.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this); + showCookies(cookieFrameTarget, cookieDomain) { + var model = SDK.CookieModel.fromTarget(cookieFrameTarget); + if (!this._cookieView) + this._cookieView = new Resources.CookieItemsView(model, cookieDomain); + else + this._cookieView.setCookiesDomain(model, cookieDomain); + this.showView(this._cookieView); } - _applicationCacheFrameManifestAdded(event) { - var frameId = event.data; - var manifestURL = this._applicationCacheModel.frameManifestURL(frameId); - - var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]; - if (!manifestTreeElement) { - manifestTreeElement = new Resources.ApplicationCacheManifestTreeElement(this, manifestURL); - this.applicationCacheListTreeElement.appendChild(manifestTreeElement); - this._applicationCacheManifestElements[manifestURL] = manifestTreeElement; - } - - var frameTreeElement = new Resources.ApplicationCacheFrameTreeElement(this, frameId, manifestURL); - manifestTreeElement.appendChild(frameTreeElement); - manifestTreeElement.expand(); - this._applicationCacheFrameElements[frameId] = frameTreeElement; + /** + * @param {string} text + */ + showEmptyWidget(text) { + if (!this._emptyWidget) + this._emptyWidget = new UI.EmptyWidget(text); + else + this._emptyWidget.text = text; + this.showView(this._emptyWidget); } - _applicationCacheFrameManifestRemoved(event) { - var frameId = event.data; - var frameTreeElement = this._applicationCacheFrameElements[frameId]; - if (!frameTreeElement) - return; - - var manifestURL = frameTreeElement.manifestURL; - delete this._applicationCacheFrameElements[frameId]; - delete this._applicationCacheViews[frameId]; - frameTreeElement.parent.removeChild(frameTreeElement); - - var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]; - if (manifestTreeElement.childCount()) - return; - - delete this._applicationCacheManifestElements[manifestURL]; - manifestTreeElement.parent.removeChild(manifestTreeElement); - } - - _applicationCacheFrameManifestStatusChanged(event) { - var frameId = event.data; - var status = this._applicationCacheModel.frameManifestStatus(frameId); - - if (this._applicationCacheViews[frameId]) - this._applicationCacheViews[frameId].updateStatus(status); - } - - _applicationCacheNetworkStateChanged(event) { - var isNowOnline = event.data; - - for (var manifestURL in this._applicationCacheViews) - this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline); - } - - showView(view) { - if (view) - this.showResource(view.resource); - } - - _onmousemove(event) { - var nodeUnderMouse = event.target; - if (!nodeUnderMouse) - return; - - var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName('li'); - if (!listNode) - return; - - var element = listNode.treeElement; - if (this._previousHoveredElement === element) - return; - - if (this._previousHoveredElement) { - this._previousHoveredElement.hovered = false; - delete this._previousHoveredElement; - } - - if (element instanceof Resources.FrameTreeElement) { - this._previousHoveredElement = element; - element.hovered = true; - } - } - - _onmouseleave(event) { - if (this._previousHoveredElement) { - this._previousHoveredElement.hovered = false; - delete this._previousHoveredElement; - } + /** + * @param {!SDK.Target} target + * @param {string} cookieDomain + */ + clearCookies(target, cookieDomain) { + SDK.CookieModel.fromTarget(target).clear(cookieDomain, () => { + if (this._cookieView) + this._cookieView.refreshItems(); + }); } }; /** * @implements {Common.Revealer} - * @unrestricted */ Resources.ResourcesPanel.ResourceRevealer = class { /** @@ -727,1063 +168,7 @@ reveal(resource) { if (!(resource instanceof SDK.Resource)) return Promise.reject(new Error('Internal error: not a resource')); - var panel = Resources.ResourcesPanel._instance(); + var panel = Resources.ResourcesPanel._instance()._sidebar; return UI.viewManager.showView('resources').then(panel.showResource.bind(panel, resource)); } }; - -/** - * @unrestricted - */ -Resources.BaseStorageTreeElement = class extends UI.TreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {string} title - * @param {boolean} expandable - */ - constructor(storagePanel, title, expandable) { - super(title, expandable); - this._storagePanel = storagePanel; - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - if (!selectedByUser) - return false; - var itemURL = this.itemURL; - if (itemURL) - this._storagePanel._resourcesLastSelectedItemSetting.set(itemURL); - return false; - } - - /** - * @protected - * @param {?UI.Widget} view - */ - showView(view) { - if (!view) { - this._storagePanel.visibleView.detach(); - return; - } - this._storagePanel._innerShowView(view); - } -}; - -/** - * @unrestricted - */ -Resources.StorageCategoryTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {string} categoryName - * @param {string} settingsKey - */ - constructor(storagePanel, categoryName, settingsKey) { - super(storagePanel, categoryName, false); - this._expandedSetting = - Common.settings.createSetting('resources' + settingsKey + 'Expanded', settingsKey === 'Frames'); - this._categoryName = categoryName; - } - - /** - * @return {!SDK.Target} - */ - target() { - return this._storagePanel._target; - } - - get itemURL() { - return 'category://' + this._categoryName; - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - this._storagePanel.showCategoryView(this._categoryName); - return false; - } - - /** - * @override - */ - onattach() { - super.onattach(); - if (this._expandedSetting.get()) - this.expand(); - } - - /** - * @override - */ - onexpand() { - this._expandedSetting.set(true); - } - - /** - * @override - */ - oncollapse() { - this._expandedSetting.set(false); - } -}; - -/** - * @unrestricted - */ -Resources.DatabaseTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {!Resources.Database} database - */ - constructor(storagePanel, database) { - super(storagePanel, database.name, true); - this._database = database; - - var icon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - get itemURL() { - return 'database://' + encodeURI(this._database.name); - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - this._storagePanel._showDatabase(this._database); - return false; - } - - /** - * @override - */ - onexpand() { - this._updateChildren(); - } - - _updateChildren() { - this.removeChildren(); - - /** - * @param {!Array.<string>} tableNames - * @this {Resources.DatabaseTreeElement} - */ - function tableNamesCallback(tableNames) { - var tableNamesLength = tableNames.length; - for (var i = 0; i < tableNamesLength; ++i) - this.appendChild(new Resources.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i])); - } - this._database.getTableNames(tableNamesCallback.bind(this)); - } -}; - -/** - * @unrestricted - */ -Resources.DatabaseTableTreeElement = class extends Resources.BaseStorageTreeElement { - constructor(storagePanel, database, tableName) { - super(storagePanel, tableName, false); - this._database = database; - this._tableName = tableName; - var icon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - get itemURL() { - return 'database://' + encodeURI(this._database.name) + '/' + encodeURI(this._tableName); - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - this._storagePanel._showDatabase(this._database, this._tableName); - return false; - } -}; - -/** - * @unrestricted - */ -Resources.ServiceWorkerCacheTreeElement = class extends Resources.StorageCategoryTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - */ - constructor(storagePanel) { - super(storagePanel, Common.UIString('Cache Storage'), 'CacheStorage'); - var icon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - _initialize() { - /** @type {!Array.<!Resources.SWCacheTreeElement>} */ - this._swCacheTreeElements = []; - var target = this._storagePanel._target; - var model = target && SDK.ServiceWorkerCacheModel.fromTarget(target); - if (model) { - for (var cache of model.caches()) - this._addCache(model, cache); - } - SDK.targetManager.addModelListener( - SDK.ServiceWorkerCacheModel, SDK.ServiceWorkerCacheModel.Events.CacheAdded, this._cacheAdded, this); - SDK.targetManager.addModelListener( - SDK.ServiceWorkerCacheModel, SDK.ServiceWorkerCacheModel.Events.CacheRemoved, this._cacheRemoved, this); - } - - /** - * @override - */ - onattach() { - super.onattach(); - this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); - } - - _handleContextMenuEvent(event) { - var contextMenu = new UI.ContextMenu(event); - contextMenu.appendItem(Common.UIString('Refresh Caches'), this._refreshCaches.bind(this)); - contextMenu.show(); - } - - _refreshCaches() { - var target = this._storagePanel._target; - if (target) { - var model = SDK.ServiceWorkerCacheModel.fromTarget(target); - if (!model) - return; - model.refreshCacheNames(); - } - } - - /** - * @param {!Common.Event} event - */ - _cacheAdded(event) { - var cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache); - var model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model); - this._addCache(model, cache); - } - - /** - * @param {!SDK.ServiceWorkerCacheModel} model - * @param {!SDK.ServiceWorkerCacheModel.Cache} cache - */ - _addCache(model, cache) { - var swCacheTreeElement = new Resources.SWCacheTreeElement(this._storagePanel, model, cache); - this._swCacheTreeElements.push(swCacheTreeElement); - this.appendChild(swCacheTreeElement); - } - - /** - * @param {!Common.Event} event - */ - _cacheRemoved(event) { - var cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache); - var model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model); - - var swCacheTreeElement = this._cacheTreeElement(model, cache); - if (!swCacheTreeElement) - return; - - swCacheTreeElement.clear(); - this.removeChild(swCacheTreeElement); - this._swCacheTreeElements.remove(swCacheTreeElement); - } - - /** - * @param {!SDK.ServiceWorkerCacheModel} model - * @param {!SDK.ServiceWorkerCacheModel.Cache} cache - * @return {?Resources.SWCacheTreeElement} - */ - _cacheTreeElement(model, cache) { - var index = -1; - for (var i = 0; i < this._swCacheTreeElements.length; ++i) { - if (this._swCacheTreeElements[i]._cache.equals(cache) && this._swCacheTreeElements[i]._model === model) { - index = i; - break; - } - } - if (index !== -1) - return this._swCacheTreeElements[i]; - return null; - } -}; - -/** - * @unrestricted - */ -Resources.SWCacheTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {!SDK.ServiceWorkerCacheModel} model - * @param {!SDK.ServiceWorkerCacheModel.Cache} cache - */ - constructor(storagePanel, model, cache) { - super(storagePanel, cache.cacheName + ' - ' + cache.securityOrigin, false); - this._model = model; - this._cache = cache; - var icon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - get itemURL() { - // I don't think this will work at all. - return 'cache://' + this._cache.cacheId; - } - - /** - * @override - */ - onattach() { - super.onattach(); - this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); - } - - _handleContextMenuEvent(event) { - var contextMenu = new UI.ContextMenu(event); - contextMenu.appendItem(Common.UIString('Delete'), this._clearCache.bind(this)); - contextMenu.show(); - } - - _clearCache() { - this._model.deleteCache(this._cache); - } - - /** - * @param {!SDK.ServiceWorkerCacheModel.Cache} cache - */ - update(cache) { - this._cache = cache; - if (this._view) - this._view.update(cache); - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - if (!this._view) - this._view = new Resources.ServiceWorkerCacheView(this._model, this._cache); - - this.showView(this._view); - return false; - } - - clear() { - if (this._view) - this._view.clear(); - } -}; - -/** - * @unrestricted - */ -Resources.ServiceWorkersTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - */ - constructor(storagePanel) { - super(storagePanel, Common.UIString('Service Workers'), false); - var icon = UI.Icon.create('mediumicon-service-worker', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - /** - * @return {string} - */ - get itemURL() { - return 'service-workers://'; - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - if (!this._view) - this._view = new Resources.ServiceWorkersView(); - this.showView(this._view); - return false; - } -}; - -/** - * @unrestricted - */ -Resources.AppManifestTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - */ - constructor(storagePanel) { - super(storagePanel, Common.UIString('Manifest'), false); - var icon = UI.Icon.create('mediumicon-manifest', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - /** - * @return {string} - */ - get itemURL() { - return 'manifest://'; - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - if (!this._view) - this._view = new Resources.AppManifestView(); - this.showView(this._view); - return false; - } -}; - -/** - * @unrestricted - */ -Resources.ClearStorageTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - */ - constructor(storagePanel) { - super(storagePanel, Common.UIString('Clear storage'), false); - var icon = UI.Icon.create('mediumicon-clear-storage', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - /** - * @return {string} - */ - get itemURL() { - return 'clear-storage://'; - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - if (!this._view) - this._view = new Resources.ClearStorageView(this._storagePanel); - this.showView(this._view); - return false; - } -}; - -/** - * @unrestricted - */ -Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - */ - constructor(storagePanel) { - super(storagePanel, Common.UIString('IndexedDB'), 'IndexedDB'); - var icon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - _initialize() { - SDK.targetManager.addModelListener( - Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseAdded, this._indexedDBAdded, this); - SDK.targetManager.addModelListener( - Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseRemoved, this._indexedDBRemoved, this); - SDK.targetManager.addModelListener( - Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseLoaded, this._indexedDBLoaded, this); - /** @type {!Array.<!Resources.IDBDatabaseTreeElement>} */ - this._idbDatabaseTreeElements = []; - - var targets = SDK.targetManager.targets(SDK.Target.Capability.Browser); - for (var i = 0; i < targets.length; ++i) { - var indexedDBModel = Resources.IndexedDBModel.fromTarget(targets[i]); - var databases = indexedDBModel.databases(); - for (var j = 0; j < databases.length; ++j) - this._addIndexedDB(indexedDBModel, databases[j]); - } - } - - /** - * @override - */ - onattach() { - super.onattach(); - this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); - } - - _handleContextMenuEvent(event) { - var contextMenu = new UI.ContextMenu(event); - contextMenu.appendItem(Common.UIString('Refresh IndexedDB'), this.refreshIndexedDB.bind(this)); - contextMenu.show(); - } - - refreshIndexedDB() { - var targets = SDK.targetManager.targets(SDK.Target.Capability.Browser); - for (var i = 0; i < targets.length; ++i) - Resources.IndexedDBModel.fromTarget(targets[i]).refreshDatabaseNames(); - } - - /** - * @param {!Common.Event} event - */ - _indexedDBAdded(event) { - var databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId); - var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model); - this._addIndexedDB(model, databaseId); - } - - /** - * @param {!Resources.IndexedDBModel} model - * @param {!Resources.IndexedDBModel.DatabaseId} databaseId - */ - _addIndexedDB(model, databaseId) { - var idbDatabaseTreeElement = new Resources.IDBDatabaseTreeElement(this._storagePanel, model, databaseId); - this._idbDatabaseTreeElements.push(idbDatabaseTreeElement); - this.appendChild(idbDatabaseTreeElement); - model.refreshDatabase(databaseId); - } - - /** - * @param {!Common.Event} event - */ - _indexedDBRemoved(event) { - var databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId); - var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model); - - var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId); - if (!idbDatabaseTreeElement) - return; - - idbDatabaseTreeElement.clear(); - this.removeChild(idbDatabaseTreeElement); - this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement); - } - - /** - * @param {!Common.Event} event - */ - _indexedDBLoaded(event) { - var database = /** @type {!Resources.IndexedDBModel.Database} */ (event.data.database); - var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model); - - var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, database.databaseId); - if (!idbDatabaseTreeElement) - return; - - idbDatabaseTreeElement.update(database); - } - - /** - * @param {!Resources.IndexedDBModel.DatabaseId} databaseId - * @param {!Resources.IndexedDBModel} model - * @return {?Resources.IDBDatabaseTreeElement} - */ - _idbDatabaseTreeElement(model, databaseId) { - var index = -1; - for (var i = 0; i < this._idbDatabaseTreeElements.length; ++i) { - if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId) && - this._idbDatabaseTreeElements[i]._model === model) { - index = i; - break; - } - } - if (index !== -1) - return this._idbDatabaseTreeElements[i]; - return null; - } -}; - -/** - * @unrestricted - */ -Resources.IDBDatabaseTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {!Resources.IndexedDBModel} model - * @param {!Resources.IndexedDBModel.DatabaseId} databaseId - */ - constructor(storagePanel, model, databaseId) { - super(storagePanel, databaseId.name + ' - ' + databaseId.securityOrigin, false); - this._model = model; - this._databaseId = databaseId; - this._idbObjectStoreTreeElements = {}; - var icon = UI.Icon.create('mediumicon-database', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - get itemURL() { - return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name; - } - - /** - * @override - */ - onattach() { - super.onattach(); - this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); - } - - _handleContextMenuEvent(event) { - var contextMenu = new UI.ContextMenu(event); - contextMenu.appendItem(Common.UIString('Refresh IndexedDB'), this._refreshIndexedDB.bind(this)); - contextMenu.show(); - } - - _refreshIndexedDB() { - this._model.refreshDatabaseNames(); - } - - /** - * @param {!Resources.IndexedDBModel.Database} database - */ - update(database) { - this._database = database; - var objectStoreNames = {}; - for (var objectStoreName in this._database.objectStores) { - var objectStore = this._database.objectStores[objectStoreName]; - objectStoreNames[objectStore.name] = true; - if (!this._idbObjectStoreTreeElements[objectStore.name]) { - var idbObjectStoreTreeElement = - new Resources.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore); - this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement; - this.appendChild(idbObjectStoreTreeElement); - } - this._idbObjectStoreTreeElements[objectStore.name].update(objectStore); - } - for (var objectStoreName in this._idbObjectStoreTreeElements) { - if (!objectStoreNames[objectStoreName]) - this._objectStoreRemoved(objectStoreName); - } - - if (this._view) - this._view.update(database); - - this._updateTooltip(); - } - - _updateTooltip() { - this.tooltip = Common.UIString('Version') + ': ' + this._database.version; - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - if (!this._view) - this._view = new Resources.IDBDatabaseView(this._model, this._database); - - this.showView(this._view); - return false; - } - - /** - * @param {string} objectStoreName - */ - _objectStoreRemoved(objectStoreName) { - var objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName]; - objectStoreTreeElement.clear(); - this.removeChild(objectStoreTreeElement); - delete this._idbObjectStoreTreeElements[objectStoreName]; - } - - clear() { - for (var objectStoreName in this._idbObjectStoreTreeElements) - this._objectStoreRemoved(objectStoreName); - } -}; - -/** - * @unrestricted - */ -Resources.IDBObjectStoreTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {!Resources.IndexedDBModel} model - * @param {!Resources.IndexedDBModel.DatabaseId} databaseId - * @param {!Resources.IndexedDBModel.ObjectStore} objectStore - */ - constructor(storagePanel, model, databaseId, objectStore) { - super(storagePanel, objectStore.name, false); - this._model = model; - this._databaseId = databaseId; - this._idbIndexTreeElements = {}; - var icon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - get itemURL() { - return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name + '/' + - this._objectStore.name; - } - - /** - * @override - */ - onattach() { - super.onattach(); - this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); - } - - _handleContextMenuEvent(event) { - var contextMenu = new UI.ContextMenu(event); - contextMenu.appendItem(Common.UIString('Clear'), this._clearObjectStore.bind(this)); - contextMenu.show(); - } - - _clearObjectStore() { - /** - * @this {Resources.IDBObjectStoreTreeElement} - */ - function callback() { - this.update(this._objectStore); - } - this._model.clearObjectStore(this._databaseId, this._objectStore.name, callback.bind(this)); - } - - /** - * @param {!Resources.IndexedDBModel.ObjectStore} objectStore - */ - update(objectStore) { - this._objectStore = objectStore; - - var indexNames = {}; - for (var indexName in this._objectStore.indexes) { - var index = this._objectStore.indexes[indexName]; - indexNames[index.name] = true; - if (!this._idbIndexTreeElements[index.name]) { - var idbIndexTreeElement = new Resources.IDBIndexTreeElement( - this._storagePanel, this._model, this._databaseId, this._objectStore, index); - this._idbIndexTreeElements[index.name] = idbIndexTreeElement; - this.appendChild(idbIndexTreeElement); - } - this._idbIndexTreeElements[index.name].update(index); - } - for (var indexName in this._idbIndexTreeElements) { - if (!indexNames[indexName]) - this._indexRemoved(indexName); - } - for (var indexName in this._idbIndexTreeElements) { - if (!indexNames[indexName]) { - this.removeChild(this._idbIndexTreeElements[indexName]); - delete this._idbIndexTreeElements[indexName]; - } - } - - if (this.childCount()) - this.expand(); - - if (this._view) - this._view.update(this._objectStore); - - this._updateTooltip(); - } - - _updateTooltip() { - var keyPathString = this._objectStore.keyPathString; - var tooltipString = keyPathString !== null ? (Common.UIString('Key path: ') + keyPathString) : ''; - if (this._objectStore.autoIncrement) - tooltipString += '\n' + Common.UIString('autoIncrement'); - this.tooltip = tooltipString; - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - if (!this._view) - this._view = new Resources.IDBDataView(this._model, this._databaseId, this._objectStore, null); - - this.showView(this._view); - return false; - } - - /** - * @param {string} indexName - */ - _indexRemoved(indexName) { - var indexTreeElement = this._idbIndexTreeElements[indexName]; - indexTreeElement.clear(); - this.removeChild(indexTreeElement); - delete this._idbIndexTreeElements[indexName]; - } - - clear() { - for (var indexName in this._idbIndexTreeElements) - this._indexRemoved(indexName); - if (this._view) - this._view.clear(); - } -}; - -/** - * @unrestricted - */ -Resources.IDBIndexTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {!Resources.IndexedDBModel} model - * @param {!Resources.IndexedDBModel.DatabaseId} databaseId - * @param {!Resources.IndexedDBModel.ObjectStore} objectStore - * @param {!Resources.IndexedDBModel.Index} index - */ - constructor(storagePanel, model, databaseId, objectStore, index) { - super(storagePanel, index.name, false); - this._model = model; - this._databaseId = databaseId; - this._objectStore = objectStore; - this._index = index; - } - - get itemURL() { - return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name + '/' + - this._objectStore.name + '/' + this._index.name; - } - - /** - * @param {!Resources.IndexedDBModel.Index} index - */ - update(index) { - this._index = index; - - if (this._view) - this._view.update(this._index); - - this._updateTooltip(); - } - - _updateTooltip() { - var tooltipLines = []; - var keyPathString = this._index.keyPathString; - tooltipLines.push(Common.UIString('Key path: ') + keyPathString); - if (this._index.unique) - tooltipLines.push(Common.UIString('unique')); - if (this._index.multiEntry) - tooltipLines.push(Common.UIString('multiEntry')); - this.tooltip = tooltipLines.join('\n'); - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - if (!this._view) - this._view = new Resources.IDBDataView(this._model, this._databaseId, this._objectStore, this._index); - - this.showView(this._view); - return false; - } - - clear() { - if (this._view) - this._view.clear(); - } -}; - -/** - * @unrestricted - */ -Resources.DOMStorageTreeElement = class extends Resources.BaseStorageTreeElement { - constructor(storagePanel, domStorage) { - super(storagePanel, domStorage.securityOrigin ? domStorage.securityOrigin : Common.UIString('Local Files'), false); - this._domStorage = domStorage; - var icon = UI.Icon.create('mediumicon-table', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - get itemURL() { - return 'storage://' + this._domStorage.securityOrigin + '/' + - (this._domStorage.isLocalStorage ? 'local' : 'session'); - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - this._storagePanel._showDOMStorage(this._domStorage); - return false; - } - - /** - * @override - */ - onattach() { - super.onattach(); - this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); - } - - _handleContextMenuEvent(event) { - var contextMenu = new UI.ContextMenu(event); - contextMenu.appendItem(Common.UIString('Clear'), () => this._domStorage.clear()); - contextMenu.show(); - } -}; - -Resources.CookieTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {!SDK.ResourceTreeFrame} frame - * @param {string} cookieDomain - */ - constructor(storagePanel, frame, cookieDomain) { - super(storagePanel, cookieDomain ? cookieDomain : Common.UIString('Local Files'), false); - this._target = frame.target(); - this._cookieDomain = cookieDomain; - var icon = UI.Icon.create('mediumicon-cookie', 'resource-tree-item'); - this.setLeadingIcons([icon]); - } - - get itemURL() { - return 'cookies://' + this._cookieDomain; - } - - /** - * @override - */ - onattach() { - super.onattach(); - this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true); - } - - /** - * @param {!Event} event - */ - _handleContextMenuEvent(event) { - var contextMenu = new UI.ContextMenu(event); - contextMenu.appendItem( - Common.UIString('Clear'), () => this._storagePanel._clearCookies(this._target, this._cookieDomain)); - contextMenu.show(); - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - this._storagePanel.showCookies(this, this._cookieDomain, this._target); - return false; - } -}; - -/** - * @unrestricted - */ -Resources.ApplicationCacheManifestTreeElement = class extends Resources.BaseStorageTreeElement { - constructor(storagePanel, manifestURL) { - var title = new Common.ParsedURL(manifestURL).displayName; - super(storagePanel, title, false); - this.tooltip = manifestURL; - this._manifestURL = manifestURL; - } - - get itemURL() { - return 'appcache://' + this._manifestURL; - } - - get manifestURL() { - return this._manifestURL; - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - this._storagePanel.showCategoryView(this._manifestURL); - return false; - } -}; - -/** - * @unrestricted - */ -Resources.ApplicationCacheFrameTreeElement = class extends Resources.BaseStorageTreeElement { - /** - * @param {!Resources.ResourcesPanel} storagePanel - * @param {!Protocol.Page.FrameId} frameId - * @param {string} manifestURL - */ - constructor(storagePanel, frameId, manifestURL) { - super(storagePanel, '', false); - this._frameId = frameId; - this._manifestURL = manifestURL; - this._refreshTitles(); - - var icon = UI.Icon.create('largeicon-navigator-folder', 'navigator-tree-item'); - icon.classList.add('navigator-folder-tree-item'); - this.setLeadingIcons([icon]); - } - - get itemURL() { - return 'appcache://' + this._manifestURL + '/' + encodeURI(this.titleAsText()); - } - - get frameId() { - return this._frameId; - } - - get manifestURL() { - return this._manifestURL; - } - - _refreshTitles() { - var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(this._storagePanel._target); - var frame = resourceTreeModel.frameForId(this._frameId); - this.title = frame.displayName(); - } - - frameNavigated() { - this._refreshTitles(); - } - - /** - * @override - * @return {boolean} - */ - onselect(selectedByUser) { - super.onselect(selectedByUser); - this._storagePanel.showApplicationCache(this._frameId); - return false; - } -}; - -/** - * @unrestricted - */ -Resources.StorageCategoryView = class extends UI.VBox { - constructor() { - super(); - - this.element.classList.add('storage-view'); - this._emptyWidget = new UI.EmptyWidget(''); - this._emptyWidget.show(this.element); - } - - setText(text) { - this._emptyWidget.text = text; - } -};
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/module.json b/third_party/WebKit/Source/devtools/front_end/resources/module.json index 6531547e..99e22449 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/module.json +++ b/third_party/WebKit/Source/devtools/front_end/resources/module.json
@@ -40,6 +40,7 @@ "IndexedDBModel.js", "IndexedDBViews.js", "ResourcesPanel.js", + "ApplicationPanelSidebar.js", "ResourcesSection.js", "ServiceWorkerCacheViews.js", "ServiceWorkersView.js"
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js index b6d4378f..3ff7d632 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
@@ -1847,13 +1847,15 @@ /** * @param {!SDK.RemoteObject} object - * @param {function(?SDK.DOMNode)} callback + * @return {!Promise<?SDK.DOMNode>} */ - pushObjectAsNodeToFrontend(object, callback) { - if (object.isNode()) - this.pushNodeToFrontend(/** @type {string} */ (object.objectId), callback); - else - callback(null); + pushObjectAsNodeToFrontend(object) { + return new Promise(fulfill => { + if (object.isNode()) + this.pushNodeToFrontend(/** @type {string} */ (object.objectId), fulfill); + else + fulfill(null); + }); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js b/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js index 6dbd6449..2e65110 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js
@@ -84,19 +84,6 @@ } /** - * @param {!Protocol.Runtime.ObjectPreview} preview - * @return {number} - */ - static mapOrSetEntriesCount(preview) { - if (preview.subtype !== 'map' && preview.subtype !== 'set') - return 0; - var matches = preview.description.match(SDK.RemoteObject._descriptionLengthParenRegex); - if (!matches) - return 0; - return parseInt(matches[1], 10); - } - - /** * @param {!Protocol.Runtime.RemoteObject|!SDK.RemoteObject|number|string|boolean|undefined|null} object * @return {!Protocol.Runtime.CallArgument} */
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js index 06160f5..6ea5c477 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
@@ -490,7 +490,7 @@ this._queryRange = new Common.TextRange( 0, beforeRange.toString().length, 0, beforeRange.toString().length + fullWordRange.toString().length); - var shouldSelect = !this._disableDefaultSuggestionForEmptyInput || this.text(); + var shouldSelect = !this._disableDefaultSuggestionForEmptyInput || !!this.text(); if (this._suggestBox) { this._suggestBox.updateSuggestions( this._boxForAnchorAtStart(selection, fullWordRange), completions, shouldSelect, !this._isCaretAtEndOfPrompt(),
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/inspectorStyle.css b/third_party/WebKit/Source/devtools/front_end/ui/inspectorStyle.css index 0d55955..681f319c 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/inspectorStyle.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/inspectorStyle.css
@@ -48,7 +48,7 @@ .platform-linux { color: rgb(48, 57, 66); - font-family: Ubuntu, Arial, sans-serif; + font-family: Roboto, Ubuntu, Arial, sans-serif; } .platform-mac {
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp index 5a8c0c66..cb81f55 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
@@ -524,10 +524,6 @@ return blink::freshnessLifetime(response(), m_responseTimestamp); } -double Resource::stalenessLifetime() const { - return response().cacheControlStaleWhileRevalidate(); -} - static bool canUseResponse(const ResourceResponse& response, double responseTimestamp) { if (response.isNull())
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.h b/third_party/WebKit/Source/platform/loader/fetch/Resource.h index cbd4c0f7..0ff68ed 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/Resource.h +++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.h
@@ -282,7 +282,6 @@ double currentAge() const; double freshnessLifetime() const; - double stalenessLifetime() const; bool isAlive() const { return m_isAlive; }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp index f7fcd772..596adba 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -699,16 +699,6 @@ if (!eTag.isEmpty()) revalidatingRequest.setHTTPHeaderField(HTTPNames::If_None_Match, eTag); - double stalenessLifetime = resource->stalenessLifetime(); - if (std::isfinite(stalenessLifetime) && stalenessLifetime > 0) { - revalidatingRequest.setHTTPHeaderField( - HTTPNames::Resource_Freshness, - AtomicString(String::format( - "max-age=%.0lf,stale-while-revalidate=%.0lf,age=%.0lf", - resource->freshnessLifetime(), stalenessLifetime, - resource->currentAge()))); - } - resource->setRevalidatingRequest(revalidatingRequest); }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.cpp index ffeb3fd..951732d 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.cpp
@@ -453,15 +453,6 @@ return m_cacheControlHeader.maxAge; } -double ResourceResponse::cacheControlStaleWhileRevalidate() const { - if (!m_cacheControlHeader.parsed) { - m_cacheControlHeader = - parseCacheControlDirectives(m_httpHeaderFields.get(cacheControlHeader), - m_httpHeaderFields.get(pragmaHeader)); - } - return m_cacheControlHeader.staleWhileRevalidate; -} - static double parseDateValueInHeader(const HTTPHeaderMap& headers, const AtomicString& headerName) { const AtomicString& headerValue = headers.get(headerName);
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.h index f6ccce6f..f2cc0373 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.h +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.h
@@ -197,7 +197,6 @@ bool cacheControlContainsMustRevalidate() const; bool hasCacheValidatorFields() const; double cacheControlMaxAge() const; - double cacheControlStaleWhileRevalidate() const; double date() const; double age() const; double expires() const;
diff --git a/third_party/WebKit/Source/platform/network/HTTPParsers.cpp b/third_party/WebKit/Source/platform/network/HTTPParsers.cpp index e0928aa..d94093a 100644 --- a/third_party/WebKit/Source/platform/network/HTTPParsers.cpp +++ b/third_party/WebKit/Source/platform/network/HTTPParsers.cpp
@@ -700,14 +700,11 @@ CacheControlHeader cacheControlHeader; cacheControlHeader.parsed = true; cacheControlHeader.maxAge = std::numeric_limits<double>::quiet_NaN(); - cacheControlHeader.staleWhileRevalidate = - std::numeric_limits<double>::quiet_NaN(); static const char noCacheDirective[] = "no-cache"; static const char noStoreDirective[] = "no-store"; static const char mustRevalidateDirective[] = "must-revalidate"; static const char maxAgeDirective[] = "max-age"; - static const char staleWhileRevalidateDirective[] = "stale-while-revalidate"; if (!cacheControlValue.isEmpty()) { Vector<std::pair<String, String>> directives; @@ -734,17 +731,6 @@ double maxAge = directives[i].second.toDouble(&ok); if (ok) cacheControlHeader.maxAge = maxAge; - } else if (equalIgnoringCase(directives[i].first, - staleWhileRevalidateDirective)) { - if (!std::isnan(cacheControlHeader.staleWhileRevalidate)) { - // First stale-while-revalidate directive wins if there are multiple - // ones. - continue; - } - bool ok; - double staleWhileRevalidate = directives[i].second.toDouble(&ok); - if (ok) - cacheControlHeader.staleWhileRevalidate = staleWhileRevalidate; } } }
diff --git a/third_party/WebKit/Source/platform/network/HTTPParsers.h b/third_party/WebKit/Source/platform/network/HTTPParsers.h index f6b2b5f..a2094bf 100644 --- a/third_party/WebKit/Source/platform/network/HTTPParsers.h +++ b/third_party/WebKit/Source/platform/network/HTTPParsers.h
@@ -79,15 +79,13 @@ bool containsNoStore : 1; bool containsMustRevalidate : 1; double maxAge; - double staleWhileRevalidate; CacheControlHeader() : parsed(false), containsNoCache(false), containsNoStore(false), containsMustRevalidate(false), - maxAge(0.0), - staleWhileRevalidate(0.0) {} + maxAge(0.0) {} }; PLATFORM_EXPORT ContentDispositionType getContentDispositionType(const String&);
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py index 56f7982..295d5f1 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py
@@ -275,6 +275,8 @@ test_input.should_run_pixel_test = True else: test_input.should_run_pixel_test = self._port.should_run_as_pixel_test(test_input) + test_input.should_run_pixel_test_first = ( + self._port.should_run_pixel_test_first(test_input)) def _run_test(self, test_input, shard_name): self._batch_count += 1
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py index a79ed87..1804e07 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py
@@ -70,6 +70,7 @@ self._worker_name = worker_name self._test_name = test_input.test_name self._should_run_pixel_test = test_input.should_run_pixel_test + self._should_run_pixel_test_first = test_input.should_run_pixel_test_first self._reference_files = test_input.reference_files self._should_add_missing_baselines = test_input.should_add_missing_baselines self._stop_when_done = stop_when_done @@ -283,11 +284,27 @@ is_testharness_test, testharness_failures = self._compare_testharness_test(driver_output, expected_driver_output) if is_testharness_test: failures.extend(testharness_failures) + + compare_functions = [] + compare_image_fn = (self._compare_image, (expected_driver_output, driver_output)) + compare_txt_fn = (self._compare_text, (expected_driver_output.text, driver_output.text)) + compare_audio_fn = (self._compare_audio, (expected_driver_output.audio, driver_output.audio)) + + if self._should_run_pixel_test_first: + if driver_output.image_hash and self._should_run_pixel_test: + compare_functions.append(compare_image_fn) + elif not is_testharness_test: + compare_functions.append(compare_txt_fn) else: - failures.extend(self._compare_text(expected_driver_output.text, driver_output.text)) - failures.extend(self._compare_audio(expected_driver_output.audio, driver_output.audio)) - if self._should_run_pixel_test: - failures.extend(self._compare_image(expected_driver_output, driver_output)) + if not is_testharness_test: + compare_functions.append(compare_txt_fn) + if self._should_run_pixel_test: + compare_functions.append(compare_image_fn) + compare_functions.append(compare_audio_fn) + + for func, args in compare_functions: + failures.extend(func(*args)) + has_repaint_overlay = (repaint_overlay.result_contains_repaint_rects(expected_driver_output.text) or repaint_overlay.result_contains_repaint_rects(driver_output.text)) return TestResult(self._test_name, failures, driver_output.test_time, driver_output.has_stderr(),
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py index f6ee2901..503421b 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -1569,6 +1569,10 @@ return False return True + def should_run_pixel_test_first(self, test_input): + return any(test_input.test_name.startswith( + directory) for directory in self._options.image_first_tests) + def _convert_path(self, path): """Handles filename conversion for subprocess command line args.""" # See note above in diff_image() for why we need this.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index d4f23c9..f999f5c 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -235,6 +235,15 @@ dest='smoke', action='store_false', help='Do not run just the SmokeTests'), + optparse.make_option( + '--image-first-tests', + action='append', + default=[], + dest='image_first_tests', + help=('A directory (or test) where the test result will only be compared with the ' + 'image baseline if an image baseline is available, and fall back to comparison ' + 'with the text baseline when image baselines are missing. Specify multiple times ' + 'to add multiple directories/tests.')), ])) option_group_definitions.append(
diff --git a/tools/json_schema_compiler/js_externs_generator_test.py b/tools/json_schema_compiler/js_externs_generator_test.py index 88c2a09f..fe7ab688d 100755 --- a/tools/json_schema_compiler/js_externs_generator_test.py +++ b/tools/json_schema_compiler/js_externs_generator_test.py
@@ -63,6 +63,8 @@ callback BazGreekCallback = void(Baz baz, Greek greek); + callback OptionalParamCallback = void(optional Qux qux); + interface Functions { // Does something exciting! And what's more, this is a multiline function // comment! It goes onto multiple lines! @@ -75,6 +77,8 @@ static void bazGreek(optional BazGreekCallback callback); [deprecated="Use a new method."] static DOMString returnString(); + + static void optionalParam(optional OptionalParamCallback callback); }; interface Events { @@ -205,6 +209,12 @@ chrome.fakeApi.returnString = function() {}; /** + * @param {function(!chrome.fakeApi.Qux|undefined):void=} callback + * @see https://developer.chrome.com/extensions/fakeApi#method-optionalParam + */ +chrome.fakeApi.optionalParam = function(callback) {}; + +/** * Fired when we realize it's a trap! * @type {!ChromeEvent} * @see https://developer.chrome.com/extensions/fakeApi#event-onTrapDetected
diff --git a/tools/json_schema_compiler/js_util.py b/tools/json_schema_compiler/js_util.py index e563b88..064b40b 100644 --- a/tools/json_schema_compiler/js_util.py +++ b/tools/json_schema_compiler/js_util.py
@@ -119,6 +119,8 @@ c.Append('function(') for i, param in enumerate(function.params): c.Concat(self._TypeToJsType(namespace_name, param.type_), new_line=False) + if param.optional: + c.Append('|undefined', new_line=False) if i is not len(function.params) - 1: c.Append(', ', new_line=False, strip_right=False) c.Append('):', new_line=False)
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 7db750c3..887eb9b 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -4460,6 +4460,7 @@ <action name="FirstRunDef_Accept"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> + <obsolete>Deprecated 02/2017.</obsolete> </action> <action name="Flash.JavaScriptUsed" not_user_triggered="true">
diff --git a/ui/OWNERS b/ui/OWNERS index 79875b5..7eb8966a 100644 --- a/ui/OWNERS +++ b/ui/OWNERS
@@ -6,10 +6,6 @@ avi@chromium.org ccameron@chromium.org -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org - # If you're doing structural changes get a review from one of the OWNERS. per-file *.gyp*=* per-file BUILD.gn=*
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc index 2d50370..1ad03c8 100644 --- a/ui/aura/mus/window_port_mus.cc +++ b/ui/aura/mus/window_port_mus.cc
@@ -271,8 +271,16 @@ void WindowPortMus::SetFrameSinkIdFromServer( const cc::FrameSinkId& frame_sink_id) { frame_sink_id_ = frame_sink_id; - if (!pending_compositor_frame_sink_request_.is_null()) + if (!pending_compositor_frame_sink_request_.is_null()) { + // TOP_LEVEL_IN_WM, and EMBED_IN_OWNER windows should not be requesting + // CompositorFrameSinks. + DCHECK_NE(WindowMusType::TOP_LEVEL_IN_WM, window_mus_type()); + DCHECK_NE(WindowMusType::EMBED_IN_OWNER, window_mus_type()); base::ResetAndReturn(&pending_compositor_frame_sink_request_).Run(); + } + // TODO(fsamuel): If the window type is TOP_LEVEL_IN_WM or EMBED_IN_OWNER then + // we should check if we have a cc::LocalSurfaeId ready as well. If we do, + // then we are ready to embed. } void WindowPortMus::SetSurfaceInfoFromServer(
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index 8cc1db0..5037dab 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -920,6 +920,16 @@ capture_synchronizer_->SetCaptureFromServer(new_capture_window); } +void WindowTreeClient::OnFrameSinkIdAllocated( + Id window_id, + const cc::FrameSinkId& frame_sink_id) { + WindowMus* window = GetWindowByServerId(window_id); + if (!window) + return; + + window->SetFrameSinkIdFromServer(frame_sink_id); +} + void WindowTreeClient::OnTopLevelCreated(uint32_t change_id, ui::mojom::WindowDataPtr data, int64_t display_id,
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h index 8c9c8098..130d90c 100644 --- a/ui/aura/mus/window_tree_client.h +++ b/ui/aura/mus/window_tree_client.h
@@ -319,6 +319,8 @@ void OnUnembed(Id window_id) override; void OnCaptureChanged(Id new_capture_window_id, Id old_capture_window_id) override; + void OnFrameSinkIdAllocated(Id window_id, + const cc::FrameSinkId& frame_sink_id) override; void OnTopLevelCreated(uint32_t change_id, ui::mojom::WindowDataPtr data, int64_t display_id,
diff --git a/ui/base/OWNERS b/ui/base/OWNERS index b6ad79f1..498d1734 100644 --- a/ui/base/OWNERS +++ b/ui/base/OWNERS
@@ -1,7 +1,3 @@ -per-file *.isolate=maruel@chromium.org -per-file *.isolate=tandrii@chromium.org -per-file *.isolate=vadimsh@chromium.org - per-file template_expressions*=dschuyler@chromium.org # If you're doing structural changes get a review from one of the ui/OWNERS.
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc index 60f0077..cef5c86 100644 --- a/ui/gfx/canvas.cc +++ b/ui/gfx/canvas.cc
@@ -29,25 +29,10 @@ namespace gfx { -namespace { - -sk_sp<cc::PaintSurface> CreateSurface(const Size& size, bool is_opaque) { - // SkSurface cannot be zero-sized, but clients of Canvas sometimes request - // that (and then later resize). - int width = std::max(size.width(), 1); - int height = std::max(size.height(), 1); - SkAlphaType alpha = is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; - SkImageInfo info = SkImageInfo::MakeN32(width, height, alpha); - return cc::PaintSurface::MakeRaster(info); -} - -} // namespace - Canvas::Canvas(const Size& size, float image_scale, bool is_opaque) : image_scale_(image_scale) { Size pixel_size = ScaleToCeiledSize(size, image_scale); - surface_ = CreateSurface(pixel_size, is_opaque); - canvas_ = surface_->getCanvas(); + canvas_ = CreateOwnedCanvas(pixel_size, is_opaque); #if !defined(USE_CAIRO) // skia::PlatformCanvas instances are initialized to 0 by Cairo, but @@ -61,9 +46,7 @@ } Canvas::Canvas() - : image_scale_(1.f), - surface_(CreateSurface({0, 0}, false)), - canvas_(surface_->getCanvas()) {} + : image_scale_(1.f), canvas_(CreateOwnedCanvas({0, 0}, false)) {} Canvas::Canvas(cc::PaintCanvas* canvas, float image_scale) : image_scale_(image_scale), canvas_(canvas) { @@ -78,8 +61,7 @@ bool is_opaque) { image_scale_ = image_scale; Size pixel_size = ScaleToFlooredSize(size, image_scale); - surface_ = CreateSurface(pixel_size, is_opaque); - canvas_ = surface_->getCanvas(); + canvas_ = CreateOwnedCanvas(pixel_size, is_opaque); SkScalar scale_scalar = SkFloatToScalar(image_scale); canvas_->scale(scale_scalar, scale_scalar); @@ -558,10 +540,16 @@ canvas_->concat(transform.matrix()); } -SkBitmap Canvas::ToBitmap() { - SkBitmap bitmap; - bitmap.setInfo(canvas_->imageInfo()); - canvas_->readPixels(&bitmap, 0, 0); +SkBitmap Canvas::GetBitmap() const { + DCHECK(bitmap_); + SkBitmap bitmap = bitmap_.value(); + // When the bitmap is copied, it shares the underlying pixelref, but doesn't + // initialize pixels unless they are locked. Hence, ensure that the returned + // bitmap keeps the pixelref alive by locking it. Note that the dtor of + // SkBitmap will unlock the pixelrefs, so this won't leak. Also note that + // moving SkBitmap retains the same lock as the source, so the caller + // will receive a locked-pixels bitmap. + bitmap.lockPixels(); return bitmap; } @@ -619,4 +607,21 @@ canvas_->drawRect(dest_rect, flags); } +cc::PaintCanvas* Canvas::CreateOwnedCanvas(const Size& size, bool is_opaque) { + // SkBitmap cannot be zero-sized, but clients of Canvas sometimes request + // that (and then later resize). + int width = std::max(size.width(), 1); + int height = std::max(size.height(), 1); + SkAlphaType alpha = is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; + SkImageInfo info = SkImageInfo::MakeN32(width, height, alpha); + + bitmap_.emplace(); + bitmap_->allocPixels(info); + // Ensure that the bitmap is zeroed, since the code expects that. + memset(bitmap_->getPixels(), 0, bitmap_->getSafeSize()); + + owned_canvas_ = cc::SkiaPaintCanvas(bitmap_.value()); + return &owned_canvas_.value(); +} + } // namespace gfx
diff --git a/ui/gfx/canvas.h b/ui/gfx/canvas.h index 4fcb4bc..27c9751 100644 --- a/ui/gfx/canvas.h +++ b/ui/gfx/canvas.h
@@ -11,10 +11,11 @@ #include <vector> #include "base/macros.h" +#include "base/optional.h" #include "base/strings/string16.h" #include "cc/paint/paint_canvas.h" #include "cc/paint/paint_flags.h" -#include "cc/paint/paint_surface.h" +#include "cc/paint/skia_paint_canvas.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/text_constants.h" @@ -471,7 +472,8 @@ const Rect& display_rect, int flags); - SkBitmap ToBitmap(); + // Note that writing to this bitmap will modify pixels stored in this canvas. + SkBitmap GetBitmap() const; // TODO(enne): rename sk_canvas members and interface. cc::PaintCanvas* sk_canvas() { return canvas_; } @@ -496,6 +498,7 @@ bool filter, const cc::PaintFlags& flags, bool remove_image_scale); + cc::PaintCanvas* CreateOwnedCanvas(const Size& size, bool is_opaque); // The device scale factor at which drawing on this canvas occurs. // An additional scale can be applied via Canvas::Scale(). However, @@ -503,10 +506,11 @@ float image_scale_; // canvas_ is our active canvas object. Sometimes we are also the owner, - // in which case surface_ will be set. Other times we are just - // borrowing someone else's canvas, in which case canvas_ will point there - // but surface_ will be null. - sk_sp<cc::PaintSurface> surface_; + // in which case bitmap_ and owned_canvas_ will be set. Other times we are + // just borrowing someone else's canvas, in which case canvas_ will point + // there but bitmap_ and owned_canvas_ will not exist. + base::Optional<SkBitmap> bitmap_; + base::Optional<cc::SkiaPaintCanvas> owned_canvas_; cc::PaintCanvas* canvas_; DISALLOW_COPY_AND_ASSIGN(Canvas);
diff --git a/ui/gfx/canvas_paint_mac.mm b/ui/gfx/canvas_paint_mac.mm index ab7dda21..6123d915 100644 --- a/ui/gfx/canvas_paint_mac.mm +++ b/ui/gfx/canvas_paint_mac.mm
@@ -23,20 +23,11 @@ CanvasSkiaPaint::~CanvasSkiaPaint() { if (!is_empty()) { - cc::PaintCanvas* canvas = sk_canvas(); - canvas->restoreToCount(1); + sk_canvas()->restoreToCount(1); // Blit the dirty rect to the current context. - SkPixmap pixmap; - // TODO(enne): make this class record directly into a bitmap and - // remove this peekPixels call. - bool success = canvas->peekPixels(&pixmap); - DCHECK(success); - SkBitmap bitmap; - success = bitmap.installPixels(pixmap); - DCHECK(success); CGImageRef image = SkCreateCGImageRefWithColorspace( - bitmap, base::mac::GetSystemColorSpace()); + GetBitmap(), base::mac::GetSystemColorSpace()); CGRect dest_rect = NSRectToCGRect(rectangle_); CGContextRef destination_context =
diff --git a/ui/gfx/color_analysis_unittest.cc b/ui/gfx/color_analysis_unittest.cc index 929d01d..32444db 100644 --- a/ui/gfx/color_analysis_unittest.cc +++ b/ui/gfx/color_analysis_unittest.cc
@@ -345,7 +345,7 @@ canvas.FillRect(gfx::Rect(150, 0, 50, 200), SkColorSetRGB(0, 100, 100)); canvas.FillRect(gfx::Rect(200, 0, 50, 200), SkColorSetRGB(0, 0, 100)); - gfx::Matrix3F covariance = ComputeColorCovariance(canvas.ToBitmap()); + gfx::Matrix3F covariance = ComputeColorCovariance(canvas.GetBitmap()); gfx::Matrix3F expected_covariance = gfx::Matrix3F::Zeros(); expected_covariance.set(2400, 400, -1600, @@ -402,7 +402,7 @@ // The image consists of vertical non-overlapping stripes 150 pixels wide. canvas.FillRect(gfx::Rect(0, 0, 150, 200), SkColorSetRGB(0, 0, 0)); canvas.FillRect(gfx::Rect(150, 0, 150, 200), SkColorSetRGB(255, 255, 255)); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap result; result.allocPixels(SkImageInfo::MakeA8(300, 200)); @@ -439,7 +439,7 @@ canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(100, 0, 0)); canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(0, 255, 0)); canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(0, 0, 128)); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap result; result.allocPixels(SkImageInfo::MakeA8(300, 200)); @@ -481,7 +481,7 @@ canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(10, 10, 10)); canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(100, 100, 100)); canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(255, 255, 255)); - SkBitmap source = canvas.ToBitmap(); + SkBitmap source = canvas.GetBitmap(); SkBitmap result; result.allocPixels(SkImageInfo::MakeA8(300, 200)); @@ -514,7 +514,7 @@ // close to black. gfx::Canvas canvas(gfx::Size(300, 200), 1.0f, true); canvas.FillRect(gfx::Rect(0, 0, 300, 200), SkColorSetRGB(10, 10, 10)); - SkBitmap bitmap = canvas.ToBitmap(); + SkBitmap bitmap = canvas.GetBitmap(); // All expectations start at SK_ColorTRANSPARENT (i.e. 0). SkColor expectations[arraysize(color_profiles)] = {}; @@ -527,7 +527,7 @@ // Add a green that could hit a couple values. const SkColor kVibrantGreen = SkColorSetRGB(25, 200, 25); canvas.FillRect(gfx::Rect(0, 1, 300, 1), kVibrantGreen); - bitmap = canvas.ToBitmap(); + bitmap = canvas.GetBitmap(); expectations[0] = kVibrantGreen; expectations[1] = kVibrantGreen; for (size_t i = 0; i < arraysize(color_profiles); ++i) { @@ -539,7 +539,7 @@ // Add a stripe of a dark, muted green (saturation .33, luma .29). const SkColor kDarkGreen = SkColorSetRGB(50, 100, 50); canvas.FillRect(gfx::Rect(0, 2, 300, 1), kDarkGreen); - bitmap = canvas.ToBitmap(); + bitmap = canvas.GetBitmap(); expectations[3] = kDarkGreen; for (size_t i = 0; i < arraysize(color_profiles); ++i) { EXPECT_EQ(expectations[i], @@ -551,7 +551,7 @@ // normal vibrant, but is out of range for other color profiles. const SkColor kPureGreen = SkColorSetRGB(0, 255, 0); canvas.FillRect(gfx::Rect(0, 3, 300, 1), kPureGreen); - bitmap = canvas.ToBitmap(); + bitmap = canvas.GetBitmap(); expectations[1] = kPureGreen; for (size_t i = 0; i < arraysize(color_profiles); ++i) { EXPECT_EQ(expectations[i],
diff --git a/ui/gfx/color_utils_unittest.cc b/ui/gfx/color_utils_unittest.cc index 3870dd3..fcba64c0 100644 --- a/ui/gfx/color_utils_unittest.cc +++ b/ui/gfx/color_utils_unittest.cc
@@ -128,7 +128,7 @@ // Fill all pixels in black. canvas.FillRect(gfx::Rect(kSize), SK_ColorBLACK); - SkBitmap bitmap = canvas.ToBitmap(); + SkBitmap bitmap = canvas.GetBitmap(); // The thumbnail should deserve the highest boring score. EXPECT_DOUBLE_EQ(1.0, CalculateBoringScore(bitmap)); } @@ -143,7 +143,7 @@ canvas.FillRect(gfx::Rect(0, 0, kSize.width() / 2, kSize.height()), SK_ColorWHITE); - SkBitmap bitmap = canvas.ToBitmap(); + SkBitmap bitmap = canvas.GetBitmap(); ASSERT_EQ(kSize.width(), bitmap.width()); ASSERT_EQ(kSize.height(), bitmap.height()); // The thumbnail should be less boring because two colors are used.
diff --git a/ui/gfx/nine_image_painter_unittest.cc b/ui/gfx/nine_image_painter_unittest.cc index 954f97a..1cf8506 100644 --- a/ui/gfx/nine_image_painter_unittest.cc +++ b/ui/gfx/nine_image_painter_unittest.cc
@@ -85,7 +85,7 @@ gfx::Rect bounds(0, 0, 50, 50); painter.Paint(&canvas, bounds); - SkBitmap result = canvas.ToBitmap(); + SkBitmap result = canvas.GetBitmap(); gfx::Vector2d paint_offset = gfx::ToFlooredVector2d(gfx::ScaleVector2d(offset, image_scale)); @@ -116,7 +116,7 @@ gfx::Rect bounds(1, 1, 1, 1); painter.Paint(&canvas, bounds); - SkBitmap result = canvas.ToBitmap(); + SkBitmap result = canvas.GetBitmap(); EXPECT_EQ(SK_ColorGREEN, result.getColor(1, 1)); @@ -146,7 +146,7 @@ gfx::Rect bounds(1, 1, 10, 10); painter.Paint(&canvas, bounds); - SkBitmap result = canvas.ToBitmap(); + SkBitmap result = canvas.GetBitmap(); SkIRect green_rect = SkIRect::MakeLTRB(2, 2, 10, 10); for (int y = 1; y < 10; y++) { @@ -182,7 +182,7 @@ gfx::Rect bounds(0, 0, 50, 50); painter.Paint(&canvas, bounds); - SkBitmap result = canvas.ToBitmap(); + SkBitmap result = canvas.GetBitmap(); gfx::Vector2d paint_offset = gfx::ToFlooredVector2d(gfx::ScaleVector2d(offset, image_scale)); @@ -211,7 +211,7 @@ gfx::Rect bounds(0, 0, 50, 50); painter.Paint(&canvas, bounds); - SkBitmap result = canvas.ToBitmap(); + SkBitmap result = canvas.GetBitmap(); // The painting space is 50x50 and the scale of -1,-1 means an offset of 50,50 // would put the output in the top left corner. Since the offset is 70,60 it
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index ca8677a..dfd21118 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc
@@ -3798,15 +3798,17 @@ const Size kCanvasSize(300, 50); const int kTestSize = 10; - sk_sp<cc::PaintSurface> surface = cc::PaintSurface::MakeRasterN32Premul( - kCanvasSize.width(), kCanvasSize.height()); - Canvas canvas(surface->getCanvas(), 1.0f); + SkBitmap bitmap; + bitmap.allocPixels( + SkImageInfo::MakeN32Premul(kCanvasSize.width(), kCanvasSize.height())); + cc::SkiaPaintCanvas paint_canvas(bitmap); + Canvas canvas(&paint_canvas, 1.0f); RenderText* render_text = GetRenderText(); render_text->SetHorizontalAlignment(ALIGN_LEFT); render_text->SetColor(SK_ColorBLACK); for (auto* string : kTestStrings) { - surface->getCanvas()->clear(SK_ColorWHITE); + paint_canvas.clear(SK_ColorWHITE); render_text->SetText(WideToUTF16(string)); const Size string_size = render_text->GetStringSize(); render_text->ApplyBaselineStyle(SUPERSCRIPT, Range(1, 2)); @@ -3822,9 +3824,7 @@ render_text->Draw(&canvas); ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); - SkPixmap pixmap; - surface->getCanvas()->peekPixels(&pixmap); - const uint32_t* buffer = static_cast<const uint32_t*>(pixmap.addr()); + const uint32_t* buffer = static_cast<const uint32_t*>(bitmap.getPixels()); ASSERT_NE(nullptr, buffer); TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), kCanvasSize.height()); @@ -3891,15 +3891,17 @@ const Size kCanvasSize(300, 50); const int kTestSize = 10; - sk_sp<cc::PaintSurface> surface = cc::PaintSurface::MakeRasterN32Premul( - kCanvasSize.width(), kCanvasSize.height()); - Canvas canvas(surface->getCanvas(), 1.0f); + SkBitmap bitmap; + bitmap.allocPixels( + SkImageInfo::MakeN32Premul(kCanvasSize.width(), kCanvasSize.height())); + cc::SkiaPaintCanvas paint_canvas(bitmap); + Canvas canvas(&paint_canvas, 1.0f); RenderText* render_text = GetRenderText(); render_text->SetHorizontalAlignment(ALIGN_LEFT); render_text->SetColor(SK_ColorBLACK); for (auto* string : kTestStrings) { - surface->getCanvas()->clear(SK_ColorWHITE); + paint_canvas.clear(SK_ColorWHITE); render_text->SetText(WideToUTF16(string)); const Size string_size = render_text->GetStringSize(); int fake_width = string_size.width() / 2; @@ -3909,9 +3911,7 @@ render_text->set_clip_to_display_rect(true); render_text->Draw(&canvas); ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); - SkPixmap pixmap; - surface->getCanvas()->peekPixels(&pixmap); - const uint32_t* buffer = static_cast<const uint32_t*>(pixmap.addr()); + const uint32_t* buffer = static_cast<const uint32_t*>(bitmap.getPixels()); ASSERT_NE(nullptr, buffer); TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), kCanvasSize.height());