diff --git a/DEPS b/DEPS index 3ce20e0e..9c94833 100644 --- a/DEPS +++ b/DEPS
@@ -44,7 +44,7 @@ # 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': '2937ab856e912e5c103bf13e7cdd1255d78a4cff', + 'v8_revision': 'c2d2c94fd4960b69e0ea915b9e862f16bea778cb', # 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. @@ -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': '64ca2b5ad4d43754240682ba97b164dd72dad794', + 'catapult_revision': 'b0acf6c12b290c7dcbb54b389f7120c580a8e39a', # 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/PRESUBMIT.py b/PRESUBMIT.py index fc07745..0a1d129 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -2134,8 +2134,9 @@ def _CheckBuildConfigMacrosWithoutInclude(input_api, output_api): - macro_re = input_api.re.compile( - r'^\s*#(el)?if.*\bdefined\(((OS_|COMPILER_|ARCH_CPU_|WCHAR_T_IS_)[^)]*)') + # Excludes OS_CHROMEOS, which is not defined in build_config.h. + macro_re = input_api.re.compile(r'^\s*#(el)?if.*\bdefined\(((OS_(?!CHROMEOS)|' + 'COMPILER_|ARCH_CPU_|WCHAR_T_IS_)[^)]*)') include_re = input_api.re.compile( r'^#include\s+"build/build_config.h"', input_api.re.MULTILINE) extension_re = input_api.re.compile(r'\.[a-z]+$')
diff --git a/android_webview/browser/aw_render_thread_context_provider.cc b/android_webview/browser/aw_render_thread_context_provider.cc index a3ed6c8d..f89de782 100644 --- a/android_webview/browser/aw_render_thread_context_provider.cc +++ b/android_webview/browser/aw_render_thread_context_provider.cc
@@ -9,8 +9,8 @@ #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/trace_event/trace_event.h" -#include "cc/output/context_cache_controller.h" #include "cc/output/managed_memory_policy.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/client/gles2_lib.h" #include "gpu/command_buffer/client/gles2_trace_implementation.h" @@ -81,7 +81,7 @@ } cache_controller_.reset( - new cc::ContextCacheController(context_->GetImplementation(), nullptr)); + new viz::ContextCacheController(context_->GetImplementation(), nullptr)); } AwRenderThreadContextProvider::~AwRenderThreadContextProvider() { @@ -135,7 +135,7 @@ return gr_context_.get(); } -cc::ContextCacheController* AwRenderThreadContextProvider::CacheController() { +viz::ContextCacheController* AwRenderThreadContextProvider::CacheController() { DCHECK(main_thread_checker_.CalledOnValidThread()); return cache_controller_.get(); }
diff --git a/android_webview/browser/aw_render_thread_context_provider.h b/android_webview/browser/aw_render_thread_context_provider.h index 44301a31..ca2589c5 100644 --- a/android_webview/browser/aw_render_thread_context_provider.h +++ b/android_webview/browser/aw_render_thread_context_provider.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/threading/thread_checker.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/ipc/in_process_command_buffer.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/gpu/GrContext.h" @@ -29,7 +29,7 @@ namespace android_webview { -class AwRenderThreadContextProvider : public cc::ContextProvider { +class AwRenderThreadContextProvider : public viz::ContextProvider { public: static scoped_refptr<AwRenderThreadContextProvider> Create( scoped_refptr<gl::GLSurface> surface, @@ -45,13 +45,13 @@ scoped_refptr<gpu::InProcessCommandBuffer::Service> service); ~AwRenderThreadContextProvider() override; - // cc::ContextProvider: + // viz::ContextProvider: bool BindToCurrentThread() override; gpu::Capabilities ContextCapabilities() override; gpu::gles2::GLES2Interface* ContextGL() override; gpu::ContextSupport* ContextSupport() override; class GrContext* GrContext() override; - cc::ContextCacheController* CacheController() override; + viz::ContextCacheController* CacheController() override; void InvalidateGrContext(uint32_t state) override; base::Lock* GetLock() override; void SetLostContextCallback( @@ -64,7 +64,7 @@ std::unique_ptr<gpu::GLInProcessContext> context_; std::unique_ptr<gpu::gles2::GLES2TraceImplementation> trace_impl_; sk_sp<class GrContext> gr_context_; - std::unique_ptr<cc::ContextCacheController> cache_controller_; + std::unique_ptr<viz::ContextCacheController> cache_controller_; LostContextCallback lost_context_callback_;
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index 46029ea4..f4ad8144 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc
@@ -33,7 +33,8 @@ last_committed_layer_tree_frame_sink_id_(0u), last_submitted_layer_tree_frame_sink_id_(0u) { DCHECK(last_egl_context_); - surfaces_->GetFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_); + surfaces_->GetFrameSinkManager()->surface_manager()->RegisterFrameSinkId( + frame_sink_id_); CreateNewCompositorFrameSinkSupport(); } @@ -43,7 +44,8 @@ if (child_id_.is_valid()) DestroySurface(); support_.reset(); - surfaces_->GetFrameSinkManager()->InvalidateFrameSinkId(frame_sink_id_); + surfaces_->GetFrameSinkManager()->surface_manager()->InvalidateFrameSinkId( + frame_sink_id_); // Reset draw constraints. render_thread_manager_->PostExternalDrawConstraintsToChildCompositorOnRT(
diff --git a/ash/laser/DEPS b/ash/laser/DEPS index 89980df..c592c5d 100644 --- a/ash/laser/DEPS +++ b/ash/laser/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+cc", + "+components/viz/common/gpu", "+components/viz/common/quads", "+gpu/command_buffer/client", ]
diff --git a/ash/laser/laser_pointer_view.cc b/ash/laser/laser_pointer_view.cc index 784f10c..b46de05 100644 --- a/ash/laser/laser_pointer_view.cc +++ b/ash/laser/laser_pointer_view.cc
@@ -22,11 +22,11 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "cc/output/compositor_frame.h" -#include "cc/output/context_provider.h" #include "cc/output/layer_tree_frame_sink.h" #include "cc/output/layer_tree_frame_sink_client.h" #include "cc/quads/texture_draw_quad.h" #include "cc/resources/transferable_resource.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/quads/resource_format.h" #include "components/viz/common/quads/texture_mailbox.h" #include "gpu/command_buffer/client/context_support.h" @@ -240,7 +240,7 @@ gles2->DestroyImageCHROMIUM(image); } } - scoped_refptr<cc::ContextProvider> context_provider; + scoped_refptr<viz::ContextProvider> context_provider; uint32_t texture = 0; uint32_t image = 0; gpu::Mailbox mailbox;
diff --git a/ash/test/ash_test_suite.cc b/ash/test/ash_test_suite.cc index 76c38033..56e5c8b0 100644 --- a/ash/test/ash_test_suite.cc +++ b/ash/test/ash_test_suite.cc
@@ -32,11 +32,12 @@ class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient { public: explicit FrameSinkClient( - scoped_refptr<cc::ContextProvider> display_context_provider) + scoped_refptr<viz::ContextProvider> display_context_provider) : display_context_provider_(std::move(display_context_provider)) {} std::unique_ptr<cc::OutputSurface> CreateDisplayOutputSurface( - scoped_refptr<cc::ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { return cc::FakeOutputSurface::Create3d( std::move(display_context_provider_)); } @@ -51,7 +52,7 @@ void DisplayDidDrawAndSwap() override {} private: - scoped_refptr<cc::ContextProvider> display_context_provider_; + scoped_refptr<viz::ContextProvider> display_context_provider_; DISALLOW_COPY_AND_ASSIGN(FrameSinkClient); };
diff --git a/base/message_loop/message_pump_fuchsia.cc b/base/message_loop/message_pump_fuchsia.cc index ffb0dc0..110268f 100644 --- a/base/message_loop/message_pump_fuchsia.cc +++ b/base/message_loop/message_pump_fuchsia.cc
@@ -28,22 +28,23 @@ } bool MessagePumpFuchsia::FileDescriptorWatcher::StopWatchingFileDescriptor() { - if (handle_ == MX_HANDLE_INVALID) + if (!weak_pump_ || handle_ == MX_HANDLE_INVALID) return true; - uint64_t this_as_key = - static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this)); - int result = mx_port_cancel(port_, handle_, this_as_key); + + int result = mx_port_cancel(weak_pump_->port_, handle_, wait_key()); DLOG_IF(ERROR, result != MX_OK) << "mx_port_cancel(handle=" << handle_ << ") failed: " << mx_status_get_string(result); handle_ = MX_HANDLE_INVALID; + return result == MX_OK; } -MessagePumpFuchsia::MessagePumpFuchsia() : keep_running_(true) { +MessagePumpFuchsia::MessagePumpFuchsia() + : keep_running_(true), weak_factory_(this) { // TODO(wez): Remove MX_PORT_OPT_V2 once the SDK is rolled, or migrate // this implementation use ulib/port helpers. - CHECK(mx_port_create(MX_PORT_OPT_V2, &port_) == MX_OK); + CHECK_EQ(0, mx_port_create(MX_PORT_OPT_V2, &port_)); } MessagePumpFuchsia::~MessagePumpFuchsia() { @@ -61,8 +62,10 @@ DCHECK_GE(fd, 0); DCHECK(controller); DCHECK(delegate); + + controller->fd_ = fd; + controller->persistent_ = persistent; controller->watcher_ = delegate; - controller->port_ = port_; uint32_t events = 0; switch (mode) { @@ -79,7 +82,6 @@ NOTREACHED() << "unexpected mode: " << mode; return false; } - controller->desired_events_ = events; controller->io_ = __mxio_fd_to_io(fd); @@ -88,8 +90,7 @@ return false; } - controller->fd_ = fd; - controller->persistent_ = persistent; + controller->weak_pump_ = weak_factory_.GetWeakPtr(); return controller->WaitBegin(); } @@ -102,13 +103,12 @@ return false; } - uint64_t this_as_key = - static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this)); - mx_status_t status = mx_object_wait_async(handle_, port_, this_as_key, - signals, MX_WAIT_ASYNC_ONCE); + mx_status_t status = mx_object_wait_async( + handle_, weak_pump_->port_, wait_key(), signals, MX_WAIT_ASYNC_ONCE); if (status != MX_OK) { DLOG(ERROR) << "mx_object_wait_async failed: " - << mx_status_get_string(status) << " (port=" << port_ << ")"; + << mx_status_get_string(status) + << " (port=" << weak_pump_->port_ << ")"; return false; } return true;
diff --git a/base/message_loop/message_pump_fuchsia.h b/base/message_loop/message_pump_fuchsia.h index fec4ab5..001de34 100644 --- a/base/message_loop/message_pump_fuchsia.h +++ b/base/message_loop/message_pump_fuchsia.h
@@ -8,6 +8,7 @@ #include "base/base_export.h" #include "base/location.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/message_loop/message_pump.h" #include <magenta/syscalls/port.h> @@ -44,6 +45,8 @@ } private: + friend class MessagePumpFuchsia; + // Start watching the FD. bool WaitBegin(); @@ -51,13 +54,15 @@ // in based on the observed bits from the underlying packet. uint32_t WaitEnd(uint32_t observed); - friend class MessagePumpFuchsia; + // Returns the key to use to uniquely identify this object's wait operation. + uint64_t wait_key() const { + return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this)); + } const tracked_objects::Location created_from_location_; // Set directly from the inputs to WatchFileDescriptor. Watcher* watcher_ = nullptr; - mx_handle_t port_ = MX_HANDLE_INVALID; int fd_ = -1; uint32_t desired_events_ = 0; @@ -68,6 +73,9 @@ // WaitBegin and WaitEnd calls), and MX_HANDLE_INVALID otherwise. mx_handle_t handle_ = MX_HANDLE_INVALID; + // Used to safely access resources owned by the associated message pump. + WeakPtr<MessagePumpFuchsia> weak_pump_; + // This bool is used during calling |Watcher| callbacks. This object's // lifetime is owned by the user of this class. If the message loop is woken // up in the case where it needs to call both the readable and writable @@ -113,6 +121,8 @@ // The time at which we should call DoDelayedWork. TimeTicks delayed_work_time_; + base::WeakPtrFactory<MessagePumpFuchsia> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(MessagePumpFuchsia); };
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc index ac6c9aa..1266d826 100644 --- a/base/metrics/histogram.cc +++ b/base/metrics/histogram.cc
@@ -9,6 +9,7 @@ #include "base/metrics/histogram.h" +#include <inttypes.h> #include <limits.h> #include <math.h> @@ -18,6 +19,7 @@ #include "base/compiler_specific.h" #include "base/debug/alias.h" +#include "base/debug/crash_logging.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" @@ -31,6 +33,7 @@ #include "base/strings/stringprintf.h" #include "base/synchronization/lock.h" #include "base/values.h" +#include "build/build_config.h" namespace base { @@ -554,9 +557,16 @@ bad_fields |= 1 << kFlagsField; // Abort if a problem is found (except "flags", which could legally be zero). - CHECK_EQ(0U, bad_fields & ~(1 << kFlagsField)) - << histogram_name() << ": " << bad_fields; - debug::Alias(&bad_fields); + if ((bad_fields & ~(1 << kFlagsField)) != 0) { + const std::string debug_string = + base::StringPrintf("%s/%" PRIu32, histogram_name().c_str(), bad_fields); +#if !defined(OS_NACL) + // Temporary for https://crbug.com/736675. + base::debug::ScopedCrashKey crash_key("bad_histogram", debug_string); +#endif + CHECK(false) << debug_string; + debug::Alias(&bad_fields); + } } bool Histogram::SerializeInfoImpl(Pickle* pickle) const {
diff --git a/base/numerics/checked_math.h b/base/numerics/checked_math.h index 1f8ea9d..66a2e5d 100644 --- a/base/numerics/checked_math.h +++ b/base/numerics/checked_math.h
@@ -129,12 +129,18 @@ CheckedNumeric& operator^=(const Src rhs); constexpr CheckedNumeric operator-() const { - return CheckedNumeric<T>( - NegateWrapper(state_.value()), - IsValid() && - (!std::is_signed<T>::value || std::is_floating_point<T>::value || - NegateWrapper(state_.value()) != - std::numeric_limits<T>::lowest())); + // The negation of two's complement int min is int min, so we simply + // check for that in the constexpr case. + // We use an optimized code path for a known run-time variable. + return MustTreatAsConstexpr(state_.value()) || !std::is_signed<T>::value || + std::is_floating_point<T>::value + ? CheckedNumeric<T>( + NegateWrapper(state_.value()), + IsValid() && (!std::is_signed<T>::value || + std::is_floating_point<T>::value || + NegateWrapper(state_.value()) != + std::numeric_limits<T>::lowest())) + : FastRuntimeNegate(); } constexpr CheckedNumeric operator~() const { @@ -143,11 +149,7 @@ } constexpr CheckedNumeric Abs() const { - return CheckedNumeric<T>( - AbsWrapper(state_.value()), - IsValid() && - (!std::is_signed<T>::value || std::is_floating_point<T>::value || - AbsWrapper(state_.value()) != std::numeric_limits<T>::lowest())); + return !IsValueNegative(state_.value()) ? *this : -*this; } template <typename U> @@ -239,6 +241,12 @@ private: CheckedNumericState<T> state_; + CheckedNumeric FastRuntimeNegate() const { + T result; + bool success = CheckedSubOp<T, T>::Do(T(0), state_.value(), &result); + return CheckedNumeric<T>(result, IsValid() && success); + } + template <typename Src> constexpr CheckedNumeric(Src value, bool is_valid) : state_(value, is_valid) {}
diff --git a/base/numerics/clamped_math.h b/base/numerics/clamped_math.h index d4ffa3e..0ef1285 100644 --- a/base/numerics/clamped_math.h +++ b/base/numerics/clamped_math.h
@@ -79,11 +79,11 @@ constexpr ClampedNumeric operator-() const { return ClampedNumeric<T>( - // The negation of two's complement int min is int min, so that's the - // only overflow case we have to check for. And in the case of a - // run-time variable value_, we can use an optimized code path. + // The negation of two's complement int min is int min, so we can + // check and just add one to prevent overflow in the constexpr case. + // We use an optimized code path for a known run-time variable. std::is_signed<T>::value - ? (IsCompileTimeConstant(value_) + ? (MustTreatAsConstexpr(value_) ? ((std::is_floating_point<T>::value || NegateWrapper(value_) != std::numeric_limits<T>::lowest()) @@ -98,13 +98,9 @@ } constexpr ClampedNumeric Abs() const { - return ClampedNumeric<T>( - // The negation of two's complement int min is int min, so that's the - // only overflow case we have to check for. - (!std::is_signed<T>::value || std::is_floating_point<T>::value || - AbsWrapper(value_) != std::numeric_limits<T>::lowest()) - ? AbsWrapper(value_) - : std::numeric_limits<T>::max()); + // The negation of two's complement int min is int min, so that's the + // only overflow case where we will saturate. + return ClampedNumeric<T>(SaturatedAbsWrapper(value_)); } template <typename U>
diff --git a/base/numerics/clamped_math_impl.h b/base/numerics/clamped_math_impl.h index cbd96cb..a429b29 100644 --- a/base/numerics/clamped_math_impl.h +++ b/base/numerics/clamped_math_impl.h
@@ -21,6 +21,30 @@ namespace base { namespace internal { +template <typename T, + typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> +constexpr T SaturatedAbsWrapper(T value) { + // The calculation below is a static identity for unsigned types, but for + // signed integer types it provides a non-branching, saturated absolute value. + // This works because SafeUnsignedAbs() returns an unsigned type, which can + // represent the absolute value of all negative numbers of an equal-width + // integer type. The call to IsValueNegative() then detects overflow in the + // special case of numeric_limits<T>::min(), by evaluating the bit pattern as + // a signed integer value. If it is the overflow case, we end up subtracting + // one from the unsigned result, thus saturating to numeric_limits<T>::max(). + return MustTreatAsConstexpr(value) && !ClampedAbsFastOp<T>::is_supported + ? static_cast<T>(SafeUnsignedAbs(value) - + IsValueNegative<T>(SafeUnsignedAbs(value))) + : ClampedAbsFastOp<T>::Do(value); +} + +template < + typename T, + typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr> +constexpr T SaturatedAbsWrapper(T value) { + return value < 0 ? -value : value; +} + template <typename T, typename U, class Enable = void> struct ClampedAddOp {};
diff --git a/base/numerics/safe_conversions_impl.h b/base/numerics/safe_conversions_impl.h index 46234005..fe03f28 100644 --- a/base/numerics/safe_conversions_impl.h +++ b/base/numerics/safe_conversions_impl.h
@@ -76,15 +76,29 @@ : static_cast<UnsignedT>(value); } -// This provides a small optimization that generates more compact code when one -// of the components in an operation is a compile-time constant. +// This allows us to switch paths on known compile-time constants. +#if defined(__clang__) || defined(__GNUC__) +constexpr bool CanDetectCompileTimeConstant() { + return true; +} template <typename T> constexpr bool IsCompileTimeConstant(const T v) { -#if defined(__clang__) || defined(__GNUC__) return __builtin_constant_p(v); +} #else +constexpr bool CanDetectCompileTimeConstant() { return false; +} +template <typename T> +constexpr bool IsCompileTimeConstant(const T v) { + return false; +} #endif +template <typename T> +constexpr bool MustTreatAsConstexpr(const T v) { + // Either we can't detect a compile-time constant, and must always use the + // constexpr path, or we know we have a compile-time constant. + return !CanDetectCompileTimeConstant() || IsCompileTimeConstant(v); } // Forces a crash, like a CHECK(false). Used for numeric boundary errors.
diff --git a/base/numerics/safe_math_clang_gcc_impl.h b/base/numerics/safe_math_clang_gcc_impl.h index a08534ba..fbedea4 100644 --- a/base/numerics/safe_math_clang_gcc_impl.h +++ b/base/numerics/safe_math_clang_gcc_impl.h
@@ -216,6 +216,22 @@ } }; +template <typename T> +struct ClampedAbsFastOp { +// The generic code is pretty much optimal on arm, so we use it instead. +#if defined(__ARMEL__) || defined(__arch64__) + static const bool is_supported = false; +#else + static const bool is_supported = std::is_signed<T>::value; +#endif + static T Do(T value) { + // This variable assignment is necessary to prevent the compiler from + // emitting longer, ugly, branchy code. + T negated = ClampedSubFastOp<T, T>::template Do<T>(T(0), value); + return IsValueNegative(value) ? negated : value; + } +}; + } // namespace internal } // namespace base
diff --git a/base/numerics/safe_math_shared_impl.h b/base/numerics/safe_math_shared_impl.h index 603a7eb..99f230c 100644 --- a/base/numerics/safe_math_shared_impl.h +++ b/base/numerics/safe_math_shared_impl.h
@@ -94,6 +94,15 @@ return CheckOnFailure::template HandleFailure<V>(); } }; + +template <typename T> +struct ClampedAbsFastOp { + static const bool is_supported = false; + static constexpr T Do(T) { + // Force a compile failure if instantiated. + return CheckOnFailure::template HandleFailure<T>(); + } +}; #endif // BASE_HAS_OPTIMIZED_SAFE_MATH #undef BASE_HAS_OPTIMIZED_SAFE_MATH
diff --git a/base/task_scheduler/scheduler_worker.cc b/base/task_scheduler/scheduler_worker.cc index 07353443..26033d1b 100644 --- a/base/task_scheduler/scheduler_worker.cc +++ b/base/task_scheduler/scheduler_worker.cc
@@ -15,6 +15,7 @@ #if defined(OS_MACOSX) #include "base/mac/scoped_nsautorelease_pool.h" #elif defined(OS_WIN) +#include "base/win/com_init_check_hook.h" #include "base/win/scoped_com_initializer.h" #endif @@ -43,7 +44,10 @@ // A SchedulerWorker starts out waiting for work. outer_->delegate_->WaitForWork(&wake_up_event_); -#if defined(OS_WIN) + // When defined(COM_INIT_CHECK_HOOK_ENABLED), ignore + // SchedulerBackwardCompatibility::INIT_COM_STA to find incorrect uses of + // COM that should be running in a COM STA Task Runner. +#if defined(OS_WIN) && !defined(COM_INIT_CHECK_HOOK_ENABLED) std::unique_ptr<win::ScopedCOMInitializer> com_initializer; if (outer_->backward_compatibility_ == SchedulerBackwardCompatibility::INIT_COM_STA) {
diff --git a/base/task_scheduler/scheduler_worker_unittest.cc b/base/task_scheduler/scheduler_worker_unittest.cc index ab5982fb2..4d22f59 100644 --- a/base/task_scheduler/scheduler_worker_unittest.cc +++ b/base/task_scheduler/scheduler_worker_unittest.cc
@@ -30,6 +30,8 @@ #if defined(OS_WIN) #include <objbase.h> + +#include "base/win/com_init_check_hook.h" #endif using testing::_; @@ -931,7 +933,13 @@ // The call to CoInitializeEx() should have returned S_FALSE to indicate that // the COM library was already initialized on the thread. + // See SchedulerWorker::Thread::ThreadMain for why we expect two different + // results here. +#if defined(COM_INIT_CHECK_HOOK_ENABLED) + EXPECT_EQ(S_OK, delegate_raw->coinitialize_hresult()); +#else EXPECT_EQ(S_FALSE, delegate_raw->coinitialize_hresult()); +#endif worker->JoinForTesting(); }
diff --git a/build/android/apk_operations.py b/build/android/apk_operations.py index 5c4156cd..2599c79d 100755 --- a/build/android/apk_operations.py +++ b/build/android/apk_operations.py
@@ -38,13 +38,13 @@ from incremental_install import installer installer.Install(device, helper, split_globs=params['splits'], native_libs=params['native_libs'], - permissions=None) + dex_files=params['dex_files'], permissions=None) devices_obj.pMap(install_incremental_apk) - return - # Install the regular apk on devices. - def install(device): - device.Install(apk_to_install) - devices_obj.pMap(install) + else: + # Install the regular apk on devices. + def install(device): + device.Install(apk_to_install) + devices_obj.pMap(install) def _UninstallApk(install_incremental, devices_obj, apk_package): @@ -316,6 +316,7 @@ elif command == 'run': _InstallApk(install_incremental, inc_install_script, devices_obj, active_apk) + devices_obj.pFinish(None) _LaunchUrl(devices_obj, args.args, gn_args.command_line_flags_file, args.url, apk_package) elif command == 'stop': @@ -342,6 +343,8 @@ args = [adb_path, 'logcat'] os.execv(adb_path, args) + # Wait for all threads to finish. + devices_obj.pFinish(None) # Save back to the cache. if use_cache:
diff --git a/build/android/incremental_install/installer.py b/build/android/incremental_install/installer.py index a35cc93d1..54abf76 100755 --- a/build/android/incremental_install/installer.py +++ b/build/android/incremental_install/installer.py
@@ -128,8 +128,8 @@ # Push .so and .dex files to the device (if they have changed). def do_push_files(): + push_native_timer.Start() if native_libs: - push_native_timer.Start() with build_utils.TempDir() as temp_dir: device_lib_dir = posixpath.join(device_incremental_dir, 'lib') for path in native_libs: @@ -138,10 +138,10 @@ shutil.copy(path, os.path.join(temp_dir, os.path.basename(path))) device.PushChangedFiles([(temp_dir, device_lib_dir)], delete_device_stale=True) - push_native_timer.Stop(log=False) + push_native_timer.Stop(log=False) + push_dex_timer.Start() if dex_files: - push_dex_timer.Start() # Put all .dex files to be pushed into a temporary directory so that we # can use delete_device_stale=True. with build_utils.TempDir() as temp_dir: @@ -155,7 +155,7 @@ shutil.copy(src_path, os.path.join(temp_dir, dest_name)) device.PushChangedFiles([(temp_dir, device_dex_dir)], delete_device_stale=True) - push_dex_timer.Stop(log=False) + push_dex_timer.Stop(log=False) def check_selinux(): # Marshmallow has no filesystem access whatsoever. It might be possible to
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 29f538f..67a898b 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -148,10 +148,6 @@ "output/compositor_frame.h", "output/compositor_frame_metadata.cc", "output/compositor_frame_metadata.h", - "output/context_cache_controller.cc", - "output/context_cache_controller.h", - "output/context_provider.cc", - "output/context_provider.h", "output/copy_output_request.cc", "output/copy_output_request.h", "output/copy_output_result.cc", @@ -168,8 +164,6 @@ "output/gl_renderer.h", "output/gl_renderer_draw_cache.cc", "output/gl_renderer_draw_cache.h", - "output/in_process_context_provider.cc", - "output/in_process_context_provider.h", "output/latency_info_swap_promise.cc", "output/latency_info_swap_promise.h", "output/layer_quad.cc", @@ -838,7 +832,6 @@ "animation/scroll_offset_animation_curve_unittest.cc", "animation/transform_operations_unittest.cc", "surfaces/surface_hittest_unittest.cc", - "surfaces/surface_manager_ref_unittest.cc", "surfaces/surface_unittest.cc", # Setup.
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index f744ccf..12d9b364 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -161,7 +161,7 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture( DrawMode draw_mode, ResourceProvider* resource_provider, - ContextProvider* context_provider) { + viz::ContextProvider* context_provider) { if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE || !resources_.back()->id()) return;
diff --git a/cc/layers/heads_up_display_layer_impl.h b/cc/layers/heads_up_display_layer_impl.h index b9f6afcd..42af03f 100644 --- a/cc/layers/heads_up_display_layer_impl.h +++ b/cc/layers/heads_up_display_layer_impl.h
@@ -45,7 +45,7 @@ AppendQuadsData* append_quads_data) override; void UpdateHudTexture(DrawMode draw_mode, ResourceProvider* resource_provider, - ContextProvider* context_provider); + viz::ContextProvider* context_provider); void ReleaseResources() override;
diff --git a/cc/layers/heads_up_display_layer_impl_unittest.cc b/cc/layers/heads_up_display_layer_impl_unittest.cc index 94d3f13..dab961f 100644 --- a/cc/layers/heads_up_display_layer_impl_unittest.cc +++ b/cc/layers/heads_up_display_layer_impl_unittest.cc
@@ -18,7 +18,7 @@ void CheckDrawLayer(HeadsUpDisplayLayerImpl* layer, ResourceProvider* resource_provider, - ContextProvider* context_provider, + viz::ContextProvider* context_provider, DrawMode draw_mode) { std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data;
diff --git a/cc/layers/texture_layer_impl_unittest.cc b/cc/layers/texture_layer_impl_unittest.cc index 57689da..0dc3a8c 100644 --- a/cc/layers/texture_layer_impl_unittest.cc +++ b/cc/layers/texture_layer_impl_unittest.cc
@@ -6,12 +6,12 @@ #include <stddef.h> -#include "cc/output/context_provider.h" #include "cc/output/layer_tree_frame_sink.h" #include "cc/quads/draw_quad.h" #include "cc/quads/texture_draw_quad.h" #include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/layer_test_common.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 623ac76..cdbc20e 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -25,7 +25,6 @@ #include "cc/layers/solid_color_layer.h" #include "cc/layers/texture_layer_client.h" #include "cc/layers/texture_layer_impl.h" -#include "cc/output/context_provider.h" #include "cc/resources/returned_resource.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_frame_sink.h" @@ -40,6 +39,7 @@ #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/test/test_layer_tree_frame_sink.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" @@ -639,8 +639,8 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { constexpr bool disable_display_vsync = false; bool synchronous_composite = !HasImplThread() &&
diff --git a/cc/layers/video_layer_impl_unittest.cc b/cc/layers/video_layer_impl_unittest.cc index 8b62a69..7f0adc3d 100644 --- a/cc/layers/video_layer_impl_unittest.cc +++ b/cc/layers/video_layer_impl_unittest.cc
@@ -7,7 +7,6 @@ #include <stddef.h> #include "cc/layers/video_frame_provider_client_impl.h" -#include "cc/output/context_provider.h" #include "cc/output/output_surface.h" #include "cc/quads/draw_quad.h" #include "cc/quads/stream_video_draw_quad.h" @@ -16,6 +15,7 @@ #include "cc/test/fake_video_frame_provider.h" #include "cc/test/layer_test_common.h" #include "cc/trees/single_thread_proxy.h" +#include "components/viz/common/gpu/context_provider.h" #include "media/base/video_frame.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/cc/output/context_cache_controller_unittest.cc b/cc/output/context_cache_controller_unittest.cc index 35e1e25a..5f32ac3c 100644 --- a/cc/output/context_cache_controller_unittest.cc +++ b/cc/output/context_cache_controller_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/output/context_cache_controller.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "base/memory/ptr_util.h" #include "base/test/test_mock_time_task_runner.h" @@ -27,10 +27,10 @@ TEST(ContextCacheControllerTest, ScopedVisibilityBasic) { StrictMock<MockContextSupport> context_support; auto task_runner = make_scoped_refptr(new base::TestMockTimeTaskRunner); - ContextCacheController cache_controller(&context_support, task_runner); + viz::ContextCacheController cache_controller(&context_support, task_runner); EXPECT_CALL(context_support, SetAggressivelyFreeResources(false)); - std::unique_ptr<ContextCacheController::ScopedVisibility> visibility = + std::unique_ptr<viz::ContextCacheController::ScopedVisibility> visibility = cache_controller.ClientBecameVisible(); Mock::VerifyAndClearExpectations(&context_support); @@ -41,7 +41,7 @@ TEST(ContextCacheControllerTest, ScopedVisibilityMulti) { StrictMock<MockContextSupport> context_support; auto task_runner = make_scoped_refptr(new base::TestMockTimeTaskRunner); - ContextCacheController cache_controller(&context_support, task_runner); + viz::ContextCacheController cache_controller(&context_support, task_runner); EXPECT_CALL(context_support, SetAggressivelyFreeResources(false)); auto visibility_1 = cache_controller.ClientBecameVisible(); @@ -56,7 +56,7 @@ TEST(ContextCacheControllerTest, ScopedBusyWhileVisible) { StrictMock<MockContextSupport> context_support; auto task_runner = make_scoped_refptr(new base::TestMockTimeTaskRunner); - ContextCacheController cache_controller(&context_support, task_runner); + viz::ContextCacheController cache_controller(&context_support, task_runner); EXPECT_CALL(context_support, SetAggressivelyFreeResources(false)); auto visibility = cache_controller.ClientBecameVisible(); @@ -78,7 +78,7 @@ TEST(ContextCacheControllerTest, ScopedBusyWhileNotVisible) { StrictMock<MockContextSupport> context_support; auto task_runner = make_scoped_refptr(new base::TestMockTimeTaskRunner); - ContextCacheController cache_controller(&context_support, task_runner); + viz::ContextCacheController cache_controller(&context_support, task_runner); auto busy = cache_controller.ClientBecameBusy(); @@ -90,7 +90,7 @@ TEST(ContextCacheControllerTest, ScopedBusyMulitpleWhileVisible) { StrictMock<MockContextSupport> context_support; auto task_runner = make_scoped_refptr(new base::TestMockTimeTaskRunner); - ContextCacheController cache_controller(&context_support, task_runner); + viz::ContextCacheController cache_controller(&context_support, task_runner); EXPECT_CALL(context_support, SetAggressivelyFreeResources(false)); auto visible = cache_controller.ClientBecameVisible();
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 0aaefe88..8d5dfaa 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc
@@ -31,7 +31,6 @@ #include "cc/debug/debug_colors.h" #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_metadata.h" -#include "cc/output/context_provider.h" #include "cc/output/copy_output_request.h" #include "cc/output/dynamic_geometry_binding.h" #include "cc/output/layer_quad.h" @@ -48,6 +47,7 @@ #include "cc/raster/scoped_gpu_raster.h" #include "cc/resources/resource_pool.h" #include "cc/resources/scoped_resource.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" @@ -245,7 +245,7 @@ // GrContext for filters is created lazily, and may fail if the context // is lost. // TODO(vmiura,bsalomon): crbug.com/487850 Ensure that - // ContextProvider::GrContext() does not return NULL. + // viz::ContextProvider::GrContext() does not return NULL. if (renderer->output_surface_->context_provider()->GrContext()) return base::WrapUnique(new ScopedUseGrContext(renderer)); return nullptr;
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index 7bb6556..f4669b2c 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h
@@ -13,7 +13,6 @@ #include "base/macros.h" #include "cc/cc_export.h" #include "cc/output/color_lut_cache.h" -#include "cc/output/context_cache_controller.h" #include "cc/output/direct_renderer.h" #include "cc/output/gl_renderer_draw_cache.h" #include "cc/output/program_binding.h" @@ -22,6 +21,7 @@ #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/tile_draw_quad.h" #include "cc/quads/yuv_video_draw_quad.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "ui/gfx/geometry/quad_f.h" #include "ui/latency/latency_info.h" @@ -309,7 +309,8 @@ gpu::gles2::GLES2Interface* gl_; gpu::ContextSupport* context_support_; - std::unique_ptr<ContextCacheController::ScopedVisibility> context_visibility_; + std::unique_ptr<viz::ContextCacheController::ScopedVisibility> + context_visibility_; TextureMailboxDeleter* texture_mailbox_deleter_;
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index 88c506a4..c0713fc 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc
@@ -1610,7 +1610,7 @@ class MockOutputSurface : public OutputSurface { public: - explicit MockOutputSurface(scoped_refptr<ContextProvider> provider) + explicit MockOutputSurface(scoped_refptr<viz::ContextProvider> provider) : OutputSurface(std::move(provider)) {} virtual ~MockOutputSurface() {}
diff --git a/cc/output/layer_tree_frame_sink.cc b/cc/output/layer_tree_frame_sink.cc index 6ad8324..5de7e2a 100644 --- a/cc/output/layer_tree_frame_sink.cc +++ b/cc/output/layer_tree_frame_sink.cc
@@ -19,8 +19,8 @@ namespace cc { LayerTreeFrameSink::LayerTreeFrameSink( - scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> worker_context_provider, + scoped_refptr<viz::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, viz::SharedBitmapManager* shared_bitmap_manager) : context_provider_(std::move(context_provider)), @@ -55,7 +55,7 @@ } if (!success) { - // Destroy the ContextProvider on the thread attempted to be bound. + // Destroy the viz::ContextProvider on the thread attempted to be bound. context_provider_ = nullptr; client_ = nullptr; } @@ -68,9 +68,9 @@ if (context_provider_.get()) { context_provider_->SetLostContextCallback( - ContextProvider::LostContextCallback()); + viz::ContextProvider::LostContextCallback()); } - // Destroy the ContextProvider on the bound thread. + // Destroy the viz::ContextProvider on the bound thread. context_provider_ = nullptr; client_ = nullptr; }
diff --git a/cc/output/layer_tree_frame_sink.h b/cc/output/layer_tree_frame_sink.h index 514f35ee..eded4db7 100644 --- a/cc/output/layer_tree_frame_sink.h +++ b/cc/output/layer_tree_frame_sink.h
@@ -12,10 +12,10 @@ #include "base/memory/ref_counted.h" #include "base/threading/thread_checker.h" #include "cc/cc_export.h" -#include "cc/output/context_provider.h" #include "cc/output/overlay_candidate_validator.h" #include "cc/output/vulkan_context_provider.h" #include "cc/resources/returned_resource.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/common/texture_in_use_response.h" #include "ui/gfx/color_space.h" @@ -64,10 +64,11 @@ // present. // gpu_memory_buffer_manager is optional (won't be used) if context_provider // is not present. - LayerTreeFrameSink(scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> worker_context_provider, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - viz::SharedBitmapManager* shared_bitmap_manager); + LayerTreeFrameSink( + scoped_refptr<viz::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + viz::SharedBitmapManager* shared_bitmap_manager); // Constructor for Vulkan-based resources. explicit LayerTreeFrameSink( @@ -94,10 +95,12 @@ const Capabilities& capabilities() const { return capabilities_; } - // The ContextProviders may be null if frames should be submitted with + // The viz::ContextProviders may be null if frames should be submitted with // software SharedBitmap resources. - ContextProvider* context_provider() const { return context_provider_.get(); } - ContextProvider* worker_context_provider() const { + viz::ContextProvider* context_provider() const { + return context_provider_.get(); + } + viz::ContextProvider* worker_context_provider() const { return worker_context_provider_.get(); } VulkanContextProvider* vulkan_context_provider() const { @@ -129,15 +132,15 @@ virtual void DidNotProduceFrame(const BeginFrameAck& ack) = 0; protected: - // Bound to the ContextProvider to hear about when it is lost and inform the - // |client_|. + // Bound to the viz::ContextProvider to hear about when it is lost and inform + // the |client_|. void DidLoseLayerTreeFrameSink(); LayerTreeFrameSinkClient* client_ = nullptr; struct LayerTreeFrameSink::Capabilities capabilities_; - scoped_refptr<ContextProvider> context_provider_; - scoped_refptr<ContextProvider> worker_context_provider_; + scoped_refptr<viz::ContextProvider> context_provider_; + scoped_refptr<viz::ContextProvider> worker_context_provider_; scoped_refptr<VulkanContextProvider> vulkan_context_provider_; gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; viz::SharedBitmapManager* shared_bitmap_manager_;
diff --git a/cc/output/layer_tree_frame_sink_client.h b/cc/output/layer_tree_frame_sink_client.h index 1015f5b..ef8a96e8 100644 --- a/cc/output/layer_tree_frame_sink_client.h +++ b/cc/output/layer_tree_frame_sink_client.h
@@ -9,8 +9,8 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "cc/cc_export.h" -#include "cc/output/context_provider.h" #include "cc/resources/returned_resource.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/common/texture_in_use_response.h" #include "ui/gfx/geometry/rect.h" @@ -46,9 +46,9 @@ // so that frames are submitted only at the rate it can handle them. virtual void DidReceiveCompositorFrameAck() = 0; - // The LayerTreeFrameSink is lost when the ContextProviders held by it + // The LayerTreeFrameSink is lost when the viz::ContextProviders held by it // encounter an error. In this case the LayerTreeFrameSink (and the - // ContextProviders) must be recreated. + // viz::ContextProviders) must be recreated. virtual void DidLoseLayerTreeFrameSink() = 0; // For SynchronousCompositor (WebView) to ask the layer compositor to submit
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 9c86c08..6b9b006c 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc
@@ -19,7 +19,8 @@ namespace cc { -OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) +OutputSurface::OutputSurface( + scoped_refptr<viz::ContextProvider> context_provider) : context_provider_(std::move(context_provider)) { DCHECK(context_provider_); }
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index d1715cb..740613d 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h
@@ -12,11 +12,11 @@ #include "base/memory/ref_counted.h" #include "base/threading/thread_checker.h" #include "cc/cc_export.h" -#include "cc/output/context_provider.h" #include "cc/output/overlay_candidate_validator.h" #include "cc/output/software_output_device.h" #include "cc/output/vulkan_context_provider.h" #include "cc/resources/returned_resource.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/common/texture_in_use_response.h" #include "ui/gfx/color_space.h" @@ -51,7 +51,7 @@ }; // Constructor for GL-based compositing. - explicit OutputSurface(scoped_refptr<ContextProvider> context_provider); + explicit OutputSurface(scoped_refptr<viz::ContextProvider> context_provider); // Constructor for software compositing. explicit OutputSurface(std::unique_ptr<SoftwareOutputDevice> software_device); // Constructor for Vulkan-based compositing. @@ -66,7 +66,9 @@ // surface. Either of these may return a null pointer, but not both. // In the event of a lost context, the entire output surface should be // recreated. - ContextProvider* context_provider() const { return context_provider_.get(); } + viz::ContextProvider* context_provider() const { + return context_provider_.get(); + } VulkanContextProvider* vulkan_context_provider() const { return vulkan_context_provider_.get(); } @@ -120,7 +122,7 @@ protected: struct OutputSurface::Capabilities capabilities_; - scoped_refptr<ContextProvider> context_provider_; + scoped_refptr<viz::ContextProvider> context_provider_; scoped_refptr<VulkanContextProvider> vulkan_context_provider_; std::unique_ptr<SoftwareOutputDevice> software_device_;
diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h index c3f3df4..43acf529 100644 --- a/cc/output/output_surface_client.h +++ b/cc/output/output_surface_client.h
@@ -9,8 +9,8 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "cc/cc_export.h" -#include "cc/output/context_provider.h" #include "cc/resources/returned_resource.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/common/texture_in_use_response.h" #include "ui/gfx/geometry/rect.h"
diff --git a/cc/output/program_binding.h b/cc/output/program_binding.h index 6f1bc91..03e548d1 100644 --- a/cc/output/program_binding.h +++ b/cc/output/program_binding.h
@@ -9,8 +9,8 @@ #include "base/logging.h" #include "base/macros.h" -#include "cc/output/context_provider.h" #include "cc/output/shader.h" +#include "components/viz/common/gpu/context_provider.h" namespace gfx { class ColorTransform; @@ -155,7 +155,8 @@ public: Program() {} - void Initialize(ContextProvider* context_provider, const ProgramKey& key) { + void Initialize(viz::ContextProvider* context_provider, + const ProgramKey& key) { // Set parameters that are common to all sub-classes. vertex_shader_.aa_mode_ = key.aa_mode_; fragment_shader_.aa_mode_ = key.aa_mode_; @@ -396,7 +397,7 @@ fragment_shader_.uv_texture_mode_ = key.uv_texture_mode_; } - void InitializeInternal(ContextProvider* context_provider) { + void InitializeInternal(viz::ContextProvider* context_provider) { DCHECK(context_provider); DCHECK(!initialized_);
diff --git a/cc/output/texture_mailbox_deleter.cc b/cc/output/texture_mailbox_deleter.cc index 1e306a7..b72642e 100644 --- a/cc/output/texture_mailbox_deleter.cc +++ b/cc/output/texture_mailbox_deleter.cc
@@ -10,15 +10,15 @@ #include "base/location.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" -#include "cc/output/context_provider.h" #include "cc/resources/single_release_callback.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/sync_token.h" namespace cc { static void DeleteTextureOnImplThread( - const scoped_refptr<ContextProvider>& context_provider, + const scoped_refptr<viz::ContextProvider>& context_provider, unsigned texture_id, const gpu::SyncToken& sync_token, bool is_lost) { @@ -50,7 +50,7 @@ std::unique_ptr<SingleReleaseCallback> TextureMailboxDeleter::GetReleaseCallback( - scoped_refptr<ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, unsigned texture_id) { // This callback owns the |context_provider|. It must be destroyed on the impl // thread. Upon destruction of this class, the callback must immediately be
diff --git a/cc/output/texture_mailbox_deleter.h b/cc/output/texture_mailbox_deleter.h index 8003583..326c494 100644 --- a/cc/output/texture_mailbox_deleter.h +++ b/cc/output/texture_mailbox_deleter.h
@@ -19,8 +19,11 @@ struct SyncToken; } -namespace cc { +namespace viz { class ContextProvider; +} + +namespace cc { class SingleReleaseCallback; class CC_EXPORT TextureMailboxDeleter { @@ -37,9 +40,9 @@ // run, on the impl thread. If the TextureMailboxDeleter is destroyed // due to the compositor shutting down, then the ReleaseCallback will // become a no-op and the texture will be deleted immediately on the - // impl thread, along with dropping the reference to the ContextProvider. + // impl thread, along with dropping the reference to the viz::ContextProvider. std::unique_ptr<SingleReleaseCallback> GetReleaseCallback( - scoped_refptr<ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, unsigned texture_id); private:
diff --git a/cc/output/texture_mailbox_deleter_unittest.cc b/cc/output/texture_mailbox_deleter_unittest.cc index 205aede2..37c300d0 100644 --- a/cc/output/texture_mailbox_deleter_unittest.cc +++ b/cc/output/texture_mailbox_deleter_unittest.cc
@@ -34,7 +34,7 @@ EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); // When the deleter is destroyed, it immediately drops its ref on the - // ContextProvider, and deletes the texture. + // viz::ContextProvider, and deletes the texture. deleter = nullptr; EXPECT_TRUE(context_provider->HasOneRef()); EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures()); @@ -66,7 +66,7 @@ cb->Run(gpu::SyncToken(), false); // With no task runner the callback will immediately drops its ref on the - // ContextProvider and delete the texture. + // viz::ContextProvider and delete the texture. EXPECT_TRUE(context_provider->HasOneRef()); EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures()); }
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index 6cc9499..4edfc294 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -36,7 +36,7 @@ const gfx::Rect& raster_dirty_rect, const gfx::AxisTransform2d& transform, const RasterSource::PlaybackSettings& playback_settings, - ContextProvider* context_provider, + viz::ContextProvider* context_provider, ResourceProvider::ScopedWriteLockGL* resource_lock, bool async_worker_context_enabled, bool use_distance_field_text, @@ -115,8 +115,8 @@ } GpuRasterBufferProvider::GpuRasterBufferProvider( - ContextProvider* compositor_context_provider, - ContextProvider* worker_context_provider, + viz::ContextProvider* compositor_context_provider, + viz::ContextProvider* worker_context_provider, ResourceProvider* resource_provider, bool use_distance_field_text, int gpu_rasterization_msaa_sample_count, @@ -264,7 +264,8 @@ uint64_t new_content_id, const gfx::AxisTransform2d& transform, const RasterSource::PlaybackSettings& playback_settings) { - ContextProvider::ScopedContextLock scoped_context(worker_context_provider_); + viz::ContextProvider::ScopedContextLock scoped_context( + worker_context_provider_); gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); DCHECK(gl);
diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h index 7c194d2..7910541 100644 --- a/cc/raster/gpu_raster_buffer_provider.h +++ b/cc/raster/gpu_raster_buffer_provider.h
@@ -12,13 +12,16 @@ #include "cc/resources/resource_provider.h" #include "gpu/command_buffer/common/sync_token.h" -namespace cc { +namespace viz { class ContextProvider; +} + +namespace cc { class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider { public: - GpuRasterBufferProvider(ContextProvider* compositor_context_provider, - ContextProvider* worker_context_provider, + GpuRasterBufferProvider(viz::ContextProvider* compositor_context_provider, + viz::ContextProvider* worker_context_provider, ResourceProvider* resource_provider, bool use_distance_field_text, int gpu_rasterization_msaa_sample_count, @@ -88,8 +91,8 @@ DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); }; - ContextProvider* const compositor_context_provider_; - ContextProvider* const worker_context_provider_; + viz::ContextProvider* const compositor_context_provider_; + viz::ContextProvider* const worker_context_provider_; ResourceProvider* const resource_provider_; const bool use_distance_field_text_; const int msaa_sample_count_;
diff --git a/cc/raster/one_copy_raster_buffer_provider.cc b/cc/raster/one_copy_raster_buffer_provider.cc index 2ff956c..8bda2a0 100644 --- a/cc/raster/one_copy_raster_buffer_provider.cc +++ b/cc/raster/one_copy_raster_buffer_provider.cc
@@ -68,8 +68,8 @@ OneCopyRasterBufferProvider::OneCopyRasterBufferProvider( base::SequencedTaskRunner* task_runner, - ContextProvider* compositor_context_provider, - ContextProvider* worker_context_provider, + viz::ContextProvider* compositor_context_provider, + viz::ContextProvider* worker_context_provider, ResourceProvider* resource_provider, int max_copy_texture_chromium_size, bool use_partial_raster, @@ -234,7 +234,8 @@ // context was lost before ScheduleTasks was called. if (!sync_token.HasData()) return; - ContextProvider::ScopedContextLock scoped_context(worker_context_provider_); + viz::ContextProvider::ScopedContextLock scoped_context( + worker_context_provider_); gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); DCHECK(gl); // Synchronize with compositor. @@ -323,7 +324,8 @@ const gpu::SyncToken& sync_token, const RasterSource* raster_source, const gfx::Rect& rect_to_copy) { - ContextProvider::ScopedContextLock scoped_context(worker_context_provider_); + viz::ContextProvider::ScopedContextLock scoped_context( + worker_context_provider_); gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); DCHECK(gl);
diff --git a/cc/raster/one_copy_raster_buffer_provider.h b/cc/raster/one_copy_raster_buffer_provider.h index 0ed3bf2..aa46670 100644 --- a/cc/raster/one_copy_raster_buffer_provider.h +++ b/cc/raster/one_copy_raster_buffer_provider.h
@@ -8,10 +8,10 @@ #include <stdint.h> #include "base/macros.h" -#include "cc/output/context_provider.h" #include "cc/raster/raster_buffer_provider.h" #include "cc/raster/staging_buffer_pool.h" #include "cc/resources/resource_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/common/sync_token.h" namespace cc { @@ -21,8 +21,8 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider { public: OneCopyRasterBufferProvider(base::SequencedTaskRunner* task_runner, - ContextProvider* compositor_context_provider, - ContextProvider* worker_context_provider, + viz::ContextProvider* compositor_context_provider, + viz::ContextProvider* worker_context_provider, ResourceProvider* resource_provider, int max_copy_texture_chromium_size, bool use_partial_raster, @@ -114,8 +114,8 @@ const gfx::Rect& rect_to_copy); gfx::BufferUsage StagingBufferUsage() const; - ContextProvider* const compositor_context_provider_; - ContextProvider* const worker_context_provider_; + viz::ContextProvider* const compositor_context_provider_; + viz::ContextProvider* const worker_context_provider_; ResourceProvider* const resource_provider_; const int max_bytes_per_copy_operation_; const bool use_partial_raster_;
diff --git a/cc/raster/raster_buffer_provider.cc b/cc/raster/raster_buffer_provider.cc index f669b643..1eb0fd03 100644 --- a/cc/raster/raster_buffer_provider.cc +++ b/cc/raster/raster_buffer_provider.cc
@@ -24,58 +24,6 @@ namespace { -// TODO(enne): http://crbug.com/721744. Add CHECKs for conditions that would -// cause Skia to not create a surface here to diagnose what's going wrong. This -// replicates SkSurfaceValidateRasterInfo and needs to be kept in sync with -// the corresponding Skia code. This code should be removed as quickly as -// possible once a diagnosis is made. -void CheckValidRasterInfo(const SkImageInfo& info, - void* pixels, - size_t row_bytes) { - CHECK(pixels); - CHECK(!info.isEmpty()); - - static const size_t kMaxTotalSize = SK_MaxS32; - - int shift = 0; - switch (info.colorType()) { - case kAlpha_8_SkColorType: - CHECK(!info.colorSpace()); - shift = 0; - break; - case kRGB_565_SkColorType: - CHECK(!info.colorSpace()); - shift = 1; - break; - case kN32_SkColorType: - if (info.colorSpace()) - CHECK(info.colorSpace()->gammaCloseToSRGB()); - shift = 2; - break; - case kRGBA_F16_SkColorType: - if (info.colorSpace()) - CHECK(info.colorSpace()->gammaIsLinear()); - shift = 3; - break; - default: - CHECK(false) << "Unknown color type"; - break; - } - - static constexpr size_t kIgnoreRowBytesValue = static_cast<size_t>(~0); - if (kIgnoreRowBytesValue == row_bytes) - return; - - uint64_t min_row_bytes = static_cast<uint64_t>(info.width()) << shift; - CHECK_LE(min_row_bytes, row_bytes); - - size_t aligned_row_bytes = row_bytes >> shift << shift; - CHECK_EQ(aligned_row_bytes, row_bytes); - - uint64_t size = sk_64_mul(info.height(), row_bytes); - CHECK_LE(size, kMaxTotalSize); -} - bool IsSupportedPlaybackToMemoryFormat(viz::ResourceFormat format) { switch (format) { case viz::RGBA_4444: @@ -133,9 +81,12 @@ case viz::RGBA_8888: case viz::BGRA_8888: case viz::RGBA_F16: { - CheckValidRasterInfo(info, memory, stride); sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(info, memory, stride, &surface_props); + // There are some rare crashes where this doesn't succeed and may be + // indicative of memory stomps elsewhere. Instead of displaying + // invalid content, just crash the renderer and try again. + // See: http://crbug.com/721744. CHECK(surface); raster_source->PlaybackToCanvas(surface->getCanvas(), target_color_space, canvas_bitmap_rect, canvas_playback_rect,
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc index 7a6fc82..7056b94 100644 --- a/cc/raster/raster_buffer_provider_perftest.cc +++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -10,8 +10,6 @@ #include "base/test/test_simple_task_runner.h" #include "base/time/time.h" #include "cc/base/lap_timer.h" -#include "cc/output/context_cache_controller.h" -#include "cc/output/context_provider.h" #include "cc/raster/bitmap_raster_buffer_provider.h" #include "cc/raster/gpu_raster_buffer_provider.h" #include "cc/raster/one_copy_raster_buffer_provider.h" @@ -28,6 +26,8 @@ #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/tiles/tile_task_manager.h" +#include "components/viz/common/gpu/context_cache_controller.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/resources/platform_color.h" #include "gpu/command_buffer/common/sync_token.h" #include "testing/gtest/include/gtest/gtest.h" @@ -78,7 +78,7 @@ } }; -class PerfContextProvider : public ContextProvider { +class PerfContextProvider : public viz::ContextProvider { public: PerfContextProvider() : context_gl_(new PerfGLES2Interface), @@ -103,7 +103,7 @@ cache_controller_.SetGrContext(gr_context_.get()); return gr_context_.get(); } - ContextCacheController* CacheController() override { + viz::ContextCacheController* CacheController() override { return &cache_controller_; } void InvalidateGrContext(uint32_t state) override { @@ -119,7 +119,7 @@ std::unique_ptr<PerfGLES2Interface> context_gl_; sk_sp<class GrContext> gr_context_; TestContextSupport support_; - ContextCacheController cache_controller_; + viz::ContextCacheController cache_controller_; base::Lock context_lock_; }; @@ -307,8 +307,8 @@ } protected: - scoped_refptr<ContextProvider> compositor_context_provider_; - scoped_refptr<ContextProvider> worker_context_provider_; + scoped_refptr<viz::ContextProvider> compositor_context_provider_; + scoped_refptr<viz::ContextProvider> worker_context_provider_; std::unique_ptr<ResourceProvider> resource_provider_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; std::unique_ptr<SynchronousTaskGraphRunner> task_graph_runner_;
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc index 737016dd..09102fd 100644 --- a/cc/raster/raster_buffer_provider_unittest.cc +++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -275,7 +275,7 @@ return completed_tasks_; } - void LoseContext(ContextProvider* context_provider) { + void LoseContext(viz::ContextProvider* context_provider) { if (!context_provider) return; context_provider->ContextGL()->LoseContextCHROMIUM(
diff --git a/cc/raster/scoped_gpu_raster.cc b/cc/raster/scoped_gpu_raster.cc index 9807c29..c388007 100644 --- a/cc/raster/scoped_gpu_raster.cc +++ b/cc/raster/scoped_gpu_raster.cc
@@ -12,7 +12,7 @@ namespace cc { -ScopedGpuRaster::ScopedGpuRaster(ContextProvider* context_provider) +ScopedGpuRaster::ScopedGpuRaster(viz::ContextProvider* context_provider) : context_provider_(context_provider) { BeginGpuRaster(); }
diff --git a/cc/raster/scoped_gpu_raster.h b/cc/raster/scoped_gpu_raster.h index dea7f275..90aca8d 100644 --- a/cc/raster/scoped_gpu_raster.h +++ b/cc/raster/scoped_gpu_raster.h
@@ -10,7 +10,7 @@ #include "base/logging.h" #include "base/macros.h" #include "cc/cc_export.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" namespace cc { @@ -19,14 +19,14 @@ // GL resources while an instance of this class is alive. class CC_EXPORT ScopedGpuRaster { public: - explicit ScopedGpuRaster(ContextProvider* context_provider); + explicit ScopedGpuRaster(viz::ContextProvider* context_provider); ~ScopedGpuRaster(); private: void BeginGpuRaster(); void EndGpuRaster(); - ContextProvider* context_provider_; + viz::ContextProvider* context_provider_; DISALLOW_COPY_AND_ASSIGN(ScopedGpuRaster); };
diff --git a/cc/raster/staging_buffer_pool.cc b/cc/raster/staging_buffer_pool.cc index 69cd406..bcfa1c5 100644 --- a/cc/raster/staging_buffer_pool.cc +++ b/cc/raster/staging_buffer_pool.cc
@@ -128,11 +128,12 @@ } } -StagingBufferPool::StagingBufferPool(base::SequencedTaskRunner* task_runner, - ContextProvider* worker_context_provider, - ResourceProvider* resource_provider, - bool use_partial_raster, - int max_staging_buffer_usage_in_bytes) +StagingBufferPool::StagingBufferPool( + base::SequencedTaskRunner* task_runner, + viz::ContextProvider* worker_context_provider, + ResourceProvider* resource_provider, + bool use_partial_raster, + int max_staging_buffer_usage_in_bytes) : task_runner_(task_runner), worker_context_provider_(worker_context_provider), resource_provider_(resource_provider), @@ -263,7 +264,8 @@ std::unique_ptr<StagingBuffer> staging_buffer; - ContextProvider::ScopedContextLock scoped_context(worker_context_provider_); + viz::ContextProvider::ScopedContextLock scoped_context( + worker_context_provider_); gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); DCHECK(gl); @@ -409,7 +411,8 @@ lock_.AssertAcquired(); { - ContextProvider::ScopedContextLock scoped_context(worker_context_provider_); + viz::ContextProvider::ScopedContextLock scoped_context( + worker_context_provider_); gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); DCHECK(gl);
diff --git a/cc/raster/staging_buffer_pool.h b/cc/raster/staging_buffer_pool.h index 0591cca..3ab66f9 100644 --- a/cc/raster/staging_buffer_pool.h +++ b/cc/raster/staging_buffer_pool.h
@@ -18,8 +18,8 @@ #include "base/time/time.h" #include "base/trace_event/memory_dump_provider.h" #include "base/trace_event/trace_event.h" -#include "cc/output/context_provider.h" #include "cc/resources/resource_provider.h" +#include "components/viz/common/gpu/context_provider.h" namespace gpu { namespace gles2 { @@ -56,7 +56,7 @@ ~StagingBufferPool() final; StagingBufferPool(base::SequencedTaskRunner* task_runner, - ContextProvider* worker_context_provider, + viz::ContextProvider* worker_context_provider, ResourceProvider* resource_provider, bool use_partial_raster, int max_staging_buffer_usage_in_bytes); @@ -93,7 +93,7 @@ void OnPurgeMemory() override; scoped_refptr<base::SequencedTaskRunner> task_runner_; - ContextProvider* const worker_context_provider_; + viz::ContextProvider* const worker_context_provider_; ResourceProvider* const resource_provider_; const bool use_partial_raster_;
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 6c0383e..cbd33ff4 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -368,7 +368,7 @@ ResourceProvider::Child::~Child() {} ResourceProvider::Settings::Settings( - ContextProvider* compositor_context_provider, + viz::ContextProvider* compositor_context_provider, bool delegated_sync_points_required, bool enable_color_correct_rasterization, const viz::ResourceSettings& resource_settings) @@ -412,7 +412,7 @@ } ResourceProvider::ResourceProvider( - ContextProvider* compositor_context_provider, + viz::ContextProvider* compositor_context_provider, viz::SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, BlockingTaskRunner* blocking_main_thread_task_runner, @@ -1170,7 +1170,7 @@ } ResourceProvider::ScopedSkSurfaceProvider::ScopedSkSurfaceProvider( - ContextProvider* context_provider, + viz::ContextProvider* context_provider, ScopedWriteLockGL* resource_lock, bool use_mailbox, bool use_distance_field_text, @@ -2053,7 +2053,7 @@ } GLES2Interface* ResourceProvider::ContextGL() const { - ContextProvider* context_provider = compositor_context_provider_; + viz::ContextProvider* context_provider = compositor_context_provider_; return context_provider ? context_provider->ContextGL() : nullptr; }
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index e9e6147..c4d3873d 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h
@@ -26,13 +26,13 @@ #include "base/trace_event/memory_dump_provider.h" #include "cc/base/resource_id.h" #include "cc/cc_export.h" -#include "cc/output/context_provider.h" #include "cc/output/output_surface.h" #include "cc/output/renderer_settings.h" #include "cc/resources/release_callback_impl.h" #include "cc/resources/return_callback.h" #include "cc/resources/single_release_callback_impl.h" #include "cc/resources/transferable_resource.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/quads/resource_format.h" #include "components/viz/common/quads/shared_bitmap.h" #include "components/viz/common/quads/texture_mailbox.h" @@ -84,7 +84,7 @@ RESOURCE_TYPE_BITMAP, }; - ResourceProvider(ContextProvider* compositor_context_provider, + ResourceProvider(viz::ContextProvider* compositor_context_provider, viz::SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, BlockingTaskRunner* blocking_main_thread_task_runner, @@ -95,7 +95,7 @@ void Initialize(); - void DidLoseContextProvider() { lost_context_provider_ = true; } + void DidLoseVulkanContextProvider() { lost_context_provider_ = true; } int max_texture_size() const { return settings_.max_texture_size; } viz::ResourceFormat best_texture_format() const { @@ -343,7 +343,7 @@ class CC_EXPORT ScopedSkSurfaceProvider { public: - ScopedSkSurfaceProvider(ContextProvider* context_provider, + ScopedSkSurfaceProvider(viz::ContextProvider* context_provider, ScopedWriteLockGL* resource_lock, bool use_mailbox, bool use_distance_field_text, @@ -753,7 +753,7 @@ // texture target used. The resource must be locked for reading. GLenum BindForSampling(ResourceId resource_id, GLenum unit, GLenum filter); - // Returns null if we do not have a ContextProvider. + // Returns null if we do not have a viz::ContextProvider. gpu::gles2::GLES2Interface* ContextGL() const; bool IsGLContextLost() const; @@ -766,7 +766,7 @@ // Holds const settings for the ResourceProvider. Never changed after init. struct Settings { - Settings(ContextProvider* compositor_context_provider, + Settings(viz::ContextProvider* compositor_context_provider, bool delegated_sync_points_needed, bool enable_color_correct_rasterization, const viz::ResourceSettings& resource_settings); @@ -785,7 +785,7 @@ bool delegated_sync_points_required = false; } const settings_; - ContextProvider* compositor_context_provider_; + viz::ContextProvider* compositor_context_provider_; viz::SharedBitmapManager* shared_bitmap_manager_; gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; BlockingTaskRunner* blocking_main_thread_task_runner_;
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 754fe2da..24cfa916e 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc
@@ -1391,7 +1391,7 @@ EXPECT_EQ(0u, returned_to_child.size()); EXPECT_EQ(2u, resource_provider_->num_resources()); - resource_provider_->DidLoseContextProvider(); + resource_provider_->DidLoseVulkanContextProvider(); resource_provider_ = nullptr; EXPECT_EQ(2u, returned_to_child.size()); @@ -2435,7 +2435,7 @@ } // Lose the output surface in the parent. - resource_provider_->DidLoseContextProvider(); + resource_provider_->DidLoseVulkanContextProvider(); { EXPECT_EQ(0u, returned_to_child.size()); @@ -2566,7 +2566,7 @@ } // Lose the output surface in the parent. - resource_provider_->DidLoseContextProvider(); + resource_provider_->DidLoseVulkanContextProvider(); { EXPECT_EQ(0u, returned_to_child.size()); @@ -2734,7 +2734,7 @@ EXPECT_FALSE(lost_resource); EXPECT_FALSE(main_thread_task_runner); - resource_provider_->DidLoseContextProvider(); + resource_provider_->DidLoseVulkanContextProvider(); resource_provider_ = nullptr; EXPECT_LE(sync_token.release_count(), release_sync_token.release_count());
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc index 7ec8510..7dbfbb86 100644 --- a/cc/resources/video_resource_updater.cc +++ b/cc/resources/video_resource_updater.cc
@@ -180,9 +180,10 @@ VideoFrameExternalResources::~VideoFrameExternalResources() {} -VideoResourceUpdater::VideoResourceUpdater(ContextProvider* context_provider, - ResourceProvider* resource_provider, - bool use_stream_video_draw_quad) +VideoResourceUpdater::VideoResourceUpdater( + viz::ContextProvider* context_provider, + ResourceProvider* resource_provider, + bool use_stream_video_draw_quad) : context_provider_(context_provider), resource_provider_(resource_provider), use_stream_video_draw_quad_(use_stream_video_draw_quad), @@ -712,7 +713,7 @@ if (resource_it == updater->all_resources_.end()) return; - ContextProvider* context_provider = updater->context_provider_; + viz::ContextProvider* context_provider = updater->context_provider_; if (context_provider && sync_token.HasData()) { context_provider->ContextGL()->WaitSyncTokenCHROMIUM( sync_token.GetConstData());
diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h index 958d016..63b5388a 100644 --- a/cc/resources/video_resource_updater.h +++ b/cc/resources/video_resource_updater.h
@@ -27,8 +27,11 @@ class VideoFrame; } -namespace cc { +namespace viz { class ContextProvider; +} + +namespace cc { class ResourceProvider; class CC_EXPORT VideoFrameExternalResources { @@ -72,7 +75,7 @@ // resources consumable by the compositor. class CC_EXPORT VideoResourceUpdater { public: - VideoResourceUpdater(ContextProvider* context_provider, + VideoResourceUpdater(viz::ContextProvider* context_provider, ResourceProvider* resource_provider, bool use_stream_video_draw_quad); ~VideoResourceUpdater(); @@ -173,7 +176,7 @@ bool lost_resource, BlockingTaskRunner* main_thread_task_runner); - ContextProvider* context_provider_; + viz::ContextProvider* context_provider_; ResourceProvider* resource_provider_; const bool use_stream_video_draw_quad_; std::unique_ptr<media::SkCanvasVideoRenderer> video_renderer_;
diff --git a/cc/surfaces/surface_manager.h b/cc/surfaces/surface_manager.h index 47a1553d..b6573cf 100644 --- a/cc/surfaces/surface_manager.h +++ b/cc/surfaces/surface_manager.h
@@ -35,6 +35,7 @@ namespace viz { namespace test { +class SurfaceReferencesTest; class SurfaceSynchronizationTest; } } // namespace viz @@ -187,7 +188,7 @@ private: friend class viz::test::SurfaceSynchronizationTest; - friend class SurfaceManagerRefTest; + friend class viz::test::SurfaceReferencesTest; using SurfaceIdSet = std::unordered_set<viz::SurfaceId, viz::SurfaceIdHash>;
diff --git a/cc/test/fake_layer_tree_frame_sink.cc b/cc/test/fake_layer_tree_frame_sink.cc index 0eeca9b5..eb7c306b 100644 --- a/cc/test/fake_layer_tree_frame_sink.cc +++ b/cc/test/fake_layer_tree_frame_sink.cc
@@ -16,8 +16,8 @@ namespace cc { FakeLayerTreeFrameSink::FakeLayerTreeFrameSink( - scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> worker_context_provider) + scoped_refptr<viz::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) : LayerTreeFrameSink(std::move(context_provider), std::move(worker_context_provider), nullptr,
diff --git a/cc/test/fake_layer_tree_frame_sink.h b/cc/test/fake_layer_tree_frame_sink.h index 4efc404..a30bf53c 100644 --- a/cc/test/fake_layer_tree_frame_sink.h +++ b/cc/test/fake_layer_tree_frame_sink.h
@@ -81,8 +81,8 @@ protected: FakeLayerTreeFrameSink( - scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> worker_context_provider); + scoped_refptr<viz::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider); TestGpuMemoryBufferManager test_gpu_memory_buffer_manager_; TestSharedBitmapManager test_shared_bitmap_manager_;
diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index ac7d345..e809100 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc
@@ -14,7 +14,7 @@ namespace cc { FakeOutputSurface::FakeOutputSurface( - scoped_refptr<ContextProvider> context_provider) + scoped_refptr<viz::ContextProvider> context_provider) : OutputSurface(std::move(context_provider)), weak_ptr_factory_(this) { DCHECK(OutputSurface::context_provider()); }
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index 05c19013..a80fb38 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h
@@ -32,7 +32,7 @@ } static std::unique_ptr<FakeOutputSurface> Create3d( - scoped_refptr<ContextProvider> context_provider) { + scoped_refptr<viz::ContextProvider> context_provider) { return base::WrapUnique(new FakeOutputSurface(context_provider)); } @@ -42,7 +42,7 @@ } static std::unique_ptr<FakeOutputSurface> CreateOffscreen( - scoped_refptr<ContextProvider> context_provider) { + scoped_refptr<viz::ContextProvider> context_provider) { auto surface = base::WrapUnique(new FakeOutputSurface(std::move(context_provider))); surface->capabilities_.uses_default_gl_framebuffer = false; @@ -103,7 +103,8 @@ } protected: - explicit FakeOutputSurface(scoped_refptr<ContextProvider> context_provider); + explicit FakeOutputSurface( + scoped_refptr<viz::ContextProvider> context_provider); explicit FakeOutputSurface( std::unique_ptr<SoftwareOutputDevice> software_device);
diff --git a/cc/test/fake_resource_provider.h b/cc/test/fake_resource_provider.h index f8771fd5..20295b5 100644 --- a/cc/test/fake_resource_provider.h +++ b/cc/test/fake_resource_provider.h
@@ -17,7 +17,7 @@ class FakeResourceProvider : public ResourceProvider { public: static std::unique_ptr<FakeResourceProvider> Create( - ContextProvider* context_provider, + viz::ContextProvider* context_provider, viz::SharedBitmapManager* shared_bitmap_manager) { viz::ResourceSettings resource_settings; resource_settings.texture_id_allocation_chunk_size = 1; @@ -29,7 +29,7 @@ } static std::unique_ptr<FakeResourceProvider> Create( - ContextProvider* context_provider, + viz::ContextProvider* context_provider, viz::SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) { viz::ResourceSettings resource_settings; @@ -42,7 +42,7 @@ } private: - FakeResourceProvider(ContextProvider* context_provider, + FakeResourceProvider(viz::ContextProvider* context_provider, viz::SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, BlockingTaskRunner* blocking_main_thread_task_runner,
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc index 0088515..f8d935f 100644 --- a/cc/test/layer_tree_pixel_resource_test.cc +++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -128,9 +128,9 @@ DCHECK(task_runner); DCHECK(initialized_); - ContextProvider* compositor_context_provider = + viz::ContextProvider* compositor_context_provider = host_impl->layer_tree_frame_sink()->context_provider(); - ContextProvider* worker_context_provider = + viz::ContextProvider* worker_context_provider = host_impl->layer_tree_frame_sink()->worker_context_provider(); ResourceProvider* resource_provider = host_impl->resource_provider(); int max_bytes_per_copy_operation = 1024 * 1024;
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index 345d890..a3a6eee66 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc
@@ -42,8 +42,8 @@ LayerTreePixelTest::CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider>, - scoped_refptr<ContextProvider>) { + scoped_refptr<viz::ContextProvider>, + scoped_refptr<viz::ContextProvider>) { scoped_refptr<TestInProcessContextProvider> compositor_context_provider; scoped_refptr<TestInProcessContextProvider> worker_context_provider; if (test_type_ == PIXEL_TEST_GL) { @@ -68,7 +68,7 @@ std::unique_ptr<OutputSurface> LayerTreePixelTest::CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) { + scoped_refptr<viz::ContextProvider> compositor_context_provider) { std::unique_ptr<PixelTestOutputSurface> display_output_surface; if (test_type_ == PIXEL_TEST_GL) { // Pixel tests use a separate context for the Display to more closely
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h index 4e15faf..246eddf 100644 --- a/cc/test/layer_tree_pixel_test.h +++ b/cc/test/layer_tree_pixel_test.h
@@ -42,10 +42,10 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override; + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override; std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override; + scoped_refptr<viz::ContextProvider> compositor_context_provider) override; virtual std::unique_ptr<CopyOutputRequest> CreateCopyOutputRequest();
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 51131b2..f2131f381 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -474,7 +474,8 @@ // viz::TestLayerTreeFrameSinkClient implementation. std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { return hooks_->CreateDisplayOutputSurfaceOnThread( std::move(compositor_context_provider)); } @@ -878,8 +879,8 @@ LayerTreeTest::CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) { constexpr bool disable_display_vsync = false; bool synchronous_composite = !HasImplThread() && @@ -893,7 +894,7 @@ std::unique_ptr<OutputSurface> LayerTreeTest::CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) { + scoped_refptr<viz::ContextProvider> compositor_context_provider) { // By default the Display shares a context with the LayerTreeHostImpl. return FakeOutputSurface::Create3d(std::move(compositor_context_provider)); }
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index 92aeb44..5230fc60 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h
@@ -138,21 +138,21 @@ // By default, output surface recreation is synchronous. void RequestNewLayerTreeFrameSink() override; - // Override this and call the base class to change what ContextProviders will - // be used (such as for pixel tests). Or override it and create your own + // Override this and call the base class to change what viz::ContextProviders + // will be used (such as for pixel tests). Or override it and create your own // TestLayerTreeFrameSink to control how it is created. virtual std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider); - // Override this and call the base class to change what ContextProvider will - // be used, such as to prevent sharing the context with the + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider); + // Override this and call the base class to change what viz::ContextProvider + // will be used, such as to prevent sharing the context with the // LayerTreeFrameSink. Or override it and create your own OutputSurface to // change what type of OutputSurface is used, such as a real OutputSurface for // pixel tests or a software-compositing OutputSurface. std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override; + scoped_refptr<viz::ContextProvider> compositor_context_provider) override; gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl);
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h index cf285e5..611d489 100644 --- a/cc/test/pixel_test.h +++ b/cc/test/pixel_test.h
@@ -50,7 +50,7 @@ const PixelComparator& comparator, const gfx::Rect* copy_rect); - ContextProvider* context_provider() const { + viz::ContextProvider* context_provider() const { return output_surface_->context_provider(); }
diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc index a0caa4a6..5ee44fb 100644 --- a/cc/test/pixel_test_output_surface.cc +++ b/cc/test/pixel_test_output_surface.cc
@@ -17,7 +17,7 @@ namespace cc { PixelTestOutputSurface::PixelTestOutputSurface( - scoped_refptr<ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, bool flipped_output_surface) : OutputSurface(std::move(context_provider)), weak_ptr_factory_(this) { capabilities_.flipped_output_surface = flipped_output_surface;
diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h index b861d203..9841ede 100644 --- a/cc/test/pixel_test_output_surface.h +++ b/cc/test/pixel_test_output_surface.h
@@ -13,7 +13,7 @@ class PixelTestOutputSurface : public OutputSurface { public: explicit PixelTestOutputSurface( - scoped_refptr<ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, bool flipped_output_surface); explicit PixelTestOutputSurface( std::unique_ptr<SoftwareOutputDevice> software_device);
diff --git a/cc/test/test_context_provider.cc b/cc/test/test_context_provider.cc index a34e731a7..49444a9 100644 --- a/cc/test/test_context_provider.cc +++ b/cc/test/test_context_provider.cc
@@ -15,9 +15,9 @@ #include "base/callback_helpers.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "cc/output/context_cache_controller.h" #include "cc/test/test_gles2_interface.h" #include "cc/test/test_web_graphics_context_3d.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "gpu/skia_bindings/grcontext_for_gles2_interface.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" @@ -153,10 +153,11 @@ context_thread_checker_.DetachFromThread(); context_gl_->set_test_context(context3d_.get()); context3d_->set_test_support(support_.get()); - // Just pass nullptr to the ContextCacheController for its task runner. Idle - // handling is tested directly in ContextCacheController's unittests, and - // isn't needed here. - cache_controller_.reset(new ContextCacheController(support_.get(), nullptr)); + // Just pass nullptr to the viz::ContextCacheController for its task runner. + // Idle handling is tested directly in viz::ContextCacheController's + // unittests, and isn't needed here. + cache_controller_.reset( + new viz::ContextCacheController(support_.get(), nullptr)); } TestContextProvider::~TestContextProvider() { @@ -223,7 +224,7 @@ return gr_context_->get(); } -ContextCacheController* TestContextProvider::CacheController() { +viz::ContextCacheController* TestContextProvider::CacheController() { DCHECK(context_thread_checker_.CalledOnValidThread()); return cache_controller_.get(); }
diff --git a/cc/test/test_context_provider.h b/cc/test/test_context_provider.h index 7d47431..867de8c 100644 --- a/cc/test/test_context_provider.h +++ b/cc/test/test_context_provider.h
@@ -15,8 +15,8 @@ #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" -#include "cc/output/context_provider.h" #include "cc/test/test_context_support.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/gles2_interface_stub.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -28,7 +28,7 @@ class TestWebGraphicsContext3D; class TestGLES2Interface; -class TestContextProvider : public ContextProvider { +class TestContextProvider : public viz::ContextProvider { public: typedef base::Callback<std::unique_ptr<TestWebGraphicsContext3D>(void)> CreateCallback; @@ -51,7 +51,7 @@ gpu::gles2::GLES2Interface* ContextGL() override; gpu::ContextSupport* ContextSupport() override; class GrContext* GrContext() override; - ContextCacheController* CacheController() override; + viz::ContextCacheController* CacheController() override; void InvalidateGrContext(uint32_t state) override; base::Lock* GetLock() override; void SetLostContextCallback(const LostContextCallback& cb) override; @@ -80,7 +80,7 @@ std::unique_ptr<TestWebGraphicsContext3D> context3d_; std::unique_ptr<TestGLES2Interface> context_gl_; std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_; - std::unique_ptr<ContextCacheController> cache_controller_; + std::unique_ptr<viz::ContextCacheController> cache_controller_; bool bound_ = false; base::ThreadChecker main_thread_checker_;
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h index c2cc40fb..c8690d6 100644 --- a/cc/test/test_hooks.h +++ b/cc/test/test_hooks.h
@@ -126,7 +126,7 @@ // overridden. virtual void RequestNewLayerTreeFrameSink() = 0; virtual std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) = 0; + scoped_refptr<viz::ContextProvider> compositor_context_provider) = 0; }; } // namespace cc
diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc index f70d68c..441bc7a 100644 --- a/cc/test/test_in_process_context_provider.cc +++ b/cc/test/test_in_process_context_provider.cc
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" -#include "cc/output/context_cache_controller.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "components/viz/common/resources/platform_color.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gles2_implementation.h" @@ -64,7 +64,7 @@ &gpu_memory_buffer_manager_, &image_factory_, (shared_context ? shared_context->context_.get() : nullptr), base::ThreadTaskRunnerHandle::Get()); - cache_controller_.reset(new ContextCacheController( + cache_controller_.reset(new viz::ContextCacheController( context_->GetImplementation(), base::ThreadTaskRunnerHandle::Get())); } @@ -93,7 +93,7 @@ return gr_context_->get(); } -ContextCacheController* TestInProcessContextProvider::CacheController() { +viz::ContextCacheController* TestInProcessContextProvider::CacheController() { return cache_controller_.get(); }
diff --git a/cc/test/test_in_process_context_provider.h b/cc/test/test_in_process_context_provider.h index 0b8ea12..19f0ec3 100644 --- a/cc/test/test_in_process_context_provider.h +++ b/cc/test/test_in_process_context_provider.h
@@ -11,9 +11,9 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" -#include "cc/output/context_provider.h" #include "cc/test/test_gpu_memory_buffer_manager.h" #include "cc/test/test_image_factory.h" +#include "components/viz/common/gpu/context_provider.h" class GrContext; @@ -34,7 +34,7 @@ gpu::GLInProcessContext* shared_context, scoped_refptr<base::SingleThreadTaskRunner> task_runner); -class TestInProcessContextProvider : public ContextProvider { +class TestInProcessContextProvider : public viz::ContextProvider { public: explicit TestInProcessContextProvider( TestInProcessContextProvider* shared_context); @@ -43,7 +43,7 @@ gpu::gles2::GLES2Interface* ContextGL() override; gpu::ContextSupport* ContextSupport() override; class GrContext* GrContext() override; - ContextCacheController* CacheController() override; + viz::ContextCacheController* CacheController() override; void InvalidateGrContext(uint32_t state) override; base::Lock* GetLock() override; gpu::Capabilities ContextCapabilities() override; @@ -59,7 +59,7 @@ TestImageFactory image_factory_; std::unique_ptr<gpu::GLInProcessContext> context_; std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_; - std::unique_ptr<ContextCacheController> cache_controller_; + std::unique_ptr<viz::ContextCacheController> cache_controller_; base::Lock context_lock_; };
diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h index b7ae1c2..02c6bffa 100644 --- a/cc/test/test_web_graphics_context_3d.h +++ b/cc/test/test_web_graphics_context_3d.h
@@ -20,9 +20,9 @@ #include "base/memory/weak_ptr.h" #include "base/stl_util.h" #include "base/synchronization/lock.h" -#include "cc/output/context_provider.h" #include "cc/test/ordered_texture_map.h" #include "cc/test/test_texture.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/common/sync_token.h" #include "third_party/khronos/GLES2/gl2.h" #include "ui/gfx/geometry/rect.h"
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index 41511d2c..5a74b79 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -18,9 +18,9 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "cc/base/devtools_instrumentation.h" -#include "cc/output/context_provider.h" #include "cc/raster/tile_task.h" #include "cc/tiles/mipmap_util.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" @@ -392,7 +392,7 @@ DCHECK(!upload.image()); } -GpuImageDecodeCache::GpuImageDecodeCache(ContextProvider* context, +GpuImageDecodeCache::GpuImageDecodeCache(viz::ContextProvider* context, viz::ResourceFormat decode_format, size_t max_working_set_bytes, size_t max_cache_bytes) @@ -406,7 +406,7 @@ // Acquire the context_lock so that we can safely retrieve the // GrContextThreadSafeProxy. This proxy can then be used with no lock held. { - ContextProvider::ScopedContextLock context_lock(context_); + viz::ContextProvider::ScopedContextLock context_lock(context_); context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>( context->GrContext()->threadSafeProxy()); } @@ -622,7 +622,7 @@ "GpuImageDecodeCache::SetShouldAggressivelyFreeResources", "agressive_free_resources", aggressively_free_resources); if (aggressively_free_resources) { - ContextProvider::ScopedContextLock context_lock(context_); + viz::ContextProvider::ScopedContextLock context_lock(context_); base::AutoLock lock(lock_); // We want to keep as little in our cache as possible. Set our memory limit // to zero and EnsureCapacity to clean up memory. @@ -766,7 +766,7 @@ void GpuImageDecodeCache::UploadImage(const DrawImage& draw_image) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeCache::UploadImage"); - ContextProvider::ScopedContextLock context_lock(context_); + viz::ContextProvider::ScopedContextLock context_lock(context_); base::AutoLock lock(lock_); ImageData* image_data = GetImageDataForDrawImage(draw_image); DCHECK(image_data);
diff --git a/cc/tiles/gpu_image_decode_cache.h b/cc/tiles/gpu_image_decode_cache.h index b290faf..0499472 100644 --- a/cc/tiles/gpu_image_decode_cache.h +++ b/cc/tiles/gpu_image_decode_cache.h
@@ -19,9 +19,11 @@ #include "components/viz/common/quads/resource_format.h" #include "third_party/skia/include/core/SkRefCnt.h" -namespace cc { - +namespace viz { class ContextProvider; +} + +namespace cc { // OVERVIEW: // @@ -101,7 +103,7 @@ public: enum class DecodeTaskType { PART_OF_UPLOAD_TASK, STAND_ALONE_DECODE_TASK }; - explicit GpuImageDecodeCache(ContextProvider* context, + explicit GpuImageDecodeCache(viz::ContextProvider* context, viz::ResourceFormat decode_format, size_t max_working_set_bytes, size_t max_cache_bytes); @@ -348,7 +350,7 @@ void DeletePendingImages(); const viz::ResourceFormat format_; - ContextProvider* context_; + viz::ContextProvider* context_; sk_sp<GrContextThreadSafeProxy> context_threadsafe_proxy_; // All members below this point must only be accessed while holding |lock_|.
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc index 721f5b1..6c13daf 100644 --- a/cc/tiles/gpu_image_decode_cache_unittest.cc +++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -27,7 +27,7 @@ size_t kGpuMemoryLimitBytes = 96 * 1024 * 1024; class TestGpuImageDecodeCache : public GpuImageDecodeCache { public: - explicit TestGpuImageDecodeCache(ContextProvider* context, + explicit TestGpuImageDecodeCache(viz::ContextProvider* context, viz::ResourceFormat format) : GpuImageDecodeCache(context, format, @@ -651,7 +651,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -686,7 +686,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -722,7 +722,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -769,7 +769,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -826,7 +826,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -873,7 +873,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -910,7 +910,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -949,7 +949,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -989,7 +989,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -1022,7 +1022,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_TRUE(decoded_draw_image.image()); @@ -1065,7 +1065,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_FALSE(decoded_draw_image.image()); @@ -1095,7 +1095,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); DecodedDrawImage decoded_draw_image = cache.GetDecodedImageForDraw(draw_image); EXPECT_FALSE(decoded_draw_image.image()); @@ -1389,7 +1389,7 @@ // Must hold context lock before calling GetDecodedImageForDraw / // DrawWithImageFinished. - ContextProvider::ScopedContextLock context_lock(context_provider.get()); + viz::ContextProvider::ScopedContextLock context_lock(context_provider.get()); // Do an at-raster decode of the above image that *does* require mips. DrawImage draw_image_mips(
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index cf65cad..e43d7a93 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -682,7 +682,7 @@ bool gpu_rasterization_enabled = false; if (host_impl->layer_tree_frame_sink()) { - ContextProvider* compositor_context_provider = + viz::ContextProvider* compositor_context_provider = host_impl->layer_tree_frame_sink()->context_provider(); if (compositor_context_provider) { gpu_rasterization_enabled =
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index cd185fa..a546dc9 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1837,9 +1837,9 @@ layer_tree_frame_sink_->worker_context_provider())) return false; - ContextProvider* context_provider = + viz::ContextProvider* context_provider = layer_tree_frame_sink_->worker_context_provider(); - ContextProvider::ScopedContextLock scoped_context(context_provider); + viz::ContextProvider::ScopedContextLock scoped_context(context_provider); if (!context_provider->GrContext()) return false; @@ -1856,7 +1856,7 @@ int requested_msaa_samples = RequestedMSAASampleCount(); int max_msaa_samples = 0; - ContextProvider* compositor_context_provider = + viz::ContextProvider* compositor_context_provider = layer_tree_frame_sink_->context_provider(); bool gpu_rasterization_enabled = false; bool supports_disable_msaa = false; @@ -2022,7 +2022,7 @@ void LayerTreeHostImpl::DidLoseLayerTreeFrameSink() { if (resource_provider_) - resource_provider_->DidLoseContextProvider(); + resource_provider_->DidLoseVulkanContextProvider(); has_valid_layer_tree_frame_sink_ = false; client_->DidLoseLayerTreeFrameSinkOnImplThread(); } @@ -2341,7 +2341,7 @@ // resolved. CHECK(resource_provider_); - ContextProvider* compositor_context_provider = + viz::ContextProvider* compositor_context_provider = layer_tree_frame_sink_->context_provider(); if (!compositor_context_provider) { *resource_pool = @@ -2355,7 +2355,7 @@ return; } - ContextProvider* worker_context_provider = + viz::ContextProvider* worker_context_provider = layer_tree_frame_sink_->worker_context_provider(); if (use_gpu_rasterization_) { DCHECK(worker_context_provider); @@ -2483,7 +2483,7 @@ compositor_context->ContextGL()->ShallowFlushCHROMIUM(); if (auto* worker_context = layer_tree_frame_sink_->worker_context_provider()) { - ContextProvider::ScopedContextLock hold(worker_context); + viz::ContextProvider::ScopedContextLock hold(worker_context); worker_context->ContextGL()->ShallowFlushCHROMIUM(); } } @@ -4389,7 +4389,7 @@ // before we get a chance to go invisible in NotifyAllTileTasksComplete. auto* worker_context = layer_tree_frame_sink_->worker_context_provider(); if (worker_context && is_visible != !!worker_context_visibility_) { - ContextProvider::ScopedContextLock hold(worker_context); + viz::ContextProvider::ScopedContextLock hold(worker_context); if (is_visible) { worker_context_visibility_ = worker_context->CacheController()->ClientBecameVisible();
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 1f809c49..c1a3920 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -26,7 +26,6 @@ #include "cc/input/scrollbar_animation_controller.h" #include "cc/layers/layer_collections.h" #include "cc/output/begin_frame_args.h" -#include "cc/output/context_cache_controller.h" #include "cc/output/layer_tree_frame_sink_client.h" #include "cc/output/managed_memory_policy.h" #include "cc/quads/render_pass.h" @@ -43,6 +42,7 @@ #include "cc/trees/layer_tree_settings.h" #include "cc/trees/mutator_host_client.h" #include "cc/trees/task_runner_provider.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "components/viz/common/surfaces/local_surface_id.h" #include "components/viz/common/surfaces/surface_id.h" #include "ui/gfx/geometry/rect.h" @@ -750,11 +750,11 @@ // The following scoped variables must not outlive the // |layer_tree_frame_sink_|. - // These should be transfered to ContextCacheController's + // These should be transfered to viz::ContextCacheController's // ClientBecameNotVisible() before the output surface is destroyed. - std::unique_ptr<ContextCacheController::ScopedVisibility> + std::unique_ptr<viz::ContextCacheController::ScopedVisibility> compositor_context_visibility_; - std::unique_ptr<ContextCacheController::ScopedVisibility> + std::unique_ptr<viz::ContextCacheController::ScopedVisibility> worker_context_visibility_; std::unique_ptr<ResourceProvider> resource_provider_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index adb20a5..dd5579d 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -8785,11 +8785,12 @@ class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient { public: explicit FrameSinkClient( - scoped_refptr<ContextProvider> display_context_provider) + scoped_refptr<viz::ContextProvider> display_context_provider) : display_context_provider_(std::move(display_context_provider)) {} std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { return FakeOutputSurface::Create3d(std::move(display_context_provider_)); } @@ -8801,7 +8802,7 @@ void DisplayDidDrawAndSwap() override {} private: - scoped_refptr<ContextProvider> display_context_provider_; + scoped_refptr<viz::ContextProvider> display_context_provider_; }; TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { @@ -8833,7 +8834,7 @@ host_impl_->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); - // The CopyOutputResult's callback has a ref on the ContextProvider and a + // The CopyOutputResult's callback has a ref on the viz::ContextProvider and a // texture in a texture mailbox. EXPECT_FALSE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc index f1c354b..8e50cb0 100644 --- a/cc/trees/layer_tree_host_perftest.cc +++ b/cc/trees/layer_tree_host_perftest.cc
@@ -49,8 +49,8 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { constexpr bool disable_display_vsync = true; bool synchronous_composite = !HasImplThread() &&
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc index b8a5018..47f69d9 100644 --- a/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -72,8 +72,8 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { RendererSettings modified_renderer_settings = renderer_settings; modified_renderer_settings.force_antialiasing = force_antialiasing_; modified_renderer_settings.force_blending_with_shaders =
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc index 58d1140e..2617a12 100644 --- a/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -177,12 +177,12 @@ void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override { // Issue a GL finish before preparing tiles to ensure resources become // available for use in a timely manner. Needed for the one-copy path. - ContextProvider* context_provider = + viz::ContextProvider* context_provider = host_impl->layer_tree_frame_sink()->worker_context_provider(); if (!context_provider) return; - ContextProvider::ScopedContextLock lock(context_provider); + viz::ContextProvider::ScopedContextLock lock(context_provider); lock.ContextGL()->Finish(); }
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 5ed5c36..1d9f172c 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -444,15 +444,15 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { - // Create the main ContextProvider with a MockContextSupport. + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { + // Create the main viz::ContextProvider with a MockContextSupport. auto main_support = base::MakeUnique<MockContextSupport>(); mock_main_context_support_ = main_support.get(); auto test_main_context_provider = TestContextProvider::Create( TestWebGraphicsContext3D::Create(), std::move(main_support)); - // Create the main ContextProvider with a MockContextSupport. + // Create the main viz::ContextProvider with a MockContextSupport. auto worker_support = base::MakeUnique<MockContextSupport>(); mock_worker_context_support_ = worker_support.get(); auto test_worker_context_provider = TestContextProvider::Create( @@ -3363,8 +3363,8 @@ class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink { public: OnDrawLayerTreeFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider, viz::SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& renderer_settings, @@ -3407,8 +3407,8 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { auto on_draw_callback = base::Bind( &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor:: CallOnDraw, @@ -5538,8 +5538,8 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { auto context = TestWebGraphicsContext3D::Create(); context->SetMaxSamples(4); context->set_support_multisample_compatibility(false); @@ -6068,8 +6068,8 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { constexpr bool disable_display_vsync = false; bool synchronous_composite = !HasImplThread() && @@ -6393,7 +6393,8 @@ : public LayerTreeHostTestCrispUpAfterPinchEnds { protected: std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { scoped_refptr<TestContextProvider> display_context_provider = TestContextProvider::Create(); TestWebGraphicsContext3D* context3d = @@ -7628,10 +7629,10 @@ // this here to ensure that our otuput surface exists. // Retrieve max texture size from Skia. - ContextProvider* context_provider = + viz::ContextProvider* context_provider = host_impl->layer_tree_frame_sink()->context_provider(); ASSERT_TRUE(context_provider); - ContextProvider::ScopedContextLock context_lock(context_provider); + viz::ContextProvider::ScopedContextLock context_lock(context_provider); GrContext* gr_context = context_provider->GrContext(); ASSERT_TRUE(gr_context);
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index e14401b..55510ac6 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -80,8 +80,8 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { base::AutoLock lock(context3d_lock_); std::unique_ptr<TestWebGraphicsContext3D> compositor_context3d = @@ -1627,7 +1627,7 @@ void BeginTest() override { PostSetNeedsCommitToMainThread(); } void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override { - ContextProvider::ScopedContextLock scoped_context( + viz::ContextProvider::ScopedContextLock scoped_context( host_impl->layer_tree_frame_sink()->worker_context_provider()); gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc index 22f5ca1..b190d8a 100644 --- a/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -129,7 +129,8 @@ void AfterTest() override { EXPECT_EQ(4u, callbacks_.size()); } std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { if (!use_gl_renderer_) { return FakeOutputSurface::CreateSoftware( base::WrapUnique(new SoftwareOutputDevice)); @@ -466,8 +467,8 @@ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const RendererSettings& renderer_settings, double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { auto frame_sink = LayerTreeHostCopyRequestTest::CreateLayerTreeFrameSink( renderer_settings, refresh_rate, std::move(compositor_context_provider), std::move(worker_context_provider)); @@ -738,7 +739,8 @@ : public LayerTreeHostCopyRequestTest { protected: std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { display_context_provider_ = TestContextProvider::Create(); display_context_provider_->BindToCurrentThread(); return FakeOutputSurface::Create3d(display_context_provider_); @@ -864,7 +866,8 @@ } std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { // These tests expect the LayerTreeHostImpl to share a context with // the Display so that sync points are not needed and the texture counts // are visible together.
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index dd71d11..9256bbe0 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -1310,7 +1310,7 @@ return layer_tree_host_impl_->debug_state(); } -ContextProvider* LayerTreeImpl::context_provider() const { +viz::ContextProvider* LayerTreeImpl::context_provider() const { return layer_tree_host_impl_->layer_tree_frame_sink()->context_provider(); }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index 4f7eb398..5c05caf 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -31,9 +31,12 @@ } } +namespace viz { +class ContextProvider; +} + namespace cc { -class ContextProvider; class DebugRectHistory; class FrameRateCounter; class HeadsUpDisplayLayerImpl; @@ -103,7 +106,7 @@ // --------------------------------------------------------------------------- const LayerTreeSettings& settings() const; const LayerTreeDebugState& debug_state() const; - ContextProvider* context_provider() const; + viz::ContextProvider* context_provider() const; ResourceProvider* resource_provider() const; TileManager* tile_manager() const; ImageDecodeCache* image_decode_cache() const;
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index 40b7bc7..6fe0a16 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -18,7 +18,6 @@ #include "cc/base/devtools_instrumentation.h" #include "cc/benchmarks/benchmark_instrumentation.h" #include "cc/input/browser_controls_offset_manager.h" -#include "cc/output/context_provider.h" #include "cc/output/layer_tree_frame_sink.h" #include "cc/scheduler/compositor_timing_history.h" #include "cc/scheduler/delay_based_time_source.h" @@ -27,6 +26,7 @@ #include "cc/trees/mutator_host.h" #include "cc/trees/proxy_main.h" #include "cc/trees/task_runner_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" namespace cc { @@ -209,7 +209,7 @@ TRACE_EVENT0("cc", "ProxyImpl::FinishGLOnImplThread"); DCHECK(IsImplThread()); if (layer_tree_host_impl_->layer_tree_frame_sink()) { - ContextProvider* context_provider = + viz::ContextProvider* context_provider = layer_tree_host_impl_->layer_tree_frame_sink()->context_provider(); if (context_provider) context_provider->ContextGL()->Finish();
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 165f5b42..39b09aa 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc
@@ -10,7 +10,6 @@ #include "base/trace_event/trace_event.h" #include "cc/base/devtools_instrumentation.h" #include "cc/benchmarks/benchmark_instrumentation.h" -#include "cc/output/context_provider.h" #include "cc/output/layer_tree_frame_sink.h" #include "cc/quads/draw_quad.h" #include "cc/resources/ui_resource_manager.h" @@ -24,6 +23,7 @@ #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/scoped_abort_remaining_swap_promises.h" +#include "components/viz/common/gpu/context_provider.h" namespace cc {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index ed453255..bc75575 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -778,7 +778,7 @@ mToolbarHolder = (FrameLayout) mControlContainer.findViewById(R.id.toolbar_holder); mDefaultToolbarView = (BottomToolbarPhone) mControlContainer.findViewById(R.id.toolbar); - mNtpController = new BottomSheetNewTabController(this, mDefaultToolbarView); + mNtpController = new BottomSheetNewTabController(this, mDefaultToolbarView, mActivity); mActivity.getFullscreenManager().addListener(new FullscreenListener() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentController.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentController.java index 7d321f806..67c768852 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentController.java
@@ -224,6 +224,16 @@ } /** + * @param itemId The id of the MenuItem to select. + */ + public void selectItem(int itemId) { + // TODO(twellington): A #setSelectedItemId() method was added to the support library + // recently. Replace this custom implementation with that method after + // the support library is rolled. + onNavigationItemSelected(getMenu().findItem(itemId)); + } + + /** * Shows the specified {@link BottomSheetContent} and opens the {@link BottomSheet}. * @param itemId The menu item id of the {@link BottomSheetContent} to show. */ @@ -346,17 +356,6 @@ setItemTextColor(tint); } - /** - * @param itemId The id of the MenuItem to select. - */ - @VisibleForTesting - public void selectItem(int itemId) { - // TODO(twellington): A #setSelectedItemId() method was added to the support library - // recently. Replace this custom implementation with that method after - // the support library is rolled. - onNavigationItemSelected(getMenu().findItem(itemId)); - } - @VisibleForTesting public int getSelectedItemIdForTests() { // TODO(twellington): A #getSelectedItemId() method was added to the support library
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabController.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabController.java index e40ad6399..c324efd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabController.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.widget.bottomsheet; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; @@ -13,12 +15,11 @@ /** * A class that handles showing and hiding the Chrome Home new tab UI. - * - * TODO(twellington): Add tests for this class. */ public class BottomSheetNewTabController extends EmptyBottomSheetObserver { private final BottomSheet mBottomSheet; private final BottomToolbarPhone mToolbar; + private final ChromeActivity mActivity; private LayoutManagerChrome mLayoutManager; private OverviewModeObserver mOverviewModeObserver; @@ -34,11 +35,14 @@ * @param bottomSheet The {@link BottomSheet} that will be opened as part of the new tab UI. * @param toolbar The {@link BottomToolbarPhone} that this controller will set state on as part * of the new tab UI. + * @param activity The {@link ChromeActivity} containing the {@link BottomSheet}. */ - public BottomSheetNewTabController(BottomSheet bottomSheet, BottomToolbarPhone toolbar) { + public BottomSheetNewTabController( + BottomSheet bottomSheet, BottomToolbarPhone toolbar, ChromeActivity activity) { mBottomSheet = bottomSheet; mBottomSheet.addObserver(this); mToolbar = toolbar; + mActivity = activity; } /** @@ -92,14 +96,19 @@ // Tell the model that a new tab may be added soon. mTabModelSelector.getModel(isIncognito).setIsPendingTabAdd(true); - // Select the correct model, immediately ending animations so that the sheet content is not - // in transition while the sheet is opening. + // Select the correct model, immediately ending animations so that the previous sheet + // content is not in use while calling #setIsPendingTabAdd() on previous model. if (mTabModelSelector.isIncognitoSelected() != isIncognito) { mTabModelSelector.selectModel(isIncognito); mBottomSheet.endTransitionAnimations(); mTabModelSelector.getModel(!isIncognito).setIsPendingTabAdd(false); } + // Select the correct sheet content, immediately ending animations so that the sheet content + // is not in transition while the sheet is opening. + mActivity.getBottomSheetContentController().selectItem(R.id.action_home); + mBottomSheet.endTransitionAnimations(); + // Open the sheet if it isn't already open to the desired height. int sheetState = mTabModelSelector.getCurrentModel().getCount() == 0 ? BottomSheet.SHEET_STATE_FULL
diff --git a/chrome/app/chrome_crash_reporter_client_win.cc b/chrome/app/chrome_crash_reporter_client_win.cc index b685bb3..857a0c54 100644 --- a/chrome/app/chrome_crash_reporter_client_win.cc +++ b/chrome/app/chrome_crash_reporter_client_win.cc
@@ -192,6 +192,9 @@ // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. // TODO(sunnyps): Remove after fixing https://crbug.com/622080 {kBeginMainFrameHangCompositorState, kSmallSize}, + + // TODO(asvitkine): Remove after fixing https://crbug.com/736675 + {"bad_histogram", kMediumSize}, }; // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 10fd4a7..a1d9afb7 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -903,6 +903,9 @@ <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS" desc="In Printing Settings, the title of the CUPS printers setting section."> Printers </message> + <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_LEARN_MORE_LABEL" desc="Label for the link that teaches users how to use CUPS printing."> + Set up or manage CUPS printers. + </message> <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER" desc="In CUPS printing settings subpage, text for the link adding a new CUPS printer."> Add Printer </message> @@ -913,7 +916,7 @@ Remove </message> <message name="IDS_SETTINGS_PRINTING_CUPS_SEARCH_LABEL" desc="The placeholder text in the printer search field."> - printer name + Search printers </message> <message name="IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_NEARBY_TITLE" desc="Text for the title of the dialog that is used to add nearby printers."> Add a nearby printer @@ -1027,9 +1030,6 @@ <message name="IDS_SETTINGS_PRINTING_CLOUD_PRINTERS" desc="In Printing Settings, the title of the google cloud printers setting section."> Google Cloud Print </message> - <message name="IDS_SETTINGS_PRINTING_CLOUD_PRINTERS_DESCRIPTION" desc="In Printing Settings, the title description of the google cloud printers setting section."> - Set up cloud printing devices - </message> <!-- Downloads Page --> <message name="IDS_SETTINGS_DOWNLOADS" desc="Name of the settings page which displays download preferences.">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 708a342c..0a47df1 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3184,10 +3184,6 @@ "feedback/system_logs/log_sources/crash_ids_source.h", "feedback/system_logs/log_sources/memory_details_log_source.cc", "feedback/system_logs/log_sources/memory_details_log_source.h", - "feedback/system_logs/system_logs_fetcher.cc", - "feedback/system_logs/system_logs_fetcher.h", - "feedback/system_logs/system_logs_source.cc", - "feedback/system_logs/system_logs_source.h", "first_run/first_run.cc", "first_run/first_run.h", "first_run/first_run_dialog.h", @@ -3402,6 +3398,8 @@ "resource_coordinator/tab_manager_grc_tab_signal_observer.h", "resource_coordinator/tab_manager_observer.cc", "resource_coordinator/tab_manager_observer.h", + "resource_coordinator/tab_manager_stats_collector.cc", + "resource_coordinator/tab_manager_stats_collector.h", "resource_coordinator/tab_manager_web_contents_data.cc", "resource_coordinator/tab_manager_web_contents_data.h", "resource_coordinator/tab_stats.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index a8556ccf..d2f4157a 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -771,6 +771,8 @@ switches::kTLS13VariantDraft}, {flag_descriptions::kTLS13VariantExperiment, switches::kTLS13Variant, switches::kTLS13VariantExperiment}, + {flag_descriptions::kTLS13VariantRecordTypeExperiment, + switches::kTLS13Variant, switches::kTLS13VariantRecordTypeExperiment}, }; #if !defined(OS_ANDROID)
diff --git a/chrome/browser/android/DEPS b/chrome/browser/android/DEPS index 8f032b7..6ba1166 100644 --- a/chrome/browser/android/DEPS +++ b/chrome/browser/android/DEPS
@@ -1,7 +1,6 @@ include_rules = [ "-components/devtools_bridge", "+cc/layers/layer.h", - "+cc/output/context_provider.h", "+chrome_jni_registration/chrome_jni_registration.h", "+components/doodle", "+components/ntp_snippets", @@ -9,6 +8,7 @@ "+components/sync/android", "+components/sync/test/fake_server/android", "+components/toolbar", + "+components/viz/common/gpu/context_provider.h", "+components/web_contents_delegate_android", "+device/vr/features/features.h", "+sandbox/linux/seccomp-bpf/sandbox_bpf.h",
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.cc b/chrome/browser/android/thumbnail/thumbnail_cache.cc index 354da956..c9cec7f 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.cc +++ b/chrome/browser/android/thumbnail/thumbnail_cache.cc
@@ -170,7 +170,10 @@ if (!ui_resource_provider_ || bitmap.empty() || thumbnail_scale <= 0) return; - DCHECK(thumbnail_meta_data_.find(tab_id) != thumbnail_meta_data_.end()); + if (thumbnail_meta_data_.find(tab_id) == thumbnail_meta_data_.end()) { + DVLOG(1) << "Thumbnail meta data was removed for tab id " << tab_id; + return; + } base::Time time_stamp = thumbnail_meta_data_[tab_id].capture_time(); std::unique_ptr<Thumbnail> thumbnail = Thumbnail::Create(
diff --git a/chrome/browser/android/vr_shell/mailbox_to_surface_bridge.cc b/chrome/browser/android/vr_shell/mailbox_to_surface_bridge.cc index 2fc7c70..14cd5d2 100644 --- a/chrome/browser/android/vr_shell/mailbox_to_surface_bridge.cc +++ b/chrome/browser/android/vr_shell/mailbox_to_surface_bridge.cc
@@ -10,7 +10,7 @@ #include "base/memory/ptr_util.h" #include "base/sys_info.h" #include "base/threading/sequenced_task_runner_handle.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "content/public/browser/android/compositor.h" #include "content/public/browser/browser_thread.h" #include "gpu/GLES2/gl2extchromium.h" @@ -151,13 +151,13 @@ void MailboxToSurfaceBridge::OnContextAvailable( std::unique_ptr<gl::ScopedJavaSurface> surface, - scoped_refptr<cc::ContextProvider> provider) { - // Must save a reference to the ContextProvider to keep it alive, + scoped_refptr<viz::ContextProvider> provider) { + // Must save a reference to the viz::ContextProvider to keep it alive, // otherwise the GL context created from it becomes invalid. context_provider_ = std::move(provider); if (!context_provider_->BindToCurrentThread()) { - DLOG(ERROR) << "Failed to init ContextProvider"; + DLOG(ERROR) << "Failed to init viz::ContextProvider"; return; } @@ -194,7 +194,7 @@ auto relay_callback = base::Bind( [](scoped_refptr<base::SequencedTaskRunner> runner, const content::Compositor::ContextProviderCallback& callback, - scoped_refptr<cc::ContextProvider> provider) { + scoped_refptr<viz::ContextProvider> provider) { runner->PostTask(FROM_HERE, base::Bind(callback, std::move(provider))); },
diff --git a/chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h b/chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h index 1704de32..ce94fef 100644 --- a/chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h +++ b/chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h
@@ -19,7 +19,7 @@ } } -namespace cc { +namespace viz { class ContextProvider; } @@ -41,12 +41,12 @@ private: void OnContextAvailable(std::unique_ptr<gl::ScopedJavaSurface> surface, - scoped_refptr<cc::ContextProvider>); + scoped_refptr<viz::ContextProvider>); void InitializeRenderer(); void DestroyContext(); void DrawQuad(unsigned int textureHandle); - scoped_refptr<cc::ContextProvider> context_provider_; + scoped_refptr<viz::ContextProvider> context_provider_; gpu::gles2::GLES2Interface* gl_ = nullptr; int surface_handle_ = 0;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 95774ff..dd0309b 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -195,6 +195,7 @@ #include "device/usb/public/interfaces/chooser_service.mojom.h" #include "device/usb/public/interfaces/device_manager.mojom.h" #include "extensions/features/features.h" +#include "google_apis/gaia/gaia_urls.h" #include "gpu/config/gpu_switches.h" #include "media/audio/audio_manager.h" #include "media/media_features.h" @@ -1401,6 +1402,16 @@ return !url.SchemeIs(chrome::kChromeNativeScheme); } +std::vector<url::Origin> +ChromeContentBrowserClient::GetOriginsRequiringDedicatedProcess() { + std::vector<url::Origin> isolated_origin_list; + + if (base::FeatureList::IsEnabled(features::kSignInProcessIsolation)) + isolated_origin_list.emplace_back(GaiaUrls::GetInstance()->gaia_url()); + + return isolated_origin_list; +} + namespace { bool IsAutoReloadEnabled() {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index dc4aba0..e45c8e2 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -131,6 +131,7 @@ const GURL& current_url, const GURL& new_url) override; bool ShouldAssignSiteForURL(const GURL& url) override; + std::vector<url::Origin> GetOriginsRequiringDedicatedProcess() override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; std::string GetApplicationLocale() override;
diff --git a/chrome/browser/chrome_navigation_browsertest.cc b/chrome/browser/chrome_navigation_browsertest.cc index c9251da1..9add49e 100644 --- a/chrome/browser/chrome_navigation_browsertest.cc +++ b/chrome/browser/chrome_navigation_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/command_line.h" +#include "base/test/scoped_feature_list.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" @@ -11,17 +12,20 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/network_session_configurator/common/network_switches.h" #include "components/url_formatter/url_formatter.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/context_menu_params.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" +#include "google_apis/gaia/gaia_switches.h" #include "net/dns/mock_host_resolver.h" class ChromeNavigationBrowserTest : public InProcessBrowserTest { @@ -436,3 +440,70 @@ EXPECT_FALSE(navigation_observer.was_same_document()); EXPECT_FALSE(navigation_observer.was_renderer_initiated()); } + +class SignInIsolationBrowserTest : public ChromeNavigationBrowserTest { + public: + SignInIsolationBrowserTest() + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} + ~SignInIsolationBrowserTest() override {} + + void SetUp() override { + feature_list_.InitAndEnableFeature(features::kSignInProcessIsolation); + https_server_.ServeFilesFromSourceDirectory("chrome/test/data"); + ASSERT_TRUE(https_server_.InitializeAndListen()); + ChromeNavigationBrowserTest::SetUp(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + // Override the sign-in URL so that it includes correct port from the test + // server. + command_line->AppendSwitchASCII( + ::switches::kGaiaUrl, + https_server()->GetURL("accounts.google.com", "/").spec()); + + // Ignore cert errors so that the sign-in URL can be loaded from a site + // other than localhost (the EmbeddedTestServer serves a certificate that + // is valid for localhost). + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); + + ChromeNavigationBrowserTest::SetUpCommandLine(command_line); + } + + void SetUpOnMainThread() override { + host_resolver()->AddRule("*", "127.0.0.1"); + https_server_.StartAcceptingConnections(); + ChromeNavigationBrowserTest::SetUpOnMainThread(); + } + + net::EmbeddedTestServer* https_server() { return &https_server_; } + + private: + base::test::ScopedFeatureList feature_list_; + net::EmbeddedTestServer https_server_; + + DISALLOW_COPY_AND_ASSIGN(SignInIsolationBrowserTest); +}; + +// This test ensures that the sign-in origin requires a dedicated process. It +// only ensures that the corresponding base::Feature works properly; +// IsolatedOriginTest provides the main test coverage of origins whitelisted +// for process isolation. See https://crbug.com/739418. +IN_PROC_BROWSER_TEST_F(SignInIsolationBrowserTest, NavigateToSignInPage) { + const GURL first_url = + embedded_test_server()->GetURL("google.com", "/title1.html"); + const GURL signin_url = + https_server()->GetURL("accounts.google.com", "/title1.html"); + ui_test_utils::NavigateToURL(browser(), first_url); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + scoped_refptr<content::SiteInstance> first_instance( + web_contents->GetMainFrame()->GetSiteInstance()); + + // Make sure that a renderer-initiated navigation to the sign-in page swaps + // processes. + content::TestNavigationManager manager(web_contents, signin_url); + EXPECT_TRUE( + ExecuteScript(web_contents, "location = '" + signin_url.spec() + "';")); + manager.WaitForNavigationFinished(); + EXPECT_NE(web_contents->GetMainFrame()->GetSiteInstance(), first_instance); +}
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index d5a988f..1ec4119 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1327,14 +1327,14 @@ "printing/printer_configurer.h", "printing/printer_detector.h", "printing/printer_info.h", - "printing/printers_manager.cc", - "printing/printers_manager.h", - "printing/printers_manager_factory.cc", - "printing/printers_manager_factory.h", "printing/printers_sync_bridge.cc", "printing/printers_sync_bridge.h", "printing/specifics_translation.cc", "printing/specifics_translation.h", + "printing/synced_printers_manager.cc", + "printing/synced_printers_manager.h", + "printing/synced_printers_manager_factory.cc", + "printing/synced_printers_manager_factory.h", "printing/usb_printer_detector.cc", "printing/usb_printer_detector.h", "printing/usb_printer_detector_factory.cc", @@ -1847,8 +1847,8 @@ "power/renderer_freezer_unittest.cc", "preferences_unittest.cc", "printing/combining_printer_detector_unittest.cc", - "printing/printers_manager_unittest.cc", "printing/specifics_translation_unittest.cc", + "printing/synced_printers_manager_unittest.cc", "profiles/profile_list_chromeos_unittest.cc", "proxy_config_service_impl_unittest.cc", "resource_reporter/resource_reporter_unittest.cc", @@ -1887,6 +1887,7 @@ "../ui/webui/chromeos/login/l10n_util_unittest.cc", "../ui/webui/chromeos/login/oobe_display_chooser_unittest.cc", "../ui/webui/chromeos/login/signin_userlist_unittest.cc", + "../ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc", "../ui/webui/settings/chromeos/device_power_handler_unittest.cc", "../ui/webui/settings/chromeos/easy_unlock_settings_handler_unittest.cc", "//components/drive/change_list_loader_unittest.cc",
diff --git a/chrome/browser/chromeos/lock_screen_apps/note_taking_browsertest.cc b/chrome/browser/chromeos/lock_screen_apps/note_taking_browsertest.cc index e3888c69a..08b7545 100644 --- a/chrome/browser/chromeos/lock_screen_apps/note_taking_browsertest.cc +++ b/chrome/browser/chromeos/lock_screen_apps/note_taking_browsertest.cc
@@ -44,6 +44,73 @@ ash::mojom::TrayActionState::kAvailable; } + bool RunTestAppInLockScreenContext(const std::string& test_app, + std::string* error) { + scoped_refptr<const extensions::Extension> app = + LoadExtension(test_data_dir_.AppendASCII(test_app)); + if (!app) { + *error = "Unable to load the test app."; + return false; + } + + if (!EnableLockScreenAppLaunch(app->id())) { + *error = "Failed to enable app for lock screen."; + return false; + } + + // The test app will send "readyToClose" message from the app window created + // as part of the test. The message will be sent after the tests in the app + // window context have been run and the window is ready to be closed. + // The test should reply to this message in order for the app window to + // close itself. + ExtensionTestMessageListener ready_to_close("readyToClose", + true /* will_reply */); + + extensions::ResultCatcher catcher; + lock_screen_apps::StateController::Get()->RequestNewLockScreenNote(); + + if (lock_screen_apps::StateController::Get()->GetLockScreenNoteState() != + ash::mojom::TrayActionState::kLaunching) { + *error = "App launch request failed"; + return false; + } + + // The test will run two sets of tests: + // * in the window that gets created as the response to the new_note action + // launch + // * in the app background page - the test will launch an app window and + // wait for it to be closed + // Test runner should wait for both of those to finish (test result message + // will be sent for each set of tests). + if (!catcher.GetNextResult()) { + *error = catcher.message(); + if (ready_to_close.was_satisfied()) + ready_to_close.Reply("failed"); + return false; + } + + if (lock_screen_apps::StateController::Get()->GetLockScreenNoteState() != + ash::mojom::TrayActionState::kActive) { + *error = "App not in active state."; + return false; + } + + if (!ready_to_close.WaitUntilSatisfied()) { + *error = "Failed waiting for readyToClose message."; + return false; + } + + // Close the app window created by the API test. + ready_to_close.Reply("close"); + + if (!catcher.GetNextResult()) { + *error = catcher.message(); + return false; + } + + return true; + } + private: DISALLOW_COPY_AND_ASSIGN(LockScreenNoteTakingTest); }; @@ -53,42 +120,10 @@ IN_PROC_BROWSER_TEST_F(LockScreenNoteTakingTest, Launch) { ASSERT_TRUE(lock_screen_apps::StateController::IsEnabled()); - scoped_refptr<const extensions::Extension> app = - LoadExtension(test_data_dir_.AppendASCII("lock_screen_apps/app_launch")); - ASSERT_TRUE(app); - ASSERT_TRUE(EnableLockScreenAppLaunch(app->id())); - - // The test app will send "readyToClose" message from the app window created - // as part of the test. The message will be sent after the tests in the app - // window context have been run and the window is ready to be closed. - // The test should reply to this message in order for the app window to close - // itself. - ExtensionTestMessageListener ready_to_close("readyToClose", - true /* will_reply */); - - extensions::ResultCatcher catcher; - lock_screen_apps::StateController::Get()->RequestNewLockScreenNote(); - - ASSERT_EQ(ash::mojom::TrayActionState::kLaunching, - lock_screen_apps::StateController::Get()->GetLockScreenNoteState()); - - // The test will run two sets of tests: - // * in the window that gets created as the response to the new_note action - // launch - // * in the app background page - the test will launch an app window and wait - // for it to be closed - // Test runner should wait for both of those to finish (test result message - // will be sent for each set of tests). - ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); - - ASSERT_EQ(ash::mojom::TrayActionState::kActive, - lock_screen_apps::StateController::Get()->GetLockScreenNoteState()); - - ASSERT_TRUE(ready_to_close.WaitUntilSatisfied()); - // Close the app window created by the API test. - ready_to_close.Reply("close"); - - ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); + std::string error_message; + ASSERT_TRUE(RunTestAppInLockScreenContext("lock_screen_apps/app_launch", + &error_message)) + << error_message; EXPECT_EQ(ash::mojom::TrayActionState::kAvailable, lock_screen_apps::StateController::Get()->GetLockScreenNoteState()); @@ -128,3 +163,47 @@ ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); } + +IN_PROC_BROWSER_TEST_F(LockScreenNoteTakingTest, DataCreation) { + ASSERT_TRUE(lock_screen_apps::StateController::IsEnabled()); + + std::string error_message; + ASSERT_TRUE(RunTestAppInLockScreenContext("lock_screen_apps/data_provider", + &error_message)) + << error_message; + + EXPECT_EQ(ash::mojom::TrayActionState::kAvailable, + lock_screen_apps::StateController::Get()->GetLockScreenNoteState()); + + extensions::ResultCatcher catcher; + session_manager::SessionManager::Get()->SetSessionState( + session_manager::SessionState::ACTIVE); + + // Unlocking the session should trigger onDataItemsAvailable event, which + // should be catched by the background page in the main app - the event should + // start another test sequence. + ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); +} + +IN_PROC_BROWSER_TEST_F(LockScreenNoteTakingTest, PRE_DataAvailableOnRestart) { + ASSERT_TRUE(lock_screen_apps::StateController::IsEnabled()); + + std::string error_message; + ASSERT_TRUE(RunTestAppInLockScreenContext("lock_screen_apps/data_provider", + &error_message)) + << error_message; + + EXPECT_EQ(ash::mojom::TrayActionState::kAvailable, + lock_screen_apps::StateController::Get()->GetLockScreenNoteState()); +} + +IN_PROC_BROWSER_TEST_F(LockScreenNoteTakingTest, DataAvailableOnRestart) { + // In PRE_ part of the test there were data items created in the lock screen + // storage - when the lock screen note taking is initialized, + // OnDataItemsAvailable should be dispatched to the test app (given that the + // lock screen app's data storage is not empty), which should in turn run a + // sequence of API tests (in the test app background page). + // This test is intended to catch the result of these tests. + extensions::ResultCatcher catcher; + ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); +}
diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller.cc b/chrome/browser/chromeos/lock_screen_apps/state_controller.cc index 07e92a6..f0c02d1 100644 --- a/chrome/browser/chromeos/lock_screen_apps/state_controller.cc +++ b/chrome/browser/chromeos/lock_screen_apps/state_controller.cc
@@ -7,20 +7,26 @@ #include <utility> #include "ash/public/interfaces/constants.mojom.h" +#include "base/base64.h" #include "base/bind.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" +#include "base/path_service.h" #include "base/strings/string16.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/lock_screen_apps/app_manager_impl.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/session_manager/core/session_manager.h" #include "content/public/common/service_manager_connection.h" +#include "crypto/symmetric_key.h" +#include "extensions/browser/api/lock_screen_data/lock_screen_item_storage.h" #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/native_app_window.h" #include "extensions/common/extension.h" @@ -34,8 +40,21 @@ namespace { +// Key for user pref that contains the 256 bit AES key that should be used to +// encrypt persisted user data created on the lock screen. +constexpr char kDataCryptoKeyPref[] = "lockScreenAppDataCryptoKey"; + StateController* g_instance = nullptr; +// Generates a random 256 bit AES key. Returns an empty string on error. +std::string GenerateCryptoKey() { + std::unique_ptr<crypto::SymmetricKey> symmetric_key = + crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 256); + if (!symmetric_key) + return ""; + return symmetric_key->key(); +} + } // namespace // static @@ -50,6 +69,11 @@ return g_instance; } +// static +void StateController::RegisterProfilePrefs(PrefRegistrySimple* registry) { + registry->RegisterStringPref(kDataCryptoKeyPref, ""); +} + StateController::StateController() : binding_(this), app_window_observer_(this), @@ -114,6 +138,7 @@ void StateController::Shutdown() { session_observer_.RemoveAll(); + lock_screen_data_.reset(); if (app_manager_) { app_manager_->Stop(); ResetNoteTakingWindowAndMoveToNextState(true /*close_window*/); @@ -146,11 +171,49 @@ lock_screen_profile_->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true); + std::string key; + if (!GetUserCryptoKey(primary_profile, &key)) { + LOG(ERROR) << "Failed to get crypto key for user lock screen apps."; + return; + } + + InitializeWithCryptoKey(primary_profile, key); +} + +bool StateController::GetUserCryptoKey(Profile* profile, std::string* key) { + *key = profile->GetPrefs()->GetString(kDataCryptoKeyPref); + if (!key->empty() && base::Base64Decode(*key, key)) + return true; + + *key = GenerateCryptoKey(); + + if (key->empty()) + return false; + + std::string base64_encoded_key; + base::Base64Encode(*key, &base64_encoded_key); + + profile->GetPrefs()->SetString(kDataCryptoKeyPref, base64_encoded_key); + return true; +} + +void StateController::InitializeWithCryptoKey(Profile* profile, + const std::string& crypto_key) { + base::FilePath base_path; + if (!base::PathService::Get(chrome::DIR_USER_DATA, &base_path)) { + LOG(ERROR) << "Failed to get base storage dir for lock screen app data."; + return; + } + + lock_screen_data_ = + base::MakeUnique<extensions::lock_screen_data::LockScreenItemStorage>( + profile, g_browser_process->local_state(), crypto_key, + base_path.AppendASCII("lock_screen_app_data")); + // App manager might have been set previously by a test. if (!app_manager_) app_manager_ = base::MakeUnique<AppManagerImpl>(); - app_manager_->Initialize(primary_profile, - lock_screen_profile->GetOriginalProfile()); + app_manager_->Initialize(profile, lock_screen_profile_->GetOriginalProfile()); input_devices_observer_.Add(ui::InputDeviceManager::GetInstance()); power_manager_client_observer_.Add( @@ -192,6 +255,7 @@ void StateController::OnSessionStateChanged() { if (!session_manager::SessionManager::Get()->IsScreenLocked()) { + lock_screen_data_->SetSessionLocked(false); app_manager_->Stop(); ResetNoteTakingWindowAndMoveToNextState(true /*close_window*/); return; @@ -203,6 +267,7 @@ app_manager_->Start( base::Bind(&StateController::OnNoteTakingAvailabilityChanged, base::Unretained(this))); + lock_screen_data_->SetSessionLocked(true); OnNoteTakingAvailabilityChanged(); }
diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller.h b/chrome/browser/chromeos/lock_screen_apps/state_controller.h index 016e220..8893e6fa 100644 --- a/chrome/browser/chromeos/lock_screen_apps/state_controller.h +++ b/chrome/browser/chromeos/lock_screen_apps/state_controller.h
@@ -6,8 +6,10 @@ #define CHROME_BROWSER_CHROMEOS_LOCK_SCREEN_APPS_STATE_CONTROLLER_H_ #include <memory> +#include <string> #include "ash/public/interfaces/tray_action.mojom.h" +#include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/scoped_observer.h" @@ -21,6 +23,8 @@ #include "mojo/public/cpp/bindings/binding.h" #include "ui/events/devices/input_device_event_observer.h" +class PrefRegistrySimple; + namespace content { class BrowserContext; } @@ -29,6 +33,10 @@ class AppDelegate; class AppWindow; class Extension; + +namespace lock_screen_data { +class LockScreenItemStorage; +} } // namespace extensions namespace session_manager { @@ -61,6 +69,8 @@ // nullptr when lock screen apps are not enabled (see |IsEnabled|). static StateController* Get(); + static void RegisterProfilePrefs(PrefRegistrySimple* pref_registry); + // Note that only one StateController is allowed per process. Creating a // StateController will set global instance ptr that can be accessed using // |Get|. This pointer will be reset when the StateController is destroyed. @@ -145,6 +155,18 @@ Profile* lock_screen_profile, Profile::CreateStatus status); + // Gets the encryption key that should be used to encrypt user data created on + // the lock screen. If a key hadn't previously been created and saved to + // user prefs, a new key is created and saved. + // |crypto_key| - the found/created key. + // Returns whether |crypto_key| was successfully retrieved. + bool GetUserCryptoKey(Profile* profile, std::string* crypto_key); + + // Finishes lock screen apps initialization with primary user profile and + // associated encryption key to be used for encrypting user data created in + // lock screen context. + void InitializeWithCryptoKey(Profile* profile, const std::string& crypto_key); + // Called when app manager reports that note taking availability has changed. void OnNoteTakingAvailabilityChanged(); @@ -172,6 +194,9 @@ Profile* lock_screen_profile_ = nullptr; + std::unique_ptr<extensions::lock_screen_data::LockScreenItemStorage> + lock_screen_data_; + std::unique_ptr<AppManager> app_manager_; extensions::AppWindow* note_app_window_ = nullptr;
diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc b/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc index 714f20f..958884a 100644 --- a/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc +++ b/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc
@@ -10,6 +10,7 @@ #include <vector> #include "ash/public/interfaces/tray_action.mojom.h" +#include "base/base64.h" #include "base/files/file_path.h" #include "base/memory/ptr_util.h" #include "base/test/scoped_command_line.h" @@ -29,8 +30,10 @@ #include "components/session_manager/core/session_manager.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" #include "content/public/test/web_contents_tester.h" +#include "extensions/browser/api/lock_screen_data/lock_screen_item_storage.h" #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window_contents.h" #include "extensions/browser/app_window/native_app_window.h" @@ -45,6 +48,7 @@ using ash::mojom::TrayActionState; using extensions::DictionaryBuilder; using extensions::ListBuilder; +using extensions::lock_screen_data::LockScreenItemStorage; namespace { @@ -55,6 +59,9 @@ // The primary tesing profile. const char kPrimaryProfileName[] = "primary_profile"; +// Key for pref containing lock screen data crypto key. +constexpr char kDataCryptoKeyPref[] = "lockScreenAppDataCryptoKey"; + scoped_refptr<extensions::Extension> CreateTestNoteTakingApp( const std::string& app_id) { ListBuilder action_handlers; @@ -339,6 +346,7 @@ BrowserWithTestWindowTest::SetUp(); session_manager_ = base::MakeUnique<session_manager::SessionManager>(); + session_manager_->SessionStarted(); session_manager_->SetSessionState( session_manager::SessionState::LOGIN_PRIMARY); @@ -602,6 +610,78 @@ ExpectObservedStatesMatch({TrayActionState::kAvailable}, "Available on lock"); } +TEST_F(LockScreenAppStateTest, InitLockScreenDataLockScreenItemStorage) { + EXPECT_EQ(TestAppManager::State::kNotInitialized, app_manager()->state()); + SetPrimaryProfileAndWaitUntilReady(); + + LockScreenItemStorage* lock_screen_item_storage = + LockScreenItemStorage::GetIfAllowed(profile()); + ASSERT_TRUE(lock_screen_item_storage); + + std::string crypto_key_in_prefs = + profile()->GetPrefs()->GetString(kDataCryptoKeyPref); + ASSERT_FALSE(crypto_key_in_prefs.empty()); + ASSERT_TRUE(base::Base64Decode(crypto_key_in_prefs, &crypto_key_in_prefs)); + + EXPECT_EQ(crypto_key_in_prefs, + lock_screen_item_storage->crypto_key_for_testing()); + + session_manager()->SetSessionState(session_manager::SessionState::LOCKED); + + EXPECT_FALSE(LockScreenItemStorage::GetIfAllowed(profile())); + EXPECT_TRUE(LockScreenItemStorage::GetIfAllowed(lock_screen_profile())); +} + +TEST_F(LockScreenAppStateTest, + InitLockScreenDataLockScreenItemStorageWhileLocked) { + EXPECT_EQ(TestAppManager::State::kNotInitialized, app_manager()->state()); + session_manager()->SetSessionState(session_manager::SessionState::LOCKED); + SetPrimaryProfileAndWaitUntilReady(); + + EXPECT_FALSE(LockScreenItemStorage::GetIfAllowed(profile())); + + LockScreenItemStorage* lock_screen_item_storage = + LockScreenItemStorage::GetIfAllowed(lock_screen_profile()); + ASSERT_TRUE(lock_screen_item_storage); + + std::string crypto_key_in_prefs = + profile()->GetPrefs()->GetString(kDataCryptoKeyPref); + ASSERT_FALSE(crypto_key_in_prefs.empty()); + ASSERT_TRUE(base::Base64Decode(crypto_key_in_prefs, &crypto_key_in_prefs)); + + EXPECT_EQ(crypto_key_in_prefs, + lock_screen_item_storage->crypto_key_for_testing()); + + session_manager()->SetSessionState(session_manager::SessionState::ACTIVE); + + EXPECT_TRUE(LockScreenItemStorage::GetIfAllowed(profile())); + EXPECT_FALSE(LockScreenItemStorage::GetIfAllowed(lock_screen_profile())); +} + +TEST_F(LockScreenAppStateTest, + InitLockScreenDataLockScreenItemStorage_CryptoKeyExists) { + std::string crypto_key_in_prefs = "0123456789ABCDEF0123456789ABCDEF"; + std::string crypto_key_in_prefs_encoded; + base::Base64Encode(crypto_key_in_prefs, &crypto_key_in_prefs_encoded); + + profile()->GetPrefs()->SetString(kDataCryptoKeyPref, + crypto_key_in_prefs_encoded); + + SetPrimaryProfileAndWaitUntilReady(); + + LockScreenItemStorage* lock_screen_item_storage = + LockScreenItemStorage::GetIfAllowed(profile()); + ASSERT_TRUE(lock_screen_item_storage); + + EXPECT_EQ(crypto_key_in_prefs, + lock_screen_item_storage->crypto_key_for_testing()); + + session_manager()->SetSessionState(session_manager::SessionState::LOCKED); + + EXPECT_FALSE(LockScreenItemStorage::GetIfAllowed(profile())); + EXPECT_TRUE(LockScreenItemStorage::GetIfAllowed(lock_screen_profile())); +} + TEST_F(LockScreenAppStateTest, SessionLock) { app_manager()->SetInitialAppState(kTestAppId, true); SetPrimaryProfileAndWaitUntilReady();
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index efbda30b..2b54234f 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -214,6 +214,7 @@ chromeos::switches::kEnterpriseDisableArc, chromeos::switches::kEnterpriseEnableForcedReEnrollment, chromeos::switches::kHasChromeOSDiamondKey, + chromeos::switches::kHasChromeOSKeyboard, chromeos::switches::kLoginProfile, chromeos::switches::kNaturalScrollDefault, chromeos::switches::kShowMdLogin,
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_factory.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_factory.cc index 46b0ab9..a510a06 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_factory.cc +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_factory.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/chromeos/printing/cups_print_job_manager_factory.h" #include "chrome/browser/chromeos/printing/cups_print_job_manager.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -39,7 +39,7 @@ : BrowserContextKeyedServiceFactory( "CupsPrintJobManagerFactory", BrowserContextDependencyManager::GetInstance()) { - DependsOn(chromeos::PrintersManagerFactory::GetInstance()); + DependsOn(chromeos::SyncedPrintersManagerFactory::GetInstance()); } CupsPrintJobManagerFactory::~CupsPrintJobManagerFactory() {}
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc index f6bcfc0..7f0ad07 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
@@ -22,8 +22,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/printing/cups_print_job.h" -#include "chrome/browser/chromeos/printing/printers_manager.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/printing/print_job.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_context.h" @@ -336,9 +336,8 @@ int total_page_number) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - auto printer = - PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinter( - printer_name); + auto printer = SyncedPrintersManagerFactory::GetForBrowserContext(profile_) + ->GetPrinter(printer_name); if (!printer) { LOG(WARNING) << "Printer was removed while job was in progress. It cannot "
diff --git a/chrome/browser/chromeos/printing/printers_manager_factory.h b/chrome/browser/chromeos/printing/printers_manager_factory.h deleted file mode 100644 index 0991677..0000000 --- a/chrome/browser/chromeos/printing/printers_manager_factory.h +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MANAGER_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MANAGER_FACTORY_H_ - -#include "base/lazy_instance.h" -#include "base/macros.h" -#include "chrome/browser/chromeos/printing/printers_manager.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace content { -class BrowserContext; -} - -namespace chromeos { - -class PrintersManagerFactory : public BrowserContextKeyedServiceFactory { - public: - static PrintersManager* GetForBrowserContext( - content::BrowserContext* context); - - static PrintersManagerFactory* GetInstance(); - - protected: - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - - private: - friend struct base::LazyInstanceTraitsBase<PrintersManagerFactory>; - - PrintersManagerFactory(); - ~PrintersManagerFactory() override; - - // BrowserContextKeyedServiceFactory implementation: - PrintersManager* BuildServiceInstanceFor( - content::BrowserContext* browser_context) const override; - - DISALLOW_COPY_AND_ASSIGN(PrintersManagerFactory); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MANAGER_FACTORY_H_
diff --git a/chrome/browser/chromeos/printing/printers_manager.cc b/chrome/browser/chromeos/printing/synced_printers_manager.cc similarity index 86% rename from chrome/browser/chromeos/printing/printers_manager.cc rename to chrome/browser/chromeos/printing/synced_printers_manager.cc index 19d632ae..16e9b9e 100644 --- a/chrome/browser/chromeos/printing/printers_manager.cc +++ b/chrome/browser/chromeos/printing/synced_printers_manager.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 "chrome/browser/chromeos/printing/printers_manager.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" #include <memory> #include <string> @@ -51,29 +51,30 @@ } // anonymous namespace -PrintersManager::PrintersManager( +SyncedPrintersManager::SyncedPrintersManager( Profile* profile, std::unique_ptr<PrintersSyncBridge> sync_bridge) : profile_(profile), sync_bridge_(std::move(sync_bridge)) { pref_change_registrar_.Init(profile->GetPrefs()); pref_change_registrar_.Add( prefs::kRecommendedNativePrinters, - base::Bind(&PrintersManager::UpdateRecommendedPrinters, + base::Bind(&SyncedPrintersManager::UpdateRecommendedPrinters, base::Unretained(this))); UpdateRecommendedPrinters(); } -PrintersManager::~PrintersManager() {} +SyncedPrintersManager::~SyncedPrintersManager() {} // static -void PrintersManager::RegisterProfilePrefs( +void SyncedPrintersManager::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterListPref(prefs::kPrintingDevices, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterListPref(prefs::kRecommendedNativePrinters); } -std::vector<std::unique_ptr<Printer>> PrintersManager::GetPrinters() const { +std::vector<std::unique_ptr<Printer>> SyncedPrintersManager::GetPrinters() + const { std::vector<std::unique_ptr<Printer>> printers; std::vector<sync_pb::PrinterSpecifics> values = @@ -85,8 +86,8 @@ return printers; } -std::vector<std::unique_ptr<Printer>> PrintersManager::GetRecommendedPrinters() - const { +std::vector<std::unique_ptr<Printer>> +SyncedPrintersManager::GetRecommendedPrinters() const { std::vector<std::unique_ptr<Printer>> printers; for (const std::string& key : recommended_printer_ids_) { @@ -99,7 +100,7 @@ return printers; } -std::unique_ptr<Printer> PrintersManager::GetPrinter( +std::unique_ptr<Printer> SyncedPrintersManager::GetPrinter( const std::string& printer_id) const { // check for a policy printer first const auto& policy_printers = recommended_printers_; @@ -114,7 +115,7 @@ return printer.has_value() ? printing::SpecificsToPrinter(*printer) : nullptr; } -void PrintersManager::RegisterPrinter(std::unique_ptr<Printer> printer) { +void SyncedPrintersManager::RegisterPrinter(std::unique_ptr<Printer> printer) { if (printer->id().empty()) { printer->set_id(base::GenerateGUID()); } @@ -134,7 +135,7 @@ } } -bool PrintersManager::RemovePrinter(const std::string& printer_id) { +bool SyncedPrintersManager::RemovePrinter(const std::string& printer_id) { DCHECK(!printer_id.empty()); base::Optional<sync_pb::PrinterSpecifics> printer = @@ -155,21 +156,21 @@ return success; } -void PrintersManager::AddObserver(Observer* observer) { +void SyncedPrintersManager::AddObserver(Observer* observer) { observers_.AddObserver(observer); } -void PrintersManager::RemoveObserver(Observer* observer) { +void SyncedPrintersManager::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } -PrintersSyncBridge* PrintersManager::GetSyncBridge() { +PrintersSyncBridge* SyncedPrintersManager::GetSyncBridge() { return sync_bridge_.get(); } // This method is not thread safe and could interact poorly with readers of // |recommended_printers_|. -void PrintersManager::UpdateRecommendedPrinters() { +void SyncedPrintersManager::UpdateRecommendedPrinters() { const PrefService* prefs = profile_->GetPrefs(); const base::ListValue* values = @@ -227,12 +228,13 @@ recommended_printers_.swap(new_printers); } -void PrintersManager::PrinterInstalled(const Printer& printer) { +void SyncedPrintersManager::PrinterInstalled(const Printer& printer) { DCHECK(!printer.last_updated().is_null()); installed_printer_timestamps_[printer.id()] = printer.last_updated(); } -bool PrintersManager::IsConfigurationCurrent(const Printer& printer) const { +bool SyncedPrintersManager::IsConfigurationCurrent( + const Printer& printer) const { auto found = installed_printer_timestamps_.find(printer.id()); if (found == installed_printer_timestamps_.end()) return false;
diff --git a/chrome/browser/chromeos/printing/printers_manager.h b/chrome/browser/chromeos/printing/synced_printers_manager.h similarity index 82% rename from chrome/browser/chromeos/printing/printers_manager.h rename to chrome/browser/chromeos/printing/synced_printers_manager.h index 6e05cddd..5a537f1 100644 --- a/chrome/browser/chromeos/printing/printers_manager.h +++ b/chrome/browser/chromeos/printing/synced_printers_manager.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 CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MANAGER_H_ -#define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MANAGER_H_ +#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_SYNCED_PRINTERS_MANAGER_H_ +#define CHROME_BROWSER_CHROMEOS_PRINTING_SYNCED_PRINTERS_MANAGER_H_ #include <map> #include <memory> @@ -26,10 +26,11 @@ namespace chromeos { -// Manages printer information. Provides an interface to a user's printers and +// Manages information about synced local printers classes (CONFIGURED +// and ENTERPRISE). Provides an interface to a user's printers and // printers provided by policy. User printers are backed by the // PrintersSyncBridge. -class PrintersManager : public KeyedService { +class SyncedPrintersManager : public KeyedService { public: class Observer { public: @@ -38,9 +39,9 @@ virtual void OnPrinterRemoved(const Printer& printer) = 0; }; - PrintersManager(Profile* profile, - std::unique_ptr<PrintersSyncBridge> sync_bridge); - ~PrintersManager() override; + SyncedPrintersManager(Profile* profile, + std::unique_ptr<PrintersSyncBridge> sync_bridge); + ~SyncedPrintersManager() override; // Register the printing preferences with the |registry|. static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); @@ -68,11 +69,11 @@ // live on the same thread (UI) as this object. OnPrinter* methods are // invoked inline so calling RegisterPrinter in response to OnPrinterAdded is // forbidden. - void AddObserver(PrintersManager::Observer* observer); + void AddObserver(SyncedPrintersManager::Observer* observer); // Remove |observer| so that it no longer receives notifications. After the // completion of this method, the |observer| can be safely destroyed. - void RemoveObserver(PrintersManager::Observer* observer); + void RemoveObserver(SyncedPrintersManager::Observer* observer); // Returns a ModelTypeSyncBridge for the sync client. PrintersSyncBridge* GetSyncBridge(); @@ -104,9 +105,9 @@ base::ObserverList<Observer> observers_; - DISALLOW_COPY_AND_ASSIGN(PrintersManager); + DISALLOW_COPY_AND_ASSIGN(SyncedPrintersManager); }; } // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MANAGER_H_ +#endif // CHROME_BROWSER_CHROMEOS_PRINTING_SYNCED_PRINTERS_MANAGER_H_
diff --git a/chrome/browser/chromeos/printing/printers_manager_factory.cc b/chrome/browser/chromeos/printing/synced_printers_manager_factory.cc similarity index 66% rename from chrome/browser/chromeos/printing/printers_manager_factory.cc rename to chrome/browser/chromeos/printing/synced_printers_manager_factory.cc index 5f8de867..3c112102 100644 --- a/chrome/browser/chromeos/printing/printers_manager_factory.cc +++ b/chrome/browser/chromeos/printing/synced_printers_manager_factory.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 "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include <memory> #include <utility> @@ -22,36 +22,36 @@ namespace { -base::LazyInstance<PrintersManagerFactory>::DestructorAtExit +base::LazyInstance<SyncedPrintersManagerFactory>::DestructorAtExit g_printers_manager = LAZY_INSTANCE_INITIALIZER; } // namespace // static -PrintersManager* PrintersManagerFactory::GetForBrowserContext( +SyncedPrintersManager* SyncedPrintersManagerFactory::GetForBrowserContext( content::BrowserContext* context) { - return static_cast<PrintersManager*>( + return static_cast<SyncedPrintersManager*>( GetInstance()->GetServiceForBrowserContext(context, true)); } // static -PrintersManagerFactory* PrintersManagerFactory::GetInstance() { +SyncedPrintersManagerFactory* SyncedPrintersManagerFactory::GetInstance() { return g_printers_manager.Pointer(); } -content::BrowserContext* PrintersManagerFactory::GetBrowserContextToUse( +content::BrowserContext* SyncedPrintersManagerFactory::GetBrowserContextToUse( content::BrowserContext* context) const { return chrome::GetBrowserContextRedirectedInIncognito(context); } -PrintersManagerFactory::PrintersManagerFactory() +SyncedPrintersManagerFactory::SyncedPrintersManagerFactory() : BrowserContextKeyedServiceFactory( - "PrintersManager", + "SyncedPrintersManager", BrowserContextDependencyManager::GetInstance()) {} -PrintersManagerFactory::~PrintersManagerFactory() {} +SyncedPrintersManagerFactory::~SyncedPrintersManagerFactory() {} -PrintersManager* PrintersManagerFactory::BuildServiceInstanceFor( +SyncedPrintersManager* SyncedPrintersManagerFactory::BuildServiceInstanceFor( content::BrowserContext* browser_context) const { Profile* profile = Profile::FromBrowserContext(browser_context); @@ -61,11 +61,10 @@ std::unique_ptr<PrintersSyncBridge> sync_bridge = base::MakeUnique<PrintersSyncBridge>( - store_factory, - base::BindRepeating( - base::IgnoreResult(&base::debug::DumpWithoutCrashing))); + store_factory, base::BindRepeating(base::IgnoreResult( + &base::debug::DumpWithoutCrashing))); - return new PrintersManager(profile, std::move(sync_bridge)); + return new SyncedPrintersManager(profile, std::move(sync_bridge)); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/synced_printers_manager_factory.h b/chrome/browser/chromeos/printing/synced_printers_manager_factory.h new file mode 100644 index 0000000..c9bd895 --- /dev/null +++ b/chrome/browser/chromeos/printing/synced_printers_manager_factory.h
@@ -0,0 +1,45 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_SYNCED_PRINTERS_MANAGER_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_PRINTING_SYNCED_PRINTERS_MANAGER_FACTORY_H_ + +#include "base/lazy_instance.h" +#include "base/macros.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace content { +class BrowserContext; +} + +namespace chromeos { + +class SyncedPrintersManagerFactory : public BrowserContextKeyedServiceFactory { + public: + static SyncedPrintersManager* GetForBrowserContext( + content::BrowserContext* context); + + static SyncedPrintersManagerFactory* GetInstance(); + + protected: + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + + private: + friend struct base::LazyInstanceTraitsBase<SyncedPrintersManagerFactory>; + + SyncedPrintersManagerFactory(); + ~SyncedPrintersManagerFactory() override; + + // BrowserContextKeyedServiceFactory implementation: + SyncedPrintersManager* BuildServiceInstanceFor( + content::BrowserContext* browser_context) const override; + + DISALLOW_COPY_AND_ASSIGN(SyncedPrintersManagerFactory); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_PRINTING_SYNCED_PRINTERS_MANAGER_FACTORY_H_
diff --git a/chrome/browser/chromeos/printing/printers_manager_unittest.cc b/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc similarity index 89% rename from chrome/browser/chromeos/printing/printers_manager_unittest.cc rename to chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc index d73860c..39e7c880 100644 --- a/chrome/browser/chromeos/printing/printers_manager_unittest.cc +++ b/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/printing/printers_manager.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" #include <memory> #include <utility> @@ -13,8 +13,8 @@ #include "base/optional.h" #include "base/run_loop.h" #include "base/time/time.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" #include "chrome/browser/chromeos/printing/printers_sync_bridge.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "components/sync/model/fake_model_type_change_processor.h" @@ -43,7 +43,7 @@ } )json"; // Helper class to record observed events. -class LoggingObserver : public PrintersManager::Observer { +class LoggingObserver : public SyncedPrintersManager::Observer { public: void OnPrinterAdded(const Printer& printer) override { last_added_ = printer; @@ -84,9 +84,9 @@ } // namespace -class PrintersManagerTest : public testing::Test { +class SyncedPrintersManagerTest : public testing::Test { protected: - PrintersManagerTest() + SyncedPrintersManagerTest() : manager_( &profile_, base::MakeUnique<PrintersSyncBridge>( @@ -103,10 +103,10 @@ // Must outlive |manager_|. TestingProfile profile_; - PrintersManager manager_; + SyncedPrintersManager manager_; }; -TEST_F(PrintersManagerTest, AddPrinter) { +TEST_F(SyncedPrintersManagerTest, AddPrinter) { LoggingObserver observer; manager_.AddObserver(&observer); manager_.RegisterPrinter(base::MakeUnique<Printer>(kPrinterId)); @@ -120,7 +120,7 @@ EXPECT_FALSE(observer.UpdateCalled()); } -TEST_F(PrintersManagerTest, UpdatePrinterAssignsId) { +TEST_F(SyncedPrintersManagerTest, UpdatePrinterAssignsId) { manager_.RegisterPrinter(base::MakeUnique<Printer>()); auto printers = manager_.GetPrinters(); @@ -128,7 +128,7 @@ EXPECT_FALSE(printers[0]->id().empty()); } -TEST_F(PrintersManagerTest, UpdatePrinter) { +TEST_F(SyncedPrintersManagerTest, UpdatePrinter) { manager_.RegisterPrinter(base::MakeUnique<Printer>(kPrinterId)); auto updated_printer = base::MakeUnique<Printer>(kPrinterId); updated_printer->set_uri(kUri); @@ -147,7 +147,7 @@ EXPECT_FALSE(observer.AddCalled()); } -TEST_F(PrintersManagerTest, RemovePrinter) { +TEST_F(SyncedPrintersManagerTest, RemovePrinter) { manager_.RegisterPrinter(base::MakeUnique<Printer>("OtherUUID")); manager_.RegisterPrinter(base::MakeUnique<Printer>(kPrinterId)); manager_.RegisterPrinter(base::MakeUnique<Printer>()); @@ -162,7 +162,7 @@ // Tests for policy printers -TEST_F(PrintersManagerTest, RecommendedPrinters) { +TEST_F(SyncedPrintersManagerTest, RecommendedPrinters) { std::string first_printer = R"json({ "display_name": "Color Laser", @@ -195,7 +195,7 @@ EXPECT_EQ(Printer::Source::SRC_POLICY, printers[1]->source()); } -TEST_F(PrintersManagerTest, GetRecommendedPrinter) { +TEST_F(SyncedPrintersManagerTest, GetRecommendedPrinter) { std::string printer = kLexJson; auto value = base::MakeUnique<base::ListValue>(); value->AppendString(printer); @@ -215,18 +215,18 @@ EXPECT_EQ(Printer::Source::SRC_POLICY, from_list.source()); } -TEST_F(PrintersManagerTest, PrinterNotInstalled) { +TEST_F(SyncedPrintersManagerTest, PrinterNotInstalled) { Printer printer(kPrinterId, base::Time::FromInternalValue(1000)); EXPECT_FALSE(manager_.IsConfigurationCurrent(printer)); } -TEST_F(PrintersManagerTest, PrinterIsInstalled) { +TEST_F(SyncedPrintersManagerTest, PrinterIsInstalled) { Printer printer(kPrinterId, base::Time::FromInternalValue(1000)); manager_.PrinterInstalled(printer); EXPECT_TRUE(manager_.IsConfigurationCurrent(printer)); } -TEST_F(PrintersManagerTest, UpdatedPrinterConfiguration) { +TEST_F(SyncedPrintersManagerTest, UpdatedPrinterConfiguration) { Printer printer(kPrinterId, base::Time::FromInternalValue(1000)); manager_.PrinterInstalled(printer);
diff --git a/chrome/browser/chromeos/printing/usb_printer_detector.cc b/chrome/browser/chromeos/printing/usb_printer_detector.cc index 3be8d30..60723d7 100644 --- a/chrome/browser/chromeos/printing/usb_printer_detector.cc +++ b/chrome/browser/chromeos/printing/usb_printer_detector.cc
@@ -22,7 +22,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" #include "chrome/browser/chromeos/printing/printer_configurer.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/chromeos/printing/usb_printer_detector.h" #include "chrome/browser/chromeos/printing/usb_printer_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -195,8 +195,8 @@ // one for the one we generated automatically and skip the parts where we // try to automagically figure out the driver. std::unique_ptr<Printer> existing_printer_configuration = - PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinter( - data->printer->id()); + SyncedPrintersManagerFactory::GetForBrowserContext(profile_) + ->GetPrinter(data->printer->id()); if (existing_printer_configuration != nullptr) { data->is_new = false; data->printer = std::move(existing_printer_configuration); @@ -267,8 +267,8 @@ // We aren't done with data->printer yet, so we have to copy it instead // of moving it. auto printer_copy = base::MakeUnique<Printer>(*data->printer); - PrintersManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter( - std::move(printer_copy)); + SyncedPrintersManagerFactory::GetForBrowserContext(profile_) + ->RegisterPrinter(std::move(printer_copy)); } // TODO(justincarlson): If the device was hotplugged, pop a timed // notification that says the printer is now available for printing.
diff --git a/chrome/browser/chromeos/printing/usb_printer_detector_factory.cc b/chrome/browser/chromeos/printing/usb_printer_detector_factory.cc index c8dbd12a..fc9b6647 100644 --- a/chrome/browser/chromeos/printing/usb_printer_detector_factory.cc +++ b/chrome/browser/chromeos/printing/usb_printer_detector_factory.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/chromeos/printing/usb_printer_detector_factory.h" #include "base/command_line.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/chromeos/printing/usb_printer_detector.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" @@ -39,7 +39,7 @@ BrowserContextDependencyManager::GetInstance()) { DependsOn( extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); - DependsOn(PrintersManagerFactory::GetInstance()); + DependsOn(SyncedPrintersManagerFactory::GetInstance()); } UsbPrinterDetectorFactory::~UsbPrinterDetectorFactory() {}
diff --git a/chrome/browser/chromeos/system_logs/command_line_log_source.h b/chrome/browser/chromeos/system_logs/command_line_log_source.h index 16745ded..374ac69 100644 --- a/chrome/browser/chromeos/system_logs/command_line_log_source.h +++ b/chrome/browser/chromeos/system_logs/command_line_log_source.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_SYSTEM_LOGS_COMMAND_LINE_LOG_SOURCE_H_ #include "base/macros.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/chromeos/system_logs/dbus_log_source.h b/chrome/browser/chromeos/system_logs/dbus_log_source.h index 2ffb2e2..a80140e 100644 --- a/chrome/browser/chromeos/system_logs/dbus_log_source.h +++ b/chrome/browser/chromeos/system_logs/dbus_log_source.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_SYSTEM_LOGS_DBUS_LOG_SOURCE_H_ #include "base/macros.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/chromeos/system_logs/debug_daemon_log_source.h b/chrome/browser/chromeos/system_logs/debug_daemon_log_source.h index fa09b05..3b537ef 100644 --- a/chrome/browser/chromeos/system_logs/debug_daemon_log_source.h +++ b/chrome/browser/chromeos/system_logs/debug_daemon_log_source.h
@@ -12,7 +12,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/chromeos/system_logs/device_event_log_source.h b/chrome/browser/chromeos/system_logs/device_event_log_source.h index 6337369..a3d8eb6 100644 --- a/chrome/browser/chromeos/system_logs/device_event_log_source.h +++ b/chrome/browser/chromeos/system_logs/device_event_log_source.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_SYSTEM_LOGS_DEVICE_EVENT_LOG_SOURCE_H_ #include "base/macros.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/chromeos/system_logs/lsb_release_log_source.h b/chrome/browser/chromeos/system_logs/lsb_release_log_source.h index 4ec9e81..bfd39b4b 100644 --- a/chrome/browser/chromeos/system_logs/lsb_release_log_source.h +++ b/chrome/browser/chromeos/system_logs/lsb_release_log_source.h
@@ -5,7 +5,7 @@ #define CHROME_BROWSER_CHROMEOS_SYSTEM_LOGS_LSB_RELEASE_LOG_SOURCE_H_ #include "base/macros.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/chromeos/system_logs/single_debug_daemon_log_source.h b/chrome/browser/chromeos/system_logs/single_debug_daemon_log_source.h index 97c4a480..b7d63111 100644 --- a/chrome/browser/chromeos/system_logs/single_debug_daemon_log_source.h +++ b/chrome/browser/chromeos/system_logs/single_debug_daemon_log_source.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/chromeos/system_logs/single_log_file_log_source.h b/chrome/browser/chromeos/system_logs/single_log_file_log_source.h index 861c1ed..e3ee9e3 100644 --- a/chrome/browser/chromeos/system_logs/single_log_file_log_source.h +++ b/chrome/browser/chromeos/system_logs/single_log_file_log_source.h
@@ -11,8 +11,8 @@ #include "base/files/file.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" #include "components/feedback/anonymizer_tool.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace base { class Time;
diff --git a/chrome/browser/chromeos/system_logs/touch_log_source.h b/chrome/browser/chromeos/system_logs/touch_log_source.h index 08e4b6c..e2efaeee 100644 --- a/chrome/browser/chromeos/system_logs/touch_log_source.h +++ b/chrome/browser/chromeos/system_logs/touch_log_source.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_SYSTEM_LOGS_TOUCH_LOG_SOURCE_H_ #include "base/macros.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api.h b/chrome/browser/extensions/api/feedback_private/feedback_private_api.h index 2a814c5..ef781bd 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_private_api.h +++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api.h
@@ -8,8 +8,8 @@ #include <memory> #include "chrome/browser/extensions/chrome_extension_function.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" #include "chrome/common/extensions/api/feedback_private.h" +#include "components/feedback/system_logs/system_logs_source.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/extension_function.h" #include "ui/gfx/geometry/rect.h"
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_service.h b/chrome/browser/extensions/api/feedback_private/feedback_service.h index dc706ac..9e6dfa8 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_service.h +++ b/chrome/browser/extensions/api/feedback_private/feedback_service.h
@@ -12,8 +12,8 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/feedback/system_logs/system_logs_fetcher.h" #include "components/feedback/feedback_data.h" +#include "components/feedback/system_logs/system_logs_fetcher.h" class Profile;
diff --git a/chrome/browser/extensions/api/feedback_private/log_source_access_manager.h b/chrome/browser/extensions/api/feedback_private/log_source_access_manager.h index 95b0a2b..9d44b01 100644 --- a/chrome/browser/extensions/api/feedback_private/log_source_access_manager.h +++ b/chrome/browser/extensions/api/feedback_private/log_source_access_manager.h
@@ -15,8 +15,8 @@ #include "base/memory/weak_ptr.h" #include "base/time/tick_clock.h" #include "base/time/time.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" #include "chrome/common/extensions/api/feedback_private.h" +#include "components/feedback/system_logs/system_logs_source.h" #include "content/public/browser/browser_context.h" namespace extensions {
diff --git a/chrome/browser/extensions/api/feedback_private/log_source_resource.h b/chrome/browser/extensions/api/feedback_private/log_source_resource.h index 02c1a4e..e510360 100644 --- a/chrome/browser/extensions/api/feedback_private/log_source_resource.h +++ b/chrome/browser/extensions/api/feedback_private/log_source_resource.h
@@ -10,7 +10,7 @@ #include "base/callback_helpers.h" #include "base/macros.h" #include "chrome/browser/extensions/api/feedback_private/log_source_access_manager.h" -#include "chrome/browser/feedback/system_logs/system_logs_fetcher.h" +#include "components/feedback/system_logs/system_logs_fetcher.h" #include "extensions/browser/api/api_resource.h" #include "extensions/browser/api/api_resource_manager.h"
diff --git a/chrome/browser/extensions/api/feedback_private/single_log_source_factory.h b/chrome/browser/extensions/api/feedback_private/single_log_source_factory.h index feb2943..5743d1a 100644 --- a/chrome/browser/extensions/api/feedback_private/single_log_source_factory.h +++ b/chrome/browser/extensions/api/feedback_private/single_log_source_factory.h
@@ -8,8 +8,8 @@ #include <memory> #include "base/callback.h" -#include "chrome/browser/feedback/system_logs/system_logs_fetcher.h" #include "chrome/common/extensions/api/feedback_private.h" +#include "components/feedback/system_logs/system_logs_fetcher.h" namespace extensions {
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 12b0727..e154c55 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -6354,6 +6354,35 @@ EXPECT_FALSE(HasExternalInstallErrors(service_)); } +// Regression test for crbug.com/739142. Verifies that no UAF occurs when +// ExternalInstallError needs to be deleted asynchronously. +TEST_F(ExtensionServiceTest, InstallPromptAborted) { + FeatureSwitch::ScopedOverride prompt( + FeatureSwitch::prompt_for_external_extensions(), true); + InitializeEmptyExtensionService(); + + MockExternalProvider* reg_provider = + AddMockExternalProvider(Manifest::EXTERNAL_REGISTRY); + + reg_provider->UpdateOrAddExtension(good_crx, "1.0.0.0", + data_dir().AppendASCII("good.crx")); + WaitForExternalExtensionInstalled(); + EXPECT_EQ( + 1u, service()->external_install_manager()->GetErrorsForTesting().size()); + EXPECT_FALSE(service()->IsExtensionEnabled(good_crx)); + EXPECT_TRUE(GetError(good_crx)); + + // Abort the extension install prompt. This should cause the + // ExternalInstallError to be deleted asynchronously. + GetError(good_crx)->OnInstallPromptDone( + ExtensionInstallPrompt::Result::ABORTED); + EXPECT_TRUE(GetError(good_crx)); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(GetError(good_crx)); + + EXPECT_FALSE(HasExternalInstallErrors(service_)); +} + TEST_F(ExtensionServiceTest, MultipleExternalInstallBubbleErrors) { FeatureSwitch::ScopedOverride prompt( FeatureSwitch::prompt_for_external_extensions(), true);
diff --git a/chrome/browser/extensions/external_install_manager.cc b/chrome/browser/extensions/external_install_manager.cc index d1419d0..8eb7020f 100644 --- a/chrome/browser/extensions/external_install_manager.cc +++ b/chrome/browser/extensions/external_install_manager.cc
@@ -114,10 +114,15 @@ const std::string& extension_id) { auto iter = errors_.find(extension_id); if (iter != errors_.end()) { + // The |extension_id| may be owned by the ExternalInstallError, which is + // deleted subsequently. To avoid any UAFs, make a safe copy of + // |extension_id| now. + std::string extension_id_copy = extension_id; + if (iter->second.get() == currently_visible_install_alert_) currently_visible_install_alert_ = nullptr; errors_.erase(iter); - unacknowledged_ids_.erase(extension_id); + unacknowledged_ids_.erase(extension_id_copy); UpdateExternalExtensionAlert(); } }
diff --git a/chrome/browser/feedback/system_logs/about_system_logs_fetcher.cc b/chrome/browser/feedback/system_logs/about_system_logs_fetcher.cc index 1149cf4..3bb9374 100644 --- a/chrome/browser/feedback/system_logs/about_system_logs_fetcher.cc +++ b/chrome/browser/feedback/system_logs/about_system_logs_fetcher.cc
@@ -8,7 +8,7 @@ #include "build/build_config.h" #include "chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h" #include "chrome/browser/feedback/system_logs/log_sources/memory_details_log_source.h" -#include "chrome/browser/feedback/system_logs/system_logs_fetcher.h" +#include "components/feedback/system_logs/system_logs_fetcher.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/system_logs/command_line_log_source.h"
diff --git a/chrome/browser/feedback/system_logs/chrome_system_logs_fetcher.cc b/chrome/browser/feedback/system_logs/chrome_system_logs_fetcher.cc index 31df6ba1..30d49ef 100644 --- a/chrome/browser/feedback/system_logs/chrome_system_logs_fetcher.cc +++ b/chrome/browser/feedback/system_logs/chrome_system_logs_fetcher.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h" #include "chrome/browser/feedback/system_logs/log_sources/crash_ids_source.h" #include "chrome/browser/feedback/system_logs/log_sources/memory_details_log_source.h" -#include "chrome/browser/feedback/system_logs/system_logs_fetcher.h" +#include "components/feedback/system_logs/system_logs_fetcher.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/system_logs/command_line_log_source.h"
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h index d947b407..5d33b844 100644 --- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h +++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "build/build_config.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/feedback/system_logs/log_sources/crash_ids_source.h b/chrome/browser/feedback/system_logs/log_sources/crash_ids_source.h index 6339c5fb..5193bf5 100644 --- a/chrome/browser/feedback/system_logs/log_sources/crash_ids_source.h +++ b/chrome/browser/feedback/system_logs/log_sources/crash_ids_source.h
@@ -8,7 +8,7 @@ #include <vector> #include "base/callback_forward.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" #include "components/upload_list/upload_list.h" namespace system_logs {
diff --git a/chrome/browser/feedback/system_logs/log_sources/memory_details_log_source.h b/chrome/browser/feedback/system_logs/log_sources/memory_details_log_source.h index fc438b4..7edd90f 100644 --- a/chrome/browser/feedback/system_logs/log_sources/memory_details_log_source.h +++ b/chrome/browser/feedback/system_logs/log_sources/memory_details_log_source.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_FEEDBACK_SYSTEM_LOGS_LOG_SOURCES_MEMORY_DETAILS_LOG_SOURCE_H_ #include "base/macros.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 684d2fb..1379b7be 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1180,6 +1180,8 @@ const char kTLS13VariantDisabled[] = "Disabled"; const char kTLS13VariantDraft[] = "Enabled (Draft)"; const char kTLS13VariantExperiment[] = "Enabled (Experiment)"; +const char kTLS13VariantRecordTypeExperiment[] = + "Enabled (Record Type Experiment)"; const char kTopDocumentIsolationName[] = "Top document isolation"; const char kTopDocumentIsolationDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 0024836..a0ec35a 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -707,6 +707,7 @@ extern const char kTLS13VariantDisabled[]; extern const char kTLS13VariantDraft[]; extern const char kTLS13VariantExperiment[]; +extern const char kTLS13VariantRecordTypeExperiment[]; extern const char kSuggestionsWithSubStringMatchName[]; extern const char kSuggestionsWithSubStringMatchDescription[];
diff --git a/chrome/browser/media/router/media_router_metrics.cc b/chrome/browser/media/router/media_router_metrics.cc index 491da23..7da3ae6 100644 --- a/chrome/browser/media/router/media_router_metrics.cc +++ b/chrome/browser/media/router/media_router_metrics.cc
@@ -28,7 +28,9 @@ const char MediaRouterMetrics::kHistogramMediaRouterCastingSource[] = "MediaRouter.Source.CastingSource"; const char MediaRouterMetrics::kHistogramMediaRouterFileFormat[] = - "MediaRouter.Source.FileFormat"; + "MediaRouter.Source.LocalFileFormat"; +const char MediaRouterMetrics::kHistogramMediaRouterFileSize[] = + "MediaRouter.Source.LocalFileSize"; const char MediaRouterMetrics::kHistogramRouteCreationOutcome[] = "MediaRouter.Route.CreationOutcome"; const char MediaRouterMetrics::kHistogramUiDialogPaint[] = @@ -91,6 +93,10 @@ media::container_names::CONTAINER_MAX); } +void MediaRouterMetrics::RecordMediaRouterFileSize(int64_t size) { + UMA_HISTOGRAM_MEMORY_LARGE_MB(kHistogramMediaRouterFileSize, size); +} + void MediaRouterMetrics::RecordDialDeviceCounts(size_t available_device_count, size_t known_device_count) { if (clock_->Now() - device_count_metrics_record_time_ <
diff --git a/chrome/browser/media/router/media_router_metrics.h b/chrome/browser/media/router/media_router_metrics.h index dd8dc022..f94ff203 100644 --- a/chrome/browser/media/router/media_router_metrics.h +++ b/chrome/browser/media/router/media_router_metrics.h
@@ -68,6 +68,7 @@ static const char kHistogramIconClickLocation[]; static const char kHistogramMediaRouterCastingSource[]; static const char kHistogramMediaRouterFileFormat[]; + static const char kHistogramMediaRouterFileSize[]; static const char kHistogramRouteCreationOutcome[]; static const char kHistogramUiDialogPaint[]; static const char kHistogramUiDialogLoadedWithData[]; @@ -103,6 +104,9 @@ static void RecordMediaRouterFileFormat( media::container_names::MediaContainerName format); + // Records the size of a cast file. + static void RecordMediaRouterFileSize(int64_t size); + // Records device counts. // TODO(zhaobin): Move device count specific metrics and state into its own // class eventually.
diff --git a/chrome/browser/media/webrtc/media_stream_device_permission_context_unittest.cc b/chrome/browser/media/webrtc/media_stream_device_permission_context_unittest.cc index 6a22aa6..5c8682c 100644 --- a/chrome/browser/media/webrtc/media_stream_device_permission_context_unittest.cc +++ b/chrome/browser/media/webrtc/media_stream_device_permission_context_unittest.cc
@@ -164,17 +164,3 @@ TEST_F(MediaStreamDevicePermissionContextTests, TestCameraSecureQueryingUrl) { TestSecureQueryingUrl(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); } - -// An embedding origin of about:blank should not be blocked. crbug.com/740540. -TEST_F(MediaStreamDevicePermissionContextTests, TestAboutBlankNotBlocked) { - TestPermissionContext permission_context( - profile(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); - GURL secure_url("https://www.example.com"); - - EXPECT_EQ( - CONTENT_SETTING_ASK, - permission_context - .GetPermissionStatus(nullptr /* render_frame_host */, secure_url, - GURL("about:blank").GetOrigin()) - .content_setting); -}
diff --git a/chrome/browser/permissions/permission_context_base.cc b/chrome/browser/permissions/permission_context_base.cc index d4dfb8c..8210831 100644 --- a/chrome/browser/permissions/permission_context_base.cc +++ b/chrome/browser/permissions/permission_context_base.cc
@@ -230,20 +230,21 @@ } if (IsRestrictedToSecureOrigins()) { - // TODO(raymes): The secure origin check here in the browser should match - // what we do in blink (i.e. what is described in the secure context spec). - // Right now, we can't even check IsOriginSecure(embedding_origin) because - // the |embedding_origin| is obtained from the WebContents which does match - // the origin of the document in blink in all cases. For example, an - // about:blank URL may be a secure context in blink, but it is not treated - // as such in the browser at present. The |requesting_origin| is passed from - // blink and so is accurate under normal circumstances but may be forged by - // a compromised renderer so even this check below is not particularly - // secure... if (!content::IsOriginSecure(requesting_origin)) { return PermissionResult(CONTENT_SETTING_BLOCK, PermissionStatusSource::UNSPECIFIED); } + + // TODO(raymes): We should check the entire chain of embedders here whenever + // possible as this corresponds to the requirements of the secure contexts + // spec and matches what is implemented in blink. Right now we just check + // the top level and requesting origins. Note: chrome-extension:// origins + // are currently exempt from checking the embedder chain. crbug.com/530507. + if (!requesting_origin.SchemeIs(extensions::kExtensionScheme) && + !content::IsOriginSecure(embedding_origin)) { + return PermissionResult(CONTENT_SETTING_BLOCK, + PermissionStatusSource::UNSPECIFIED); + } } // Check whether the feature is enabled for the frame by feature policy. We
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 01c8299a..222a42a 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -195,6 +195,7 @@ #include "chrome/browser/chromeos/extensions/echo_private_api.h" #include "chrome/browser/chromeos/file_system_provider/registry.h" #include "chrome/browser/chromeos/first_run/first_run.h" +#include "chrome/browser/chromeos/lock_screen_apps/state_controller.h" #include "chrome/browser/chromeos/login/demo_mode/demo_mode_detector.h" #include "chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.h" #include "chrome/browser/chromeos/login/quick_unlock/pin_storage.h" @@ -217,7 +218,7 @@ #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" #include "chrome/browser/chromeos/power/power_prefs.h" #include "chrome/browser/chromeos/preferences.h" -#include "chrome/browser/chromeos/printing/printers_manager.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" #include "chrome/browser/chromeos/resource_reporter/resource_reporter.h" #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" #include "chrome/browser/chromeos/settings/device_settings_cache.h" @@ -591,7 +592,7 @@ chromeos::quick_unlock::FingerprintStorage::RegisterProfilePrefs(registry); chromeos::quick_unlock::PinStorage::RegisterProfilePrefs(registry); chromeos::Preferences::RegisterProfilePrefs(registry); - chromeos::PrintersManager::RegisterProfilePrefs(registry); + chromeos::SyncedPrintersManager::RegisterProfilePrefs(registry); chromeos::quick_unlock::RegisterProfilePrefs(registry); chromeos::SAMLOfflineSigninLimiter::RegisterProfilePrefs(registry); chromeos::ServicesCustomizationDocument::RegisterProfilePrefs(registry); @@ -599,6 +600,7 @@ chromeos::UserImageSyncObserver::RegisterProfilePrefs(registry); extensions::EPKPChallengeUserKey::RegisterProfilePrefs(registry); flags_ui::PrefServiceFlagsStorage::RegisterProfilePrefs(registry); + lock_screen_apps::StateController::RegisterProfilePrefs(registry); policy::DeviceStatusCollector::RegisterProfilePrefs(registry); ::onc::RegisterProfilePrefs(registry); #endif
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 1c940336..4288055 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -120,7 +120,7 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/printing/cups_print_job_manager_factory.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/chromeos/printing/usb_printer_detector_factory.h" #include "chrome/browser/chromeos/tether/tether_service_factory.h" #include "chrome/browser/extensions/api/platform_keys/verify_trust_api.h" @@ -233,7 +233,7 @@ #if defined(OS_CHROMEOS) chromeos::UsbPrinterDetectorFactory::GetInstance(); chromeos::CupsPrintJobManagerFactory::GetInstance(); - chromeos::PrintersManagerFactory::GetInstance(); + chromeos::SyncedPrintersManagerFactory::GetInstance(); TetherServiceFactory::GetInstance(); extensions::VerifyTrustAPI::GetFactoryInstance(); #endif
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc index 1b84c5f..e600164 100644 --- a/chrome/browser/resource_coordinator/tab_manager.cc +++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/resource_coordinator/resource_coordinator_web_contents_observer.h" #include "chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.h" #include "chrome/browser/resource_coordinator/tab_manager_observer.h" +#include "chrome/browser/resource_coordinator/tab_manager_stats_collector.h" #include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h" #include "chrome/browser/sessions/session_restore.h" #include "chrome/browser/ui/browser.h" @@ -155,6 +156,7 @@ if (resource_coordinator::IsResourceCoordinatorEnabled()) { grc_tab_signal_observer_.reset(new GRCTabSignalObserver()); } + tab_manager_stats_collector_.reset(new TabManagerStatsCollector(this)); } TabManager::~TabManager() { @@ -825,6 +827,11 @@ content::WebContents* new_contents, int index, int reason) { + // An active tab is not purged. + // Calling GetWebContentsData() early ensures that the WebContentsData is + // created for |new_contents|, which |tab_manager_stats_collector_| expects. + GetWebContentsData(new_contents)->set_is_purged(false); + // If |old_contents| is set, that tab has switched from being active to // inactive, so record the time of that transition. if (old_contents) { @@ -835,12 +842,9 @@ GetTimeToPurge(min_time_to_purge_, max_time_to_purge_)); // Only record switch-to-tab metrics when a switch happens, i.e. // |old_contents| is set. - RecordSwitchToTab(new_contents); + tab_manager_stats_collector_->RecordSwitchToTab(new_contents); } - // An active tab is not purged. - GetWebContentsData(new_contents)->set_is_purged(false); - // Reload |web_contents| if it is in an active browser and discarded. if (IsActiveWebContentsInActiveBrowser(new_contents)) { ReloadWebContentsIfDiscarded(new_contents, @@ -999,14 +1003,6 @@ return browser_info_list; } -void TabManager::RecordSwitchToTab(content::WebContents* contents) const { - if (is_session_restore_loading_tabs_) { - UMA_HISTOGRAM_ENUMERATION("TabManager.SessionRestore.SwitchToTab", - GetWebContentsData(contents)->tab_loading_state(), - TAB_LOADING_STATE_MAX); - } -} - content::NavigationThrottle::ThrottleCheckResult TabManager::MaybeThrottleNavigation( content::NavigationHandle* navigation_handle) {
diff --git a/chrome/browser/resource_coordinator/tab_manager.h b/chrome/browser/resource_coordinator/tab_manager.h index aa5deb5f..83dcd12 100644 --- a/chrome/browser/resource_coordinator/tab_manager.h +++ b/chrome/browser/resource_coordinator/tab_manager.h
@@ -47,6 +47,7 @@ #if defined(OS_CHROMEOS) class TabManagerDelegate; #endif +class TabManagerStatsCollector; // The TabManager periodically updates (see // |kAdjustmentIntervalSeconds| in the source) the status of renderers @@ -209,13 +210,14 @@ FRIEND_TEST_ALL_PREFIXES(TabManagerTest, FastShutdownSingleTabProcess); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, GetUnsortedTabStatsIsInVisibleWindow); - FRIEND_TEST_ALL_PREFIXES(TabManagerTest, HistogramsSessionRestoreSwitchToTab); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardTabWithNonVisibleTabs); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, MaybeThrottleNavigation); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OnDidFinishNavigation); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OnDidStopLoading); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OnWebContentsDestroyed); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OnDelayedTabSelected); + FRIEND_TEST_ALL_PREFIXES(TabManagerStatsCollectorTest, + HistogramsSessionRestoreSwitchToTab); // Information about a Browser. struct BrowserInfo { @@ -367,10 +369,6 @@ void OnSessionRestoreStartedLoadingTabs(); void OnSessionRestoreFinishedLoadingTabs(); - // Records UMA histograms for the tab state when switching to a different tab - // during session restore. - void RecordSwitchToTab(content::WebContents* contents) const; - // Returns true if the navigation should be delayed. bool ShouldDelayNavigation( content::NavigationHandle* navigation_handle) const; @@ -476,6 +474,10 @@ // GRC tab signal observer, receives tab scoped signal from GRC. std::unique_ptr<GRCTabSignalObserver> grc_tab_signal_observer_; + // Records UMAs for tab and system-related events and properties during + // session restore. + std::unique_ptr<TabManagerStatsCollector> tab_manager_stats_collector_; + // Weak pointer factory used for posting delayed tasks. base::WeakPtrFactory<TabManager> weak_ptr_factory_;
diff --git a/chrome/browser/resource_coordinator/tab_manager_stats_collector.cc b/chrome/browser/resource_coordinator/tab_manager_stats_collector.cc new file mode 100644 index 0000000..88e9953 --- /dev/null +++ b/chrome/browser/resource_coordinator/tab_manager_stats_collector.cc
@@ -0,0 +1,28 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/tab_manager_stats_collector.h" + +#include "base/metrics/histogram_macros.h" +#include "chrome/browser/resource_coordinator/tab_manager.h" +#include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h" + +namespace resource_coordinator { + +TabManagerStatsCollector::TabManagerStatsCollector(TabManager* tab_manager) + : tab_manager_(tab_manager) {} + +TabManagerStatsCollector::~TabManagerStatsCollector() = default; + +void TabManagerStatsCollector::RecordSwitchToTab( + content::WebContents* contents) const { + if (tab_manager_->IsSessionRestoreLoadingTabs()) { + auto* data = TabManager::WebContentsData::FromWebContents(contents); + DCHECK(data); + UMA_HISTOGRAM_ENUMERATION("TabManager.SessionRestore.SwitchToTab", + data->tab_loading_state(), TAB_LOADING_STATE_MAX); + } +} + +} // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_manager_stats_collector.h b/chrome/browser/resource_coordinator/tab_manager_stats_collector.h new file mode 100644 index 0000000..b619571e --- /dev/null +++ b/chrome/browser/resource_coordinator/tab_manager_stats_collector.h
@@ -0,0 +1,33 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_STATS_COLLECTOR_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_STATS_COLLECTOR_H_ + +namespace content { +class WebContents; +} // namespace content + +namespace resource_coordinator { + +class TabManager; + +// TabManagerStatsCollector records UMAs on behalf of TabManager for tab and +// system-related events and properties during session restore. +class TabManagerStatsCollector { + public: + explicit TabManagerStatsCollector(TabManager* tab_manager); + ~TabManagerStatsCollector(); + + // Records UMA histograms for the tab state when switching to a different tab + // during session restore. + void RecordSwitchToTab(content::WebContents* contents) const; + + private: + TabManager* tab_manager_; +}; + +} // namespace resource_coordinator + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_STATS_COLLECTOR_H_
diff --git a/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc new file mode 100644 index 0000000..87ebfae --- /dev/null +++ b/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc
@@ -0,0 +1,78 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/tab_manager_stats_collector.h" + +#include <memory> + +#include "base/logging.h" +#include "base/macros.h" +#include "base/test/histogram_tester.h" +#include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/browser/web_contents.h" +#include "content/test/test_web_contents.h" +#include "testing/gtest/include/gtest/gtest.h" + +using content::WebContents; + +namespace resource_coordinator { + +class TabManagerStatsCollectorTest : public ChromeRenderViewHostTestHarness { + public: + WebContents* CreateWebContents() { + return content::TestWebContents::Create(profile(), nullptr); + } +}; + +TEST_F(TabManagerStatsCollectorTest, HistogramsSessionRestoreSwitchToTab) { + const char kHistogramName[] = "TabManager.SessionRestore.SwitchToTab"; + + TabManager tab_manager; + std::unique_ptr<WebContents> tab(CreateWebContents()); + + auto* data = tab_manager.GetWebContentsData(tab.get()); + auto* stats_collector = tab_manager.tab_manager_stats_collector_.get(); + + base::HistogramTester histograms; + histograms.ExpectTotalCount(kHistogramName, 0); + + data->SetTabLoadingState(TAB_IS_LOADING); + stats_collector->RecordSwitchToTab(tab.get()); + stats_collector->RecordSwitchToTab(tab.get()); + + // Nothing should happen until we're in a session restore. + histograms.ExpectTotalCount(kHistogramName, 0); + + tab_manager.OnSessionRestoreStartedLoadingTabs(); + + data->SetTabLoadingState(TAB_IS_NOT_LOADING); + stats_collector->RecordSwitchToTab(tab.get()); + stats_collector->RecordSwitchToTab(tab.get()); + histograms.ExpectTotalCount(kHistogramName, 2); + histograms.ExpectBucketCount(kHistogramName, TAB_IS_NOT_LOADING, 2); + + data->SetTabLoadingState(TAB_IS_LOADING); + stats_collector->RecordSwitchToTab(tab.get()); + stats_collector->RecordSwitchToTab(tab.get()); + stats_collector->RecordSwitchToTab(tab.get()); + + histograms.ExpectTotalCount(kHistogramName, 5); + histograms.ExpectBucketCount(kHistogramName, TAB_IS_NOT_LOADING, 2); + histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADING, 3); + + data->SetTabLoadingState(TAB_IS_LOADED); + stats_collector->RecordSwitchToTab(tab.get()); + stats_collector->RecordSwitchToTab(tab.get()); + stats_collector->RecordSwitchToTab(tab.get()); + stats_collector->RecordSwitchToTab(tab.get()); + + histograms.ExpectTotalCount(kHistogramName, 9); + histograms.ExpectBucketCount(kHistogramName, TAB_IS_NOT_LOADING, 2); + histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADING, 3); + histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADED, 4); +} + +} // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_manager_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_unittest.cc index 49537e1..2c94819 100644 --- a/chrome/browser/resource_coordinator/tab_manager_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
@@ -14,7 +14,6 @@ #include "base/memory/ptr_util.h" #include "base/metrics/field_trial.h" #include "base/strings/string16.h" -#include "base/test/histogram_tester.h" #include "base/test/mock_entropy_provider.h" #include "base/test/simple_test_tick_clock.h" #include "base/time/time.h" @@ -682,59 +681,6 @@ EXPECT_FALSE(tab_manager->IsSessionRestoreLoadingTabs()); } -TEST_F(TabManagerTest, HistogramsSessionRestoreSwitchToTab) { - const char kHistogramName[] = "TabManager.SessionRestore.SwitchToTab"; - - TabManager tab_manager; - TabStripDummyDelegate delegate; - TabStripModel tab_strip(&delegate, profile()); - WebContents* tab = CreateWebContents(); - tab_strip.AppendWebContents(tab, true); - - auto* data = tab_manager.GetWebContentsData(tab); - - base::HistogramTester histograms; - histograms.ExpectTotalCount(kHistogramName, 0); - - data->SetTabLoadingState(TAB_IS_LOADING); - tab_manager.RecordSwitchToTab(tab); - tab_manager.RecordSwitchToTab(tab); - - // Nothing should happen until we're in a session restore - histograms.ExpectTotalCount(kHistogramName, 0); - - tab_manager.OnSessionRestoreStartedLoadingTabs(); - - data->SetTabLoadingState(TAB_IS_NOT_LOADING); - tab_manager.RecordSwitchToTab(tab); - tab_manager.RecordSwitchToTab(tab); - histograms.ExpectTotalCount(kHistogramName, 2); - histograms.ExpectBucketCount(kHistogramName, TAB_IS_NOT_LOADING, 2); - - data->SetTabLoadingState(TAB_IS_LOADING); - tab_manager.RecordSwitchToTab(tab); - tab_manager.RecordSwitchToTab(tab); - tab_manager.RecordSwitchToTab(tab); - - histograms.ExpectTotalCount(kHistogramName, 5); - histograms.ExpectBucketCount(kHistogramName, TAB_IS_NOT_LOADING, 2); - histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADING, 3); - - data->SetTabLoadingState(TAB_IS_LOADED); - tab_manager.RecordSwitchToTab(tab); - tab_manager.RecordSwitchToTab(tab); - tab_manager.RecordSwitchToTab(tab); - tab_manager.RecordSwitchToTab(tab); - - histograms.ExpectTotalCount(kHistogramName, 9); - histograms.ExpectBucketCount(kHistogramName, TAB_IS_NOT_LOADING, 2); - histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADING, 3); - histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADED, 4); - - // Tabs with a committed URL must be closed explicitly to avoid DCHECK errors. - tab_strip.CloseAllTabs(); -} - TEST_F(TabManagerTest, MaybeThrottleNavigation) { TabManager* tab_manager = g_browser_process->GetTabManager(); MaybeThrottleNavigations(tab_manager);
diff --git a/chrome/browser/resource_coordinator/tab_manager_web_contents_data.h b/chrome/browser/resource_coordinator/tab_manager_web_contents_data.h index 379b46b..361e1db9 100644 --- a/chrome/browser/resource_coordinator/tab_manager_web_contents_data.h +++ b/chrome/browser/resource_coordinator/tab_manager_web_contents_data.h
@@ -141,7 +141,6 @@ // Needed to access tab_data_. FRIEND_TEST_ALL_PREFIXES(TabManagerWebContentsDataTest, CopyState); FRIEND_TEST_ALL_PREFIXES(TabManagerWebContentsDataTest, TabLoadingState); - FRIEND_TEST_ALL_PREFIXES(TabManagerTest, HistogramsSessionRestoreSwitchToTab); struct Data { Data();
diff --git a/chrome/browser/resources/md_extensions/pack_dialog.html b/chrome/browser/resources/md_extensions/pack_dialog.html index b315a819..9ef2cd4 100644 --- a/chrome/browser/resources/md_extensions/pack_dialog.html +++ b/chrome/browser/resources/md_extensions/pack_dialog.html
@@ -1,8 +1,9 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
diff --git a/chrome/browser/resources/md_extensions/shortcut_input.html b/chrome/browser/resources/md_extensions/shortcut_input.html index 44a916d8..3645469 100644 --- a/chrome/browser/resources/md_extensions/shortcut_input.html +++ b/chrome/browser/resources/md_extensions/shortcut_input.html
@@ -1,8 +1,9 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> <link rel="import" href="chrome://extensions/shortcut_util.html">
diff --git a/chrome/browser/resources/md_extensions/toolbar.html b/chrome/browser/resources/md_extensions/toolbar.html index faa032e..b1f44efdf 100644 --- a/chrome/browser/resources/md_extensions/toolbar.html +++ b/chrome/browser/resources/md_extensions/toolbar.html
@@ -1,6 +1,7 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
diff --git a/chrome/browser/resources/print_preview/data/app_state.js b/chrome/browser/resources/print_preview/data/app_state.js index 6bc3976..ffad895 100644 --- a/chrome/browser/resources/print_preview/data/app_state.js +++ b/chrome/browser/resources/print_preview/data/app_state.js
@@ -177,9 +177,8 @@ return this.state_[field] ? print_preview.Margins.parse(this.state_[field]) : null; - } else { - return this.state_[field]; } + return this.state_[field]; }, /**
diff --git a/chrome/browser/resources/print_preview/data/cloud_parsers.js b/chrome/browser/resources/print_preview/data/cloud_parsers.js index 24ab1b0..25e16c1 100644 --- a/chrome/browser/resources/print_preview/data/cloud_parsers.js +++ b/chrome/browser/resources/print_preview/data/cloud_parsers.js
@@ -108,11 +108,11 @@ if (typeStr == CloudDestinationParser.CloudType_.ANDROID || typeStr == CloudDestinationParser.CloudType_.IOS) { return print_preview.DestinationType.MOBILE; - } else if (typeStr == CloudDestinationParser.CloudType_.DOCS) { - return print_preview.DestinationType.GOOGLE_PROMOTED; - } else { - return print_preview.DestinationType.GOOGLE; } + if (typeStr == CloudDestinationParser.CloudType_.DOCS) { + return print_preview.DestinationType.GOOGLE_PROMOTED; + } + return print_preview.DestinationType.GOOGLE; }; /** Namespace which contains a method to parse printer sharing invitation. */
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js index 0980850e..3ccbb1e 100644 --- a/chrome/browser/resources/print_preview/data/destination_store.js +++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -1341,16 +1341,15 @@ this.destinations_.push(destination); this.destinationMap_[key] = destination; return true; - } else if ( - existingDestination.connectionStatus == + } + if (existingDestination.connectionStatus == print_preview.DestinationConnectionStatus.UNKNOWN && destination.connectionStatus != print_preview.DestinationConnectionStatus.UNKNOWN) { existingDestination.connectionStatus = destination.connectionStatus; return true; - } else { - return false; } + return false; }, /**
diff --git a/chrome/browser/resources/print_preview/data/measurement_system.js b/chrome/browser/resources/print_preview/data/measurement_system.js index 323c195..01c6a55 100644 --- a/chrome/browser/resources/print_preview/data/measurement_system.js +++ b/chrome/browser/resources/print_preview/data/measurement_system.js
@@ -91,12 +91,11 @@ get unitSymbol() { if (this.unitType_ == print_preview.MeasurementSystemUnitType.METRIC) { return 'mm'; - } else if ( - this.unitType_ == print_preview.MeasurementSystemUnitType.IMPERIAL) { - return '"'; - } else { - throw Error('Unit type not supported: ' + this.unitType_); } + if (this.unitType_ == print_preview.MeasurementSystemUnitType.IMPERIAL) { + return '"'; + } + throw Error('Unit type not supported: ' + this.unitType_); }, /** @@ -141,9 +140,8 @@ convertFromPoints: function(pts) { if (this.unitType_ == print_preview.MeasurementSystemUnitType.METRIC) { return pts / MeasurementSystem.PTS_PER_MM_; - } else { - return pts / MeasurementSystem.PTS_PER_INCH_; } + return pts / MeasurementSystem.PTS_PER_INCH_; }, /** @@ -153,9 +151,8 @@ convertToPoints: function(localUnits) { if (this.unitType_ == print_preview.MeasurementSystemUnitType.METRIC) { return localUnits * MeasurementSystem.PTS_PER_MM_; - } else { - return localUnits * MeasurementSystem.PTS_PER_INCH_; } + return localUnits * MeasurementSystem.PTS_PER_INCH_; } };
diff --git a/chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js b/chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js index ff31b24..753c5164 100644 --- a/chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js +++ b/chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js
@@ -106,15 +106,13 @@ /** @return {print_preview.ValueType} The value of the ticket item. */ getValue: function() { - if (this.isCapabilityAvailable()) { - if (this.value_ == null) { - return this.getDefaultValueInternal(); - } else { - return this.value_; - } - } else { + if (!this.isCapabilityAvailable()) { return this.getCapabilityNotAvailableValueInternal(); } + if (this.value_ == null) { + return this.getDefaultValueInternal(); + } + return this.value_; }, /** @return {boolean} Whether the ticket item was modified by the user. */
diff --git a/chrome/browser/resources/print_preview/previewarea/preview_area.js b/chrome/browser/resources/print_preview/previewarea/preview_area.js index 536c62d4..812305f 100644 --- a/chrome/browser/resources/print_preview/previewarea/preview_area.js +++ b/chrome/browser/resources/print_preview/previewarea/preview_area.js
@@ -523,41 +523,42 @@ if (!this.previewGenerator_) return; var previewRequest = this.previewGenerator_.requestPreview(); - if (previewRequest.id > -1) { - cr.dispatchSimpleEvent( - this, PreviewArea.EventType.PREVIEW_GENERATION_IN_PROGRESS); - if (this.loadingTimeout_ == null) { - this.loadingTimeout_ = setTimeout( - this.showMessage_.bind( - this, print_preview.PreviewAreaMessageId_.LOADING), - PreviewArea.LOADING_TIMEOUT_); - } - previewRequest.request.then( - /** @param {number} previewUid The unique id of the preview. */ - function(previewUid) { - this.previewGenerator_.onPreviewGenerationDone( - previewRequest.id, previewUid); - }.bind(this), - /** - * @param {*} type The type of print preview failure that - * occurred. - */ - function(type) { - if (/** @type{string} */ (type) == 'CANCELLED') - return; // overriden by a new request, do nothing. - else if (/** @type{string} */ (type) == 'SETTINGS_INVALID') { - this.cancelTimeout(); - this.showCustomMessage( - loadTimeData.getString('invalidPrinterSettings')); - cr.dispatchSimpleEvent( - this, PreviewArea.EventType.SETTINGS_INVALID); - } else { - this.onPreviewGenerationFail_(); - } - }.bind(this)); - } else { + if (previewRequest.id <= -1) { this.marginControlContainer_.showMarginControlsIfNeeded(); + return; } + + cr.dispatchSimpleEvent( + this, PreviewArea.EventType.PREVIEW_GENERATION_IN_PROGRESS); + if (this.loadingTimeout_ == null) { + this.loadingTimeout_ = setTimeout( + this.showMessage_.bind( + this, print_preview.PreviewAreaMessageId_.LOADING), + PreviewArea.LOADING_TIMEOUT_); + } + previewRequest.request.then( + /** @param {number} previewUid The unique id of the preview. */ + function(previewUid) { + this.previewGenerator_.onPreviewGenerationDone( + previewRequest.id, previewUid); + }.bind(this), + /** + * @param {*} type The type of print preview failure that + * occurred. + */ + function(type) { + if (/** @type{string} */ (type) == 'CANCELLED') + return; // overriden by a new request, do nothing. + if (/** @type{string} */ (type) == 'SETTINGS_INVALID') { + this.cancelTimeout(); + this.showCustomMessage( + loadTimeData.getString('invalidPrinterSettings')); + cr.dispatchSimpleEvent( + this, PreviewArea.EventType.SETTINGS_INVALID); + } else { + this.onPreviewGenerationFail_(); + } + }.bind(this)); }, /**
diff --git a/chrome/browser/resources/print_preview/settings/page_settings.js b/chrome/browser/resources/print_preview/settings/page_settings.js index 4002ca61..f8f70ee 100644 --- a/chrome/browser/resources/print_preview/settings/page_settings.js +++ b/chrome/browser/resources/print_preview/settings/page_settings.js
@@ -146,28 +146,28 @@ * @private */ setInvalidStateVisible_: function(validity) { - if (validity !== PageRangeStatus.NO_ERROR) { - var message; - if (validity === PageRangeStatus.LIMIT_ERROR) { - if (this.pageRangeTicketItem_.getDocumentNumPages()) { - message = loadTimeData.getStringF( - 'pageRangeLimitInstructionWithValue', - this.pageRangeTicketItem_.getDocumentNumPages()); - } else { - message = loadTimeData.getString('pageRangeLimitInstruction'); - } - } else { - message = loadTimeData.getStringF( - 'pageRangeSyntaxInstruction', - loadTimeData.getString('examplePageRangeText')); - } - this.customHintEl_.textContent = message; - this.customInput_.classList.add('invalid'); - fadeInElement(this.customHintEl_); - } else { + if (validity === PageRangeStatus.NO_ERROR) { this.customInput_.classList.remove('invalid'); fadeOutElement(this.customHintEl_); + return; } + var message; + if (validity === PageRangeStatus.LIMIT_ERROR) { + if (this.pageRangeTicketItem_.getDocumentNumPages()) { + message = loadTimeData.getStringF( + 'pageRangeLimitInstructionWithValue', + this.pageRangeTicketItem_.getDocumentNumPages()); + } else { + message = loadTimeData.getString('pageRangeLimitInstruction'); + } + } else { + message = loadTimeData.getStringF( + 'pageRangeSyntaxInstruction', + loadTimeData.getString('examplePageRangeText')); + } + this.customHintEl_.textContent = message; + this.customInput_.classList.add('invalid'); + fadeInElement(this.customHintEl_); }, /**
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html index c1456201..2b0ec22 100644 --- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html +++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html
@@ -1,5 +1,7 @@ -<link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html"> @@ -42,7 +44,7 @@ #show-files-button { --paper-button-ink-color: white; /* Left-align the text of the button with the rest of the card's text */ - -webkit-margin-start: calc(var(--settings-button-edge-spacing) * -1); + -webkit-margin-start: calc(var(--cr-button-edge-spacing) * -1); color: var(--google-blue-700); text-transform: inherit; }
diff --git a/chrome/browser/resources/settings/controls/controlled_button.html b/chrome/browser/resources/settings/controls/controlled_button.html index 5cc109a..e013479 100644 --- a/chrome/browser/resources/settings/controls/controlled_button.html +++ b/chrome/browser/resources/settings/controls/controlled_button.html
@@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="pref_control_behavior.html"> <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../settings_shared_css.html"> @@ -13,8 +14,8 @@ <style include="settings-shared"> :host { --justify-margin: 8px; - -webkit-margin-end: calc(var(--settings-button-edge-spacing) * -1); - -webkit-margin-start: calc(var(--settings-button-edge-spacing) * -1); + -webkit-margin-end: calc(var(--cr-button-edge-spacing) * -1); + -webkit-margin-start: calc(var(--cr-button-edge-spacing) * -1); align-items: center; display: flex; }
diff --git a/chrome/browser/resources/settings/people_page/change_picture.js b/chrome/browser/resources/settings/people_page/change_picture.js index fe9f948..26c9ff6 100644 --- a/chrome/browser/resources/settings/people_page/change_picture.js +++ b/chrome/browser/resources/settings/people_page/change_picture.js
@@ -88,6 +88,7 @@ currentRouteChanged: function(newRoute) { if (newRoute == settings.routes.CHANGE_PICTURE) { this.browserProxy_.initialize(); + this.browserProxy_.requestSelectedImage(); this.pictureList_.setFocus(); } else { // Ensure we deactivate the camera when we navigate away.
diff --git a/chrome/browser/resources/settings/people_page/change_picture_browser_proxy.js b/chrome/browser/resources/settings/people_page/change_picture_browser_proxy.js index d6dc9b9..1d682e8 100644 --- a/chrome/browser/resources/settings/people_page/change_picture_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/change_picture_browser_proxy.js
@@ -61,6 +61,9 @@ * expected. */ chooseFile() {} + + /** Requests the currently selected image. */ + requestSelectedImage() {} } /** @@ -96,6 +99,11 @@ chooseFile() { chrome.send('chooseFile'); } + + /** @override */ + requestSelectedImage() { + chrome.send('requestSelectedImage'); + } } // The singleton instance_ is replaced with a test version of this wrapper
diff --git a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js index a04c9a79..808d616ba 100644 --- a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js +++ b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js
@@ -367,16 +367,28 @@ currentDialog_: String, /** @private {boolean} */ - showDiscoveryDialog_: Boolean, + showDiscoveryDialog_: { + type: Boolean, + value: false, + }, /** @private {boolean} */ - showManuallyAddDialog_: Boolean, + showManuallyAddDialog_: { + type: Boolean, + value: false, + }, /** @private {boolean} */ - showConfiguringDialog_: Boolean, + showConfiguringDialog_: { + type: Boolean, + value: false, + }, /** @private {boolean} */ - showManufacturerDialog_: Boolean, + showManufacturerDialog_: { + type: Boolean, + value: false, + }, }, listeners: { @@ -525,6 +537,7 @@ // "ADD PRINTER" button. if (!this.previousDialog_) { this.$$('add-printer-discovery-dialog').close(); + this.newPrinter = getEmptyPrinter_(); this.openManuallyAddPrinterDialog_(); } },
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers.html b/chrome/browser/resources/settings/printing_page/cups_printers.html index c6ffedd..6a3b9fe 100644 --- a/chrome/browser/resources/settings/printing_page/cups_printers.html +++ b/chrome/browser/resources/settings/printing_page/cups_printers.html
@@ -12,16 +12,17 @@ <dom-module id="settings-cups-printers"> <template> <style include="settings-shared action-link"> - .settings-box .start { - color: var(--paper-grey-600); - } - .settings-box .start .secondary { color: var(--paper-grey-800); font-size: 92.31%; /* 12px / 13px */ } - + .settings-box .primary-button { + --paper-button-disabled: { + background: none; + color: black; + opacity: 0.26; + }; -webkit-margin-end: 0; -webkit-margin-start: auto; } @@ -55,14 +56,19 @@ </style> <div class="settings-box first"> + <div class="start"> + <span>$i18n{cupsPrintersLearnMoreLabel}</span> + <a href="$i18n{printingCUPSPrintLearnMoreUrl}" target="_blank"> + $i18n{learnMore} + </a> + <div class="secondary" hidden="[[canAddPrinter_]]"> + $i18n{requireNetworkMessage} + </div> + </div> <paper-button class="primary-button" id="addPrinter" - on-tap="onAddPrinterTap_" hidden="[[!canAddPrinter_]]"> + on-tap="onAddPrinterTap_" disabled="[[!canAddPrinter_]]"> $i18n{addCupsPrinter} </paper-button> - <div class="start" hidden="[[canAddPrinter_]]"> - <span>$i18n{addCupsPrinter}</span> - <div class="secondary">$i18n{requireNetworkMessage}</div> - </div> </div> <settings-cups-add-printer-dialog id="addPrinterDialog"
diff --git a/chrome/browser/resources/settings/printing_page/printing_page.html b/chrome/browser/resources/settings/printing_page/printing_page.html index 48b76bb8..6f9f7516 100644 --- a/chrome/browser/resources/settings/printing_page/printing_page.html +++ b/chrome/browser/resources/settings/printing_page/printing_page.html
@@ -31,14 +31,9 @@ </div> </template> </if> - <div id="cloudPrinters" class="settings-box two-line" + <div id="cloudPrinters" class="settings-box" on-tap="onTapCloudPrinters_" actionable> - <div class="start"> - $i18n{cloudPrintersTitle} - <div class="secondary" id="cloudPrintersSecondary"> - $i18n{cloudPrintersTitleDescription} - </div> - </div> + <div class="start">$i18n{cloudPrintersTitle}</div> <button class="subpage-arrow" is="paper-icon-button-light" aria-label="$i18n{cloudPrintersTitle}" aria-describedby="cloudPrintersSecondary"></button>
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html index 0591b4d2..279c57df 100644 --- a/chrome/browser/resources/settings/settings_shared_css.html +++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -1,3 +1,5 @@ +<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="settings_icons_css.html"> <link rel="import" href="settings_vars_css.html"> @@ -5,7 +7,7 @@ <!-- Common styles for Material Design settings. --> <dom-module id="settings-shared"> <template> - <style include="settings-icons cr-shared-style"> + <style include="settings-icons paper-button-style cr-shared-style"> /* Prevent action-links from being selected to avoid accidental * selection when trying to click it. */ a[is=action-link] { @@ -38,25 +40,7 @@ -webkit-margin-start: var(--cr-icon-ripple-margin); } - /* See notes in .primary-button. - * TODO(dschuyler): Remove unnecessary .secondary-button references. */ - paper-button { - --paper-button: { - -webkit-padding-end: var(--settings-button-edge-spacing); - -webkit-padding-start: var(--settings-button-edge-spacing); - color: var(--paper-grey-600); - font-weight: 500; - min-width: 1em; /* A tighter fit than 5.14em for short buttons. */ - text-decoration: none; - }; - --paper-button-flat-keyboard-focus: { - background: rgba(0, 0, 0, .12); - }; - flex-shrink: 0; - height: 36px; - margin: 0; - } - + /* For "Advanced" toggle button. */ paper-button[toggles][active] { background-color: var(--paper-grey-300); } @@ -64,7 +48,7 @@ /* If a button is at the end of the row, shift it to overlap the end of * the row. */ .settings-box paper-button:last-of-type { - -webkit-margin-end: calc(var(--settings-button-edge-spacing) * -1); + -webkit-margin-end: calc(var(--cr-button-edge-spacing) * -1); } /* Special case for buttons inside of toggle-buttons. */ @@ -79,7 +63,7 @@ /* Adjust the margin between the separator and the first button. */ .settings-box .separator + paper-button { - -webkit-margin-start: calc(var(--settings-button-edge-spacing) * -1); + -webkit-margin-start: calc(var(--cr-button-edge-spacing) * -1); } /* There are two settings button styles, .primary-button and normal
diff --git a/chrome/browser/resources/settings/settings_vars_css.html b/chrome/browser/resources/settings/settings_vars_css.html index 9de80593..153aa5e 100644 --- a/chrome/browser/resources/settings/settings_vars_css.html +++ b/chrome/browser/resources/settings/settings_vars_css.html
@@ -13,7 +13,6 @@ * UX design (bettes@). */ --settings-actionable: var(--cr-actionable); - --settings-button-edge-spacing: 12px; --settings-box-row-padding: 20px; --settings-box-row-indent: calc(
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index ac80a07..09f9903 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -40,6 +40,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/browser/threat_details.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" +#include "components/safe_browsing/web_ui/constants.h" #include "components/safe_browsing_db/database_manager.h" #include "components/safe_browsing_db/test_database_manager.h" #include "components/safe_browsing_db/util.h" @@ -802,6 +803,31 @@ EXPECT_TRUE(YesInterstitial()); } +IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, HardcodedUrls) { + const GURL urls[] = {GURL(kChromeUISafeBrowsingMatchMalwareUrl), + GURL(kChromeUISafeBrowsingMatchPhishingUrl), + GURL(kChromeUISafeBrowsingMatchUnwantedUrl)}; + + for (const GURL& url : urls) { + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_TRUE(WaitForReady(browser())); + + EXPECT_EQ(VISIBLE, GetVisibility("primary-button")); + EXPECT_EQ(HIDDEN, GetVisibility("details")); + EXPECT_EQ(HIDDEN, GetVisibility("proceed-link")); + EXPECT_EQ(HIDDEN, GetVisibility("error-code")); + EXPECT_TRUE(Click("details-button")); + EXPECT_EQ(VISIBLE, GetVisibility("details")); + EXPECT_EQ(VISIBLE, GetVisibility("proceed-link")); + EXPECT_EQ(HIDDEN, GetVisibility("error-code")); + EXPECT_TRUE(ClickAndWaitForDetach("primary-button")); + + AssertNoInterstitial(false); // Assert the interstitial is gone + EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank" + browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + } +} + IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, DontProceed) { SetupWarningAndNavigate(browser());
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 8dbeb11..75e3f7a5 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -114,9 +114,9 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/printing/printers_manager.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" #include "chrome/browser/chromeos/printing/printers_sync_bridge.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/ui/app_list/arc/arc_package_sync_data_type_controller.h" #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h" #include "components/sync_wifi/wifi_credential_syncable_service.h" @@ -507,7 +507,8 @@ web_data_service_.get()); #if defined(OS_CHROMEOS) case syncer::PRINTERS: - return chromeos::PrintersManagerFactory::GetForBrowserContext(profile_) + return chromeos::SyncedPrintersManagerFactory::GetForBrowserContext( + profile_) ->GetSyncBridge() ->AsWeakPtr(); #endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc index f066d65c..3ce1976 100644 --- a/chrome/browser/sync/profile_sync_service_factory.cc +++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -68,7 +68,7 @@ #endif // !defined(OS_ANDROID) #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "components/sync_wifi/wifi_credential_syncable_service_factory.h" #endif // defined(OS_CHROMEOS) @@ -159,7 +159,7 @@ extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); #endif // BUILDFLAG(ENABLE_EXTENSIONS) #if defined(OS_CHROMEOS) - DependsOn(chromeos::PrintersManagerFactory::GetInstance()); + DependsOn(chromeos::SyncedPrintersManagerFactory::GetInstance()); DependsOn(sync_wifi::WifiCredentialSyncableServiceFactory::GetInstance()); #endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/sync/test/integration/printers_helper.cc b/chrome/browser/sync/test/integration/printers_helper.cc index 540b37f..d1d8a196 100644 --- a/chrome/browser/sync/test/integration/printers_helper.cc +++ b/chrome/browser/sync/test/integration/printers_helper.cc
@@ -14,8 +14,8 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/threading/sequenced_worker_pool.h" -#include "chrome/browser/chromeos/printing/printers_manager.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "content/public/test/test_utils.h" @@ -67,9 +67,10 @@ return base::StringPrintf("printer%d", index); } -chromeos::PrintersManager* GetPrinterStore(content::BrowserContext* context) { - chromeos::PrintersManager* manager = - chromeos::PrintersManagerFactory::GetForBrowserContext(context); +chromeos::SyncedPrintersManager* GetPrinterStore( + content::BrowserContext* context) { + chromeos::SyncedPrintersManager* manager = + chromeos::SyncedPrintersManagerFactory::GetForBrowserContext(context); // TODO(sync): crbug.com/709094: Remove all of this once the bug is fixed. // Must wait for ModelTypeStore initialization. It is fairly difficult to get @@ -85,17 +86,17 @@ } // namespace -void AddPrinter(chromeos::PrintersManager* manager, +void AddPrinter(chromeos::SyncedPrintersManager* manager, const chromeos::Printer& printer) { manager->RegisterPrinter(base::MakeUnique<chromeos::Printer>(printer)); } -void RemovePrinter(chromeos::PrintersManager* manager, int index) { +void RemovePrinter(chromeos::SyncedPrintersManager* manager, int index) { chromeos::Printer testPrinter(CreateTestPrinter(index)); manager->RemovePrinter(testPrinter.id()); } -bool EditPrinterDescription(chromeos::PrintersManager* manager, +bool EditPrinterDescription(chromeos::SyncedPrintersManager* manager, int index, const std::string& description) { PrinterList printers = manager->GetPrinters(); @@ -123,15 +124,15 @@ return printer; } -chromeos::PrintersManager* GetVerifierPrinterStore() { - chromeos::PrintersManager* manager = +chromeos::SyncedPrintersManager* GetVerifierPrinterStore() { + chromeos::SyncedPrintersManager* manager = GetPrinterStore(sync_datatype_helper::test()->verifier()); return manager; } -chromeos::PrintersManager* GetPrinterStore(int index) { - chromeos::PrintersManager* manager = +chromeos::SyncedPrintersManager* GetPrinterStore(int index) { + chromeos::SyncedPrintersManager* manager = GetPrinterStore(sync_datatype_helper::test()->GetProfile(index)); return manager;
diff --git a/chrome/browser/sync/test/integration/printers_helper.h b/chrome/browser/sync/test/integration/printers_helper.h index a88265c..c68d16e 100644 --- a/chrome/browser/sync/test/integration/printers_helper.h +++ b/chrome/browser/sync/test/integration/printers_helper.h
@@ -8,7 +8,7 @@ #include <memory> #include <string> -#include "chrome/browser/chromeos/printing/printers_manager.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" #include "chrome/browser/sync/test/integration/await_match_status_change_checker.h" #include "chromeos/printing/printer_configuration.h" @@ -22,23 +22,23 @@ chromeos::Printer CreateTestPrinter(int index); // Add printer to the supplied store. -void AddPrinter(chromeos::PrintersManager* manager, +void AddPrinter(chromeos::SyncedPrintersManager* manager, const chromeos::Printer& printer); // Remove printer |index| from the |manager|. -void RemovePrinter(chromeos::PrintersManager* manager, int index); +void RemovePrinter(chromeos::SyncedPrintersManager* manager, int index); // Change the description of the printer at |index| with |description|. Returns // false if the printer is not tracked by the manager. -bool EditPrinterDescription(chromeos::PrintersManager* manager, +bool EditPrinterDescription(chromeos::SyncedPrintersManager* manager, int index, const std::string& description); // Returns the verifier store. -chromeos::PrintersManager* GetVerifierPrinterStore(); +chromeos::SyncedPrintersManager* GetVerifierPrinterStore(); // Returns printer store at |index|. -chromeos::PrintersManager* GetPrinterStore(int index); +chromeos::SyncedPrintersManager* GetPrinterStore(int index); // Returns the number of printers in the verifier store. int GetVerifierPrinterCount();
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc index fdc9a99..eb7e503 100644 --- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc
@@ -18,6 +18,7 @@ #include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "components/autofill/core/browser/autofill_metrics.h" +#include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/common/autofill_pref_names.h" #include "components/user_prefs/user_prefs.h" @@ -91,9 +92,11 @@ base::Bind(&SaveCardCallback)); } - void ShowLocalBubble() { - controller()->ShowBubbleForLocalSave(CreditCard(), - base::Bind(&SaveCardCallback)); + void ShowLocalBubble(CreditCard* card = nullptr) { + controller()->ShowBubbleForLocalSave( + card ? CreditCard(*card) + : autofill::test::GetCreditCard(), // Visa by default + base::Bind(&SaveCardCallback)); } void ShowUploadBubble(bool should_cvc_be_requested = false) { @@ -160,7 +163,7 @@ TEST_F(SaveCardBubbleControllerImplTest, PropagateShouldRequestCvcFromUserWhenTrue) { - ShowUploadBubble(true /* should_cvc_be_requested */); + ShowUploadBubble(/*should_cvc_be_requested=*/true); EXPECT_TRUE(controller()->ShouldRequestCvcFromUser()); } @@ -203,7 +206,7 @@ TEST_F(SaveCardBubbleControllerImplTest, Metrics_Upload_FirstShow_ShowBubble_RequestCvc) { base::HistogramTester histogram_tester; - ShowUploadBubble(true /* should_cvc_be_requested */); + ShowUploadBubble(/*should_cvc_be_requested=*/true); EXPECT_THAT( histogram_tester.GetAllSamples( @@ -212,7 +215,8 @@ Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1))); } -TEST_F(SaveCardBubbleControllerImplTest, Metrics_Upload_Reshows_ShowBubble) { +TEST_F(SaveCardBubbleControllerImplTest, + Metrics_Upload_Reshows_ShowBubble_NotRequestCvc) { ShowUploadBubble(); base::HistogramTester histogram_tester; @@ -225,6 +229,20 @@ Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1))); } +TEST_F(SaveCardBubbleControllerImplTest, + Metrics_Upload_Reshows_ShowBubble_RequestCvc) { + ShowUploadBubble(/*should_cvc_be_requested=*/true); + + base::HistogramTester histogram_tester; + CloseAndReshowBubble(); + + EXPECT_THAT( + histogram_tester.GetAllSamples( + "Autofill.SaveCreditCardPrompt.Upload.Reshows"), + ElementsAre(Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, 1), + Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1))); +} + TEST_F(SaveCardBubbleControllerImplTest, Metrics_Local_FirstShow_SaveButton) { ShowLocalBubble(); @@ -337,8 +355,17 @@ ShowLocalBubble(); base::HistogramTester histogram_tester; - // Fake-navigate after bubble has been visible for a long time. - controller()->set_elapsed(base::TimeDelta::FromMinutes(1)); + // The bubble should still stick around for up to kSurviveNavigationSeconds + // (5) seconds regardless of navigation. + controller()->set_elapsed(base::TimeDelta::FromSeconds(3)); + + controller()->SimulateNavigation(); + + histogram_tester.ExpectTotalCount( + "Autofill.SaveCreditCardPrompt.Local.FirstShow", 0); + + // Wait 3 more seconds (6 total); bubble should go away on next navigation. + controller()->set_elapsed(base::TimeDelta::FromSeconds(6)); controller()->SimulateNavigation(); @@ -353,8 +380,18 @@ CloseAndReshowBubble(); base::HistogramTester histogram_tester; - // Fake-navigate after bubble has been visible for a long time. - controller()->set_elapsed(base::TimeDelta::FromMinutes(1)); + // The bubble should still stick around for up to kSurviveNavigationSeconds + // (5) seconds regardless of navigation. + controller()->set_elapsed(base::TimeDelta::FromSeconds(3)); + + controller()->SimulateNavigation(); + + histogram_tester.ExpectTotalCount( + "Autofill.SaveCreditCardPrompt.Local.Reshows", 0); + + // Wait 3 more seconds (6 total); bubble should go away on next navigation. + controller()->set_elapsed(base::TimeDelta::FromSeconds(6)); + controller()->SimulateNavigation(); histogram_tester.ExpectUniqueSample( @@ -363,6 +400,55 @@ } TEST_F(SaveCardBubbleControllerImplTest, + Metrics_Upload_FirstShow_NavigateWhileShowing) { + ShowUploadBubble(); + + base::HistogramTester histogram_tester; + // The bubble should still stick around for up to kSurviveNavigationSeconds + // (5) seconds regardless of navigation. + controller()->set_elapsed(base::TimeDelta::FromSeconds(3)); + + controller()->SimulateNavigation(); + + histogram_tester.ExpectTotalCount( + "Autofill.SaveCreditCardPrompt.Upload.FirstShow", 0); + + // Wait 3 more seconds (6 total); bubble should go away on next navigation. + controller()->set_elapsed(base::TimeDelta::FromSeconds(6)); + + controller()->SimulateNavigation(); + + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Upload.FirstShow", + AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING, 1); +} + +TEST_F(SaveCardBubbleControllerImplTest, + Metrics_Upload_Reshows_NavigateWhileShowing) { + ShowUploadBubble(); + CloseAndReshowBubble(); + + base::HistogramTester histogram_tester; + // The bubble should still stick around for up to kSurviveNavigationSeconds + // (5) seconds regardless of navigation. + controller()->set_elapsed(base::TimeDelta::FromSeconds(3)); + + controller()->SimulateNavigation(); + + histogram_tester.ExpectTotalCount( + "Autofill.SaveCreditCardPrompt.Upload.Reshows", 0); + + // Wait 3 more seconds (6 total); bubble should go away on next navigation. + controller()->set_elapsed(base::TimeDelta::FromSeconds(6)); + + controller()->SimulateNavigation(); + + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Upload.Reshows", + AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING, 1); +} + +TEST_F(SaveCardBubbleControllerImplTest, Metrics_Local_FirstShow_NavigateWhileHidden) { ShowLocalBubble(); @@ -393,6 +479,60 @@ AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_HIDDEN, 1); } +TEST_F(SaveCardBubbleControllerImplTest, + Metrics_Upload_FirstShow_NavigateWhileHidden) { + ShowUploadBubble(); + + base::HistogramTester histogram_tester; + controller()->OnBubbleClosed(); + // Fake-navigate after bubble has been visible for a long time. + controller()->set_elapsed(base::TimeDelta::FromMinutes(1)); + controller()->SimulateNavigation(); + + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Upload.FirstShow", + AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_HIDDEN, 1); +} + +TEST_F(SaveCardBubbleControllerImplTest, + Metrics_Upload_Reshows_NavigateWhileHidden) { + ShowUploadBubble(); + CloseAndReshowBubble(); + + base::HistogramTester histogram_tester; + controller()->OnBubbleClosed(); + // Fake-navigate after bubble has been visible for a long time. + controller()->set_elapsed(base::TimeDelta::FromMinutes(1)); + controller()->SimulateNavigation(); + + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Upload.Reshows", + AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_HIDDEN, 1); +} + +TEST_F(SaveCardBubbleControllerImplTest, Metrics_Local_FirstShow_LearnMore) { + ShowLocalBubble(); + + base::HistogramTester histogram_tester; + controller()->OnLearnMoreClicked(); + + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Local.FirstShow", + AutofillMetrics::SAVE_CARD_PROMPT_DISMISS_CLICK_LEARN_MORE, 1); +} + +TEST_F(SaveCardBubbleControllerImplTest, Metrics_Local_Reshows_LearnMore) { + ShowLocalBubble(); + CloseAndReshowBubble(); + + base::HistogramTester histogram_tester; + controller()->OnLearnMoreClicked(); + + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Local.Reshows", + AutofillMetrics::SAVE_CARD_PROMPT_DISMISS_CLICK_LEARN_MORE, 1); +} + TEST_F(SaveCardBubbleControllerImplTest, Metrics_Upload_FirstShow_LearnMore) { ShowUploadBubble(); @@ -523,4 +663,27 @@ .empty()); } +TEST_F(SaveCardBubbleControllerImplTest, TestInputCvcIsValid) { + // Note: InputCvcIsValid(~) handles string trimming. + // 3-digit CVC: + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("text"))); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16(""))); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("1"))); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("12"))); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("12 "))); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("1234"))); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("12345"))); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("1x3"))); + EXPECT_TRUE(controller()->InputCvcIsValid(base::ASCIIToUTF16("123"))); + EXPECT_TRUE(controller()->InputCvcIsValid(base::ASCIIToUTF16("123 "))); + EXPECT_TRUE(controller()->InputCvcIsValid(base::ASCIIToUTF16(" 123"))); + EXPECT_TRUE(controller()->InputCvcIsValid(base::ASCIIToUTF16("999"))); + // 4-digit CVC: + CreditCard amex = autofill::test::GetCreditCard2(); // Amex + ShowLocalBubble(&amex); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("123"))); + EXPECT_TRUE(controller()->InputCvcIsValid(base::ASCIIToUTF16("1234"))); + EXPECT_FALSE(controller()->InputCvcIsValid(base::ASCIIToUTF16("12345"))); +} + } // namespace autofill
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc index ec95ae6..79ac1d8 100644 --- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc +++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -1181,7 +1181,7 @@ EnsureFindBoxOpen(); EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText()); - EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText()); + EXPECT_EQ(ASCIIToUTF16("1/1"), GetMatchCountText()); // Close the Find box. browser()->GetFindBarController()->EndFindSession( @@ -1194,7 +1194,7 @@ // After the Find box has been reopened, it should have been prepopulated with // the word "page" again. EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText()); - EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText()); + EXPECT_EQ(ASCIIToUTF16("1/1"), GetMatchCountText()); } // This tests that whenever you open Find in a new tab it should prepopulate @@ -1211,7 +1211,7 @@ browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_EQ(1, FindInPageASCII(web_contents_1, "page", kFwd, kIgnoreCase, &ordinal)); - EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText()); + EXPECT_EQ(ASCIIToUTF16("1/1"), GetMatchCountText()); // Now create a second tab and load the same page. chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED); @@ -1474,14 +1474,14 @@ GURL url = GetURL(kSimple); ui_test_utils::NavigateToURL(browser(), url); - // Change the match count on the first tab to "1 of 1". + // Change the match count on the first tab to "1/1". int ordinal = 0; WebContents* web_contents_1 = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_EQ(1, FindInPageASCII(web_contents_1, "page", kFwd, kIgnoreCase, &ordinal)); EnsureFindBoxOpen(); - EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText()); + EXPECT_EQ(ASCIIToUTF16("1/1"), GetMatchCountText()); // Next, do a search in a second tab. chrome::AddTabAt(browser(), GURL(), -1, true); @@ -1489,7 +1489,7 @@ WebContents* web_contents_2 = browser()->tab_strip_model()->GetActiveWebContents(); FindInPageASCII(web_contents_2, "text", kFwd, kIgnoreCase, &ordinal); - EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText()); + EXPECT_EQ(ASCIIToUTF16("1/1"), GetMatchCountText()); // Go back to the first tab and verify that the match text is cleared. // text to "text". @@ -1528,8 +1528,8 @@ FindInPageASCII(web_contents_incognito, "foo", true, kIgnoreCase, NULL); EXPECT_EQ(ASCIIToUTF16("foo"), GetFindBarTextForBrowser(browser_incognito)); - EXPECT_EQ(ASCIIToUTF16("1 of 2"), - GetFindBarMatchCountTextForBrowser(browser_incognito)); + EXPECT_EQ(ASCIIToUTF16("1/2"), + GetFindBarMatchCountTextForBrowser(browser_incognito)); // Close the find bar. FindTabHelper* find_tab_helper = @@ -1544,7 +1544,7 @@ observer.Wait(); EXPECT_EQ(ASCIIToUTF16("foo"), GetFindBarTextForBrowser(browser_incognito)); - EXPECT_EQ(ASCIIToUTF16("2 of 2"), + EXPECT_EQ(ASCIIToUTF16("2/2"), GetFindBarMatchCountTextForBrowser(browser_incognito)); }
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc index 4f0345d..6d0d42b9 100644 --- a/chrome/browser/ui/views/find_bar_view.cc +++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/find_bar_host.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h" @@ -42,20 +43,12 @@ #include "ui/views/controls/separator.h" #include "ui/views/layout/box_layout.h" #include "ui/views/painter.h" +#include "ui/views/view_properties.h" #include "ui/views/view_targeter.h" #include "ui/views/widget/widget.h" namespace { -// These layout constants are all in dp. -// The horizontal and vertical insets for the bar. -const int kInteriorPadding = 8; -// Default spacing between child views. -const int kInterChildSpacing = 4; -// Additional spacing around the separator. -const int kSeparatorLeftSpacing = 12 - kInterChildSpacing; -const int kSeparatorRightSpacing = 8 - kInterChildSpacing; - // The default number of average characters that the text box will be. const int kDefaultCharWidth = 30; @@ -161,15 +154,56 @@ base::MakeUnique<views::ViewTargeter>(this)); AddChildViewAt(match_count_text_, 1); - separator_->SetBorder(views::CreateEmptyBorder(0, kSeparatorLeftSpacing, 0, - kSeparatorRightSpacing)); + ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); + AddChildViewAt(separator_, 2); + // Normally we could space objects horizontally by simply passing a constant + // value to BoxLayout for between-child spacing. But for the vector image + // buttons, we want the spacing to apply between the inner "glyph" portions + // of the buttons, ignoring the surrounding borders. BoxLayout has no way + // to dynamically adjust for this, so instead of using between-child spacing, + // we place views directly adjacent, with horizontal margins on each view + // that will add up to the right spacing amounts. + + const gfx::Insets horizontal_margin( + 0, + provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL) / 2); + const gfx::Insets vector_button = + provider->GetInsetsMetric(views::INSETS_VECTOR_IMAGE_BUTTON); + const gfx::Insets vector_button_horizontal_margin( + 0, horizontal_margin.left() - vector_button.left(), 0, + horizontal_margin.right() - vector_button.right()); + const gfx::Insets toast_control_vertical_margin( + provider->GetDistanceMetric(DISTANCE_TOAST_CONTROL_VERTICAL), 0); + const gfx::Insets toast_label_vertical_margin( + provider->GetDistanceMetric(DISTANCE_TOAST_LABEL_VERTICAL), 0); + find_previous_button_->SetProperty( + views::kMarginsKey, new gfx::Insets(toast_control_vertical_margin + + vector_button_horizontal_margin)); + find_next_button_->SetProperty( + views::kMarginsKey, new gfx::Insets(toast_control_vertical_margin + + vector_button_horizontal_margin)); + close_button_->SetProperty(views::kMarginsKey, + new gfx::Insets(toast_control_vertical_margin + + vector_button_horizontal_margin)); + separator_->SetProperty( + views::kMarginsKey, + new gfx::Insets(toast_control_vertical_margin + horizontal_margin)); + find_text_->SetProperty( + views::kMarginsKey, + new gfx::Insets(toast_control_vertical_margin + horizontal_margin)); + match_count_text_->SetProperty( + views::kMarginsKey, + new gfx::Insets(toast_label_vertical_margin + horizontal_margin)); + find_text_->SetBorder(views::NullBorder()); - views::BoxLayout* manager = - new views::BoxLayout(views::BoxLayout::kHorizontal, - gfx::Insets(kInteriorPadding), kInterChildSpacing); + views::BoxLayout* manager = new views::BoxLayout( + views::BoxLayout::kHorizontal, + gfx::Insets(provider->GetInsetsMetric(INSETS_TOAST) - horizontal_margin), + 0); + SetLayoutManager(manager); manager->SetFlexForView(find_text_, 1); }
diff --git a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc b/chrome/browser/ui/views/harmony/chrome_layout_provider.cc index c292261..9631f017 100644 --- a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc +++ b/chrome/browser/ui/views/harmony/chrome_layout_provider.cc
@@ -34,6 +34,15 @@ Get()->GetDistanceMetric(DISTANCE_CONTROL_TOTAL_VERTICAL_TEXT_PADDING); } +gfx::Insets ChromeLayoutProvider::GetInsetsMetric(int metric) const { + switch (metric) { + case ChromeInsetsMetric::INSETS_TOAST: + return gfx::Insets(0, 8); + default: + return views::LayoutProvider::GetInsetsMetric(metric); + } +} + int ChromeLayoutProvider::GetDistanceMetric(int metric) const { switch (metric) { case DISTANCE_BUTTON_MINIMUM_WIDTH: @@ -58,6 +67,10 @@ return 20; case DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE: return 30; + case DISTANCE_TOAST_CONTROL_VERTICAL: + return 8; + case DISTANCE_TOAST_LABEL_VERTICAL: + return 12; default: return views::LayoutProvider::GetDistanceMetric(metric); }
diff --git a/chrome/browser/ui/views/harmony/chrome_layout_provider.h b/chrome/browser/ui/views/harmony/chrome_layout_provider.h index c5185da..e931ff9 100644 --- a/chrome/browser/ui/views/harmony/chrome_layout_provider.h +++ b/chrome/browser/ui/views/harmony/chrome_layout_provider.h
@@ -12,6 +12,11 @@ #include "ui/views/layout/grid_layout.h" #include "ui/views/layout/layout_provider.h" +enum ChromeInsetsMetric { + // Margins used by toasts. + INSETS_TOAST = views::VIEWS_INSETS_END, +}; + enum ChromeDistanceMetric { // Default minimum width of a button. DISTANCE_BUTTON_MINIMUM_WIDTH = views::VIEWS_DISTANCE_END, @@ -33,6 +38,10 @@ // Horizontal indent of a subsection relative to related items above, e.g. // checkboxes below explanatory text/headings. DISTANCE_SUBSECTION_HORIZONTAL_INDENT, + // Vertical margin for controls in a toast. + DISTANCE_TOAST_CONTROL_VERTICAL, + // Vertical margin for labels in a toast. + DISTANCE_TOAST_LABEL_VERTICAL, // Horizontal spacing between controls that are logically unrelated. DISTANCE_UNRELATED_CONTROL_HORIZONTAL, // Larger horizontal spacing between unrelated controls. @@ -54,6 +63,7 @@ static int GetControlHeightForFont(const gfx::FontList& font); // views::LayoutProvider: + gfx::Insets GetInsetsMetric(int metric) const override; int GetDistanceMetric(int metric) const override; const views::TypographyProvider& GetTypographyProvider() const override;
diff --git a/chrome/browser/ui/views/harmony/harmony_layout_provider.cc b/chrome/browser/ui/views/harmony/harmony_layout_provider.cc index 03a1890..cbe4d3d 100644 --- a/chrome/browser/ui/views/harmony/harmony_layout_provider.cc +++ b/chrome/browser/ui/views/harmony/harmony_layout_provider.cc
@@ -18,6 +18,8 @@ } case views::INSETS_VECTOR_IMAGE_BUTTON: return gfx::Insets(kHarmonyLayoutUnit / 4); + case INSETS_TOAST: + return gfx::Insets(0, kHarmonyLayoutUnit); default: return ChromeLayoutProvider::GetInsetsMetric(metric); } @@ -73,9 +75,9 @@ return kHarmonyLayoutUnit; case DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE: return kHarmonyLayoutUnit; + default: + return ChromeLayoutProvider::GetDistanceMetric(metric); } - NOTREACHED(); - return 0; } views::GridLayout::Alignment
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc index 7118b9f..c15ebea 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc
@@ -4,17 +4,13 @@ #include "chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h" -#include <stdint.h> - #include "ash/display/window_tree_host_manager.h" #include "ash/shell.h" -#include "base/stl_util.h" #include "content/public/browser/browser_thread.h" #include "ui/display/display.h" +#include "ui/display/display_layout.h" #include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" -#include "ui/events/devices/device_data_manager.h" -#include "ui/events/devices/touchscreen_device.h" using content::BrowserThread; @@ -27,9 +23,6 @@ display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE; } -// TODO(felixe): More context at crbug.com/738885 -const uint16_t kDeviceIds[] = {0x0457, 0x266e}; - } // namespace OobeDisplayChooser::OobeDisplayChooser() : weak_ptr_factory_(this) {} @@ -58,21 +51,18 @@ void OobeDisplayChooser::MoveToTouchDisplay() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - const ui::DeviceDataManager* device_manager = - ui::DeviceDataManager::GetInstance(); - for (const ui::TouchscreenDevice& device : - device_manager->GetTouchscreenDevices()) { - if (!base::ContainsValue(kDeviceIds, device.vendor_id)) - continue; + const display::Displays& displays = + ash::Shell::Get()->display_manager()->active_only_display_list(); - int64_t display_id = - device_manager->GetTargetDisplayForTouchDevice(device.id); - if (display_id == display::kInvalidDisplayId) - continue; + if (displays.size() <= 1) + return; - ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId( - display_id); - break; + for (const display::Display& display : displays) { + if (TouchSupportAvailable(display)) { + ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId( + display.id()); + break; + } } }
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc index 528fd1c..acf074ae 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h" #include <memory> -#include <vector> #include "ash/display/display_configuration_controller.h" #include "ash/shell.h" @@ -14,12 +13,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display.h" #include "ui/display/display_observer.h" -#include "ui/display/manager/chromeos/touchscreen_util.h" #include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" #include "ui/display/test/display_manager_test_api.h" -#include "ui/events/devices/device_data_manager.h" -#include "ui/events/devices/touchscreen_device.h" namespace chromeos { @@ -29,93 +25,63 @@ public: OobeDisplayChooserTest() : ash::test::AshTestBase() {} + void SetUp() override { + ash::test::AshTestBase::SetUp(); + display_manager_test_api_.reset( + new display::test::DisplayManagerTestApi(display_manager())); + } + + void EnableTouch(int64_t id) { + display_manager_test_api_->SetTouchSupport( + id, display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE); + } + + void DisableTouch(int64_t id) { + display_manager_test_api_->SetTouchSupport( + id, display::Display::TouchSupport::TOUCH_SUPPORT_UNAVAILABLE); + } + int64_t GetPrimaryDisplay() { return display::Screen::GetScreen()->GetPrimaryDisplay().id(); } - void UpdateTouchscreenDevices(const ui::TouchscreenDevice& touchscreen) { - std::vector<ui::TouchscreenDevice> devices{touchscreen}; - - ui::DeviceHotplugEventObserver* manager = - ui::DeviceDataManager::GetInstance(); - manager->OnTouchscreenDevicesUpdated(devices); - } - private: + std::unique_ptr<display::test::DisplayManagerTestApi> + display_manager_test_api_; + DISALLOW_COPY_AND_ASSIGN(OobeDisplayChooserTest); }; -const uint16_t kWhitelistedId = 0x266e; - } // namespace TEST_F(OobeDisplayChooserTest, PreferTouchAsPrimary) { - // Setup 2 displays, second one is intended to be a touch display - std::vector<display::ManagedDisplayInfo> display_info; - display_info.push_back( - display::ManagedDisplayInfo::CreateFromSpecWithID("0+0-3000x2000", 1)); - display_info.push_back( - display::ManagedDisplayInfo::CreateFromSpecWithID("3000+0-800x600", 2)); - display_manager()->OnNativeDisplaysChanged(display_info); - base::RunLoop().RunUntilIdle(); - - // Make sure the non-touch display is primary - ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(1); - - // Setup corresponding TouchscreenDevice object - ui::TouchscreenDevice touchscreen = - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, - "Touchscreen", gfx::Size(800, 600), 1); - touchscreen.vendor_id = kWhitelistedId; - UpdateTouchscreenDevices(touchscreen); - base::RunLoop().RunUntilIdle(); - - // Associate touchscreen device with display - display_info[1].AddInputDevice(touchscreen.id); - display_info[1].set_touch_support(display::Display::TOUCH_SUPPORT_AVAILABLE); - display_manager()->OnNativeDisplaysChanged(display_info); - base::RunLoop().RunUntilIdle(); - OobeDisplayChooser display_chooser; - EXPECT_EQ(1, GetPrimaryDisplay()); + + UpdateDisplay("3000x2000,800x600"); + display::DisplayIdList ids = display_manager()->GetCurrentDisplayIdList(); + DisableTouch(ids[0]); + EnableTouch(ids[1]); + + EXPECT_EQ(ids[0], GetPrimaryDisplay()); display_chooser.TryToPlaceUiOnTouchDisplay(); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(2, GetPrimaryDisplay()); + + EXPECT_EQ(ids[1], GetPrimaryDisplay()); } -TEST_F(OobeDisplayChooserTest, DontSwitchFromTouch) { - // Setup 2 displays, second one is intended to be a touch display - std::vector<display::ManagedDisplayInfo> display_info; - display_info.push_back( - display::ManagedDisplayInfo::CreateFromSpecWithID("0+0-3000x2000", 1)); - display_info.push_back( - display::ManagedDisplayInfo::CreateFromSpecWithID("3000+0-800x600", 2)); - display_info[0].set_touch_support(display::Display::TOUCH_SUPPORT_AVAILABLE); - display_manager()->OnNativeDisplaysChanged(display_info); - base::RunLoop().RunUntilIdle(); - - // Make sure the non-touch display is primary - ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(1); - - // Setup corresponding TouchscreenDevice object - ui::TouchscreenDevice touchscreen = - ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, - "Touchscreen", gfx::Size(800, 600), 1); - touchscreen.vendor_id = kWhitelistedId; - UpdateTouchscreenDevices(touchscreen); - base::RunLoop().RunUntilIdle(); - - // Associate touchscreen device with display - display_info[1].AddInputDevice(touchscreen.id); - display_info[1].set_touch_support(display::Display::TOUCH_SUPPORT_AVAILABLE); - display_manager()->OnNativeDisplaysChanged(display_info); - base::RunLoop().RunUntilIdle(); - +TEST_F(OobeDisplayChooserTest, AddingSecondTouchDisplayShouldbeNOP) { OobeDisplayChooser display_chooser; - EXPECT_EQ(1, GetPrimaryDisplay()); + + UpdateDisplay("3000x2000,800x600"); + display::DisplayIdList ids = display_manager()->GetCurrentDisplayIdList(); + EnableTouch(ids[0]); + EnableTouch(ids[1]); + + EXPECT_EQ(ids[0], GetPrimaryDisplay()); display_chooser.TryToPlaceUiOnTouchDisplay(); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, GetPrimaryDisplay()); + + EXPECT_EQ(ids[0], GetPrimaryDisplay()); } } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 94f7115..d2db7e5 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -226,12 +226,17 @@ return path; } -bool IsRemoraRequisitioned() { - policy::DeviceCloudPolicyManagerChromeOS* policy_manager = - g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->GetDeviceCloudPolicyManager(); - return policy_manager && policy_manager->IsRemoraRequisition(); +bool IsKeyboardConnected() { + const std::vector<ui::InputDevice>& keyboards = + ui::InputDeviceManager::GetInstance()->GetKeyboardDevices(); + for (const ui::InputDevice& keyboard : keyboards) { + if (keyboard.type == ui::INPUT_DEVICE_INTERNAL || + keyboard.type == ui::INPUT_DEVICE_EXTERNAL) { + return true; + } + } + + return false; } } // namespace @@ -371,7 +376,7 @@ // TODO(felixe): Display iteration and primary display selection not supported // in Mash. See http://crbug.com/720917. - if (!ash_util::IsRunningInMash() && IsRemoraRequisitioned()) + if (!ash_util::IsRunningInMash() && !IsKeyboardConnected()) oobe_display_chooser_ = base::MakeUnique<OobeDisplayChooser>(); }
diff --git a/chrome/browser/ui/webui/media_router/media_router_file_dialog.cc b/chrome/browser/ui/webui/media_router/media_router_file_dialog.cc index 3d2ee7e..517e61f 100644 --- a/chrome/browser/ui/webui/media_router/media_router_file_dialog.cc +++ b/chrome/browser/ui/webui/media_router/media_router_file_dialog.cc
@@ -154,7 +154,10 @@ base::BindOnce(&MediaRouterFileDialog::ReportFileFormat, base::Unretained(this), selected_file_->local_path)); - // TODO(paezagon): Report file media length. + cancelable_task_tracker_.PostTask( + task_runner_.get(), FROM_HERE, + base::BindOnce(&MediaRouterFileDialog::ReportFileSize, + base::Unretained(this), selected_file_->local_path)); } else { VLOG(1) << "MediaRouterFileDialog did not report file information; no file " "to report."; @@ -187,6 +190,16 @@ reinterpret_cast<const uint8_t*>(buffer), read)); } +void MediaRouterFileDialog::ReportFileSize(const base::FilePath& filename) { + int64_t size; + if (base::GetFileSize(filename, &size)) { + MediaRouterMetrics::RecordMediaRouterFileSize(size); + } else { + VLOG(1) << "Can't get file size for file: " << filename.LossyDisplayName() + << "."; + } +} + void MediaRouterFileDialog::FileSelected(const base::FilePath& path, int index, void* params) {
diff --git a/chrome/browser/ui/webui/media_router/media_router_file_dialog.h b/chrome/browser/ui/webui/media_router/media_router_file_dialog.h index 31bb5f9e..29e8bac5 100644 --- a/chrome/browser/ui/webui/media_router/media_router_file_dialog.h +++ b/chrome/browser/ui/webui/media_router/media_router_file_dialog.h
@@ -114,6 +114,9 @@ // Reports the format of a file to the UMA stats. void ReportFileFormat(const base::FilePath& filename); + // Reports the size of a file to the UMA stats. + void ReportFileSize(const base::FilePath& filename); + // Overridden from SelectFileDialog::Listener: void FileSelected(const base::FilePath& path, int index,
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc index b63e1ec26..5f8c4f8 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -88,8 +88,6 @@ #include "third_party/icu/source/i18n/unicode/ulocdata.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/printing/printers_manager.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc b/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc index 22867769..303cd17 100644 --- a/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc +++ b/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc
@@ -18,8 +18,8 @@ #include "chrome/browser/chromeos/printing/cups_print_job_manager_factory.h" #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" #include "chrome/browser/chromeos/printing/printer_configurer.h" -#include "chrome/browser/chromeos/printing/printers_manager.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/print_preview/printer_capabilities.h" #include "chrome/common/chrome_switches.h" @@ -74,7 +74,8 @@ class PrinterBackendProxyChromeos : public PrinterBackendProxy { public: explicit PrinterBackendProxyChromeos(Profile* profile) - : prefs_(chromeos::PrintersManagerFactory::GetForBrowserContext(profile)), + : prefs_(chromeos::SyncedPrintersManagerFactory::GetForBrowserContext( + profile)), printer_configurer_(chromeos::PrinterConfigurer::Create(profile)), weak_factory_(this) { // Construct the CupsPrintJobManager to listen for printing events. @@ -94,7 +95,7 @@ }; void EnumeratePrinters(const EnumeratePrintersCallback& cb) override { - // PrintersManager is not thread safe and must be called from the UI + // SyncedPrintersManager is not thread safe and must be called from the UI // thread. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -183,7 +184,7 @@ cb.Run(nullptr); } - chromeos::PrintersManager* prefs_; + chromeos::SyncedPrintersManager* prefs_; scoped_refptr<chromeos::printing::PpdProvider> ppd_provider_; std::unique_ptr<chromeos::PrinterConfigurer> printer_configurer_; base::WeakPtrFactory<PrinterBackendProxyChromeos> weak_factory_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc index c21e51d..d23a203 100644 --- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -114,6 +114,10 @@ web_ui()->RegisterMessageCallback( "selectImage", base::Bind(&ChangePictureHandler::HandleSelectImage, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "requestSelectedImage", + base::Bind(&ChangePictureHandler::HandleRequestSelectedImage, + base::Unretained(this))); } void ChangePictureHandler::OnJavascriptAllowed() { @@ -322,6 +326,11 @@ ImageDecoder::Cancel(this); } +void ChangePictureHandler::HandleRequestSelectedImage( + const base::ListValue* args) { + SendSelectedImage(); +} + void ChangePictureHandler::FileSelected(const base::FilePath& path, int index, void* params) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h index a2132822..399cf3e 100644 --- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
@@ -87,6 +87,9 @@ // Selects one of the available images as user's. void HandleSelectImage(const base::ListValue* args); + // Requests the currently selected image. + void HandleRequestSelectedImage(const base::ListValue* args); + // SelectFileDialog::Delegate implementation. void FileSelected(const base::FilePath& path, int index,
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc index dcfc342..11bd680 100644 --- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -21,7 +21,7 @@ #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" #include "chrome/browser/chromeos/printing/printer_configurer.h" #include "chrome/browser/chromeos/printing/printer_info.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" #include "chrome/browser/chromeos/printing/usb_printer_detector.h" #include "chrome/browser/chromeos/printing/usb_printer_detector_factory.h" #include "chrome/browser/download/download_prefs.h" @@ -186,7 +186,8 @@ CHECK(args->GetString(0, &callback_id)); std::vector<std::unique_ptr<Printer>> printers = - PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinters(); + SyncedPrintersManagerFactory::GetForBrowserContext(profile_) + ->GetPrinters(); auto printers_list = base::MakeUnique<base::ListValue>(); for (const std::unique_ptr<Printer>& printer : printers) { @@ -208,7 +209,7 @@ std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id); printer->set_display_name(printer_name); - PrintersManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter( + SyncedPrintersManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter( std::move(printer)); } @@ -217,8 +218,8 @@ std::string printer_name; CHECK(args->GetString(0, &printer_id)); CHECK(args->GetString(1, &printer_name)); - PrintersManager* prefs = - PrintersManagerFactory::GetForBrowserContext(profile_); + SyncedPrintersManager* prefs = + SyncedPrintersManagerFactory::GetForBrowserContext(profile_); auto printer = prefs->GetPrinter(printer_id); if (!printer) return; @@ -419,7 +420,8 @@ case PrinterSetupResult::kSuccess: { UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterAdded", printer->GetProtocol(), Printer::kProtocolMax); - auto* manager = PrintersManagerFactory::GetForBrowserContext(profile_); + auto* manager = + SyncedPrintersManagerFactory::GetForBrowserContext(profile_); manager->PrinterInstalled(*printer); manager->RegisterPrinter(std::move(printer)); break; @@ -571,8 +573,8 @@ std::unique_ptr<base::ListValue> printers_list = base::MakeUnique<base::ListValue>(); // Filter out already-configured printers as we go. - PrintersManager* printers_manager = - PrintersManagerFactory::GetForBrowserContext(profile_); + SyncedPrintersManager* printers_manager = + SyncedPrintersManagerFactory::GetForBrowserContext(profile_); if (printers_manager != nullptr) { for (const auto& printer : printers) { if (printers_manager->GetPrinter(printer.id()).get() == nullptr) { @@ -581,7 +583,7 @@ } } else { LOG(WARNING) << "Failing to get available printers because no " - "PrintersManager exists."; + "SyncedPrintersManager exists."; } FireWebUIListener("on-printer-discovered", *printers_list); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc index dbd70059..1fea2b8 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/values.h" -#include "chrome/browser/profiles/profile.h" #include "chromeos/chromeos_switches.h" #include "content/public/browser/web_ui.h" #include "ui/events/devices/input_device_manager.h" @@ -31,12 +30,17 @@ namespace chromeos { namespace settings { -KeyboardHandler::KeyboardHandler(content::WebUI* webui) - : profile_(Profile::FromWebUI(webui)), observer_(this) {} +const char KeyboardHandler::kShowKeysChangedName[] = "show-keys-changed"; -KeyboardHandler::~KeyboardHandler() { +void KeyboardHandler::TestAPI::Initialize() { + base::ListValue args; + handler_->HandleInitialize(&args); } +KeyboardHandler::KeyboardHandler() : observer_(this) {} + +KeyboardHandler::~KeyboardHandler() = default; + void KeyboardHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( "initializeKeyboardSettings", @@ -71,11 +75,16 @@ } void KeyboardHandler::UpdateShowKeys() { - const base::Value has_caps_lock(HasExternalKeyboard()); + // kHasChromeOSKeyboard will be unset on Chromebooks that have standalone Caps + // Lock keys. + const base::Value has_caps_lock( + HasExternalKeyboard() || + !base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kHasChromeOSKeyboard)); const base::Value has_diamond_key( base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kHasChromeOSDiamondKey)); - FireWebUIListener("show-keys-changed", has_caps_lock, has_diamond_key); + FireWebUIListener(kShowKeysChangedName, has_caps_lock, has_diamond_key); } } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h index 7ac9d44..d1afe730 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h
@@ -14,16 +14,10 @@ class ListValue; } -namespace content { -class WebUI; -} - namespace ui { class InputDeviceManager; } -class Profile; - namespace chromeos { namespace settings { @@ -32,7 +26,24 @@ : public ::settings::SettingsPageUIHandler, public ui::InputDeviceEventObserver { public: - explicit KeyboardHandler(content::WebUI* webui); + // Name of the message sent to WebUI when the keys that should be shown + // change. + static const char kShowKeysChangedName[]; + + // Class used by tests to interact with KeyboardHandler internals. + class TestAPI { + public: + explicit TestAPI(KeyboardHandler* handler) { handler_ = handler; } + + // Simulates a request from WebUI to initialize the page. + void Initialize(); + + private: + KeyboardHandler* handler_; // Not owned. + DISALLOW_COPY_AND_ASSIGN(TestAPI); + }; + + KeyboardHandler(); ~KeyboardHandler() override; // SettingsPageUIHandler implementation. @@ -54,8 +65,6 @@ // system status. void UpdateShowKeys(); - Profile* profile_; // Weak pointer. - ScopedObserver<ui::InputDeviceManager, KeyboardHandler> observer_; DISALLOW_COPY_AND_ASSIGN(KeyboardHandler);
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc new file mode 100644 index 0000000..7d83749 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc
@@ -0,0 +1,151 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h" + +#include <memory> + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/observer_list.h" +#include "chromeos/chromeos_switches.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/devices/input_device.h" +#include "ui/events/test/device_data_manager_test_api.h" + +namespace chromeos { +namespace settings { + +namespace { + +class TestKeyboardHandler : public KeyboardHandler { + public: + // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it. + using KeyboardHandler::set_web_ui; +}; + +} // namespace + +class KeyboardHandlerTest : public testing::Test { + public: + KeyboardHandlerTest() : handler_test_api_(&handler_) { + handler_.set_web_ui(&web_ui_); + handler_.RegisterMessages(); + handler_.AllowJavascriptForTesting(); + + // Make sure that we start out without any keyboards reported. + device_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>()); + } + + protected: + // Updates out-params from the last message sent to WebUI about a change to + // which keys should be shown. False is returned if the message was invalid or + // not found. + bool GetLastShowKeysChangedMessage(bool* has_caps_lock_out, + bool* has_diamond_key_out) + WARN_UNUSED_RESULT { + for (auto it = web_ui_.call_data().rbegin(); + it != web_ui_.call_data().rend(); ++it) { + const content::TestWebUI::CallData* data = it->get(); + std::string name; + if (data->function_name() != "cr.webUIListenerCallback" || + !data->arg1()->GetAsString(&name) || + name != KeyboardHandler::kShowKeysChangedName) { + continue; + } + return data->arg2()->GetAsBoolean(has_caps_lock_out) && + data->arg3()->GetAsBoolean(has_diamond_key_out); + } + return false; + } + + // Returns true if the last keys-changed message reported that a Caps Lock key + // is present and false otherwise. A failure is added if a message wasn't + // found. + bool HasCapsLock() { + bool has_caps_lock = false, has_diamond_key = false; + if (!GetLastShowKeysChangedMessage(&has_caps_lock, &has_diamond_key)) { + ADD_FAILURE() << "Didn't get " << KeyboardHandler::kShowKeysChangedName; + return false; + } + return has_caps_lock; + } + + // Returns true if the last keys-changed message reported that a "diamond" key + // is present and false otherwise. A failure is added if a message wasn't + // found. + bool HasDiamondKey() { + bool has_caps_lock = false, has_diamond_key = false; + if (!GetLastShowKeysChangedMessage(&has_caps_lock, &has_diamond_key)) { + ADD_FAILURE() << "Didn't get " << KeyboardHandler::kShowKeysChangedName; + return false; + } + return has_diamond_key; + } + + ui::test::DeviceDataManagerTestAPI device_test_api_; + content::TestWebUI web_ui_; + TestKeyboardHandler handler_; + KeyboardHandler::TestAPI handler_test_api_; + + private: + DISALLOW_COPY_AND_ASSIGN(KeyboardHandlerTest); +}; + +TEST_F(KeyboardHandlerTest, DefaultKeys) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kHasChromeOSKeyboard); + handler_test_api_.Initialize(); + EXPECT_FALSE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); +} + +TEST_F(KeyboardHandlerTest, NonChromeOSKeyboard) { + // If kHasChromeOSKeyboard isn't passed, we should assume there's a Caps Lock + // key. + handler_test_api_.Initialize(); + EXPECT_TRUE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); +} + +TEST_F(KeyboardHandlerTest, ExternalKeyboard) { + // An internal keyboard shouldn't change the defaults. + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kHasChromeOSKeyboard); + device_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{ + {1, ui::INPUT_DEVICE_INTERNAL, "internal keyboard"}}); + handler_test_api_.Initialize(); + EXPECT_FALSE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); + + // Simulate an external keyboard being connected. We should assume there's a + // Caps Lock key now. + device_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{ + {1, ui::INPUT_DEVICE_EXTERNAL, "external keyboard"}}); + device_test_api_.NotifyObserversKeyboardDeviceConfigurationChanged(); + EXPECT_TRUE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); + + // Disconnect the external keyboard and check that the key goes away. + device_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>()); + device_test_api_.NotifyObserversKeyboardDeviceConfigurationChanged(); + EXPECT_FALSE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); +} + +TEST_F(KeyboardHandlerTest, DiamondKey) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kHasChromeOSKeyboard); + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kHasChromeOSDiamondKey); + handler_test_api_.Initialize(); + EXPECT_FALSE(HasCapsLock()); + EXPECT_TRUE(HasDiamondKey()); +} + +} // namespace settings +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_power_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/device_power_handler_unittest.cc index acac9ab..c5a0b4c1 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_power_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_power_handler_unittest.cc
@@ -70,7 +70,6 @@ const content::TestWebUI::CallData* data = it->get(); std::string name; const base::DictionaryValue* dict = nullptr; - data->arg1()->GetAsString(&name); if (data->function_name() != "cr.webUIListenerCallback" || !data->arg1()->GetAsString(&name) || name != PowerHandler::kPowerManagementSettingsChangedName) {
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index e23f6f87..d0e730c 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -1505,10 +1505,10 @@ {"printingManageCloudPrintDevices", IDS_SETTINGS_PRINTING_MANAGE_CLOUD_PRINT_DEVICES}, {"cloudPrintersTitle", IDS_SETTINGS_PRINTING_CLOUD_PRINTERS}, - {"cloudPrintersTitleDescription", - IDS_SETTINGS_PRINTING_CLOUD_PRINTERS_DESCRIPTION}, #if defined(OS_CHROMEOS) {"cupsPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTERS}, + {"cupsPrintersLearnMoreLabel", + IDS_SETTINGS_PRINTING_CUPS_PRINTERS_LEARN_MORE_LABEL}, {"addCupsPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER}, {"cupsPrinterDetails", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_DETAILS}, {"removePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_REMOVE}, @@ -1577,6 +1577,8 @@ html_source->AddBoolean("showCupsPrintingFeatures", !base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kDisableNativeCups)); + html_source->AddString("printingCUPSPrintLearnMoreUrl", + chrome::kCupsPrintLearnMoreURL); #endif }
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 1e586a1e..b29198f5 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -165,7 +165,7 @@ AddSettingsPageUIHandler( base::MakeUnique<chromeos::settings::FingerprintHandler>(profile)); AddSettingsPageUIHandler( - base::MakeUnique<chromeos::settings::KeyboardHandler>(web_ui)); + base::MakeUnique<chromeos::settings::KeyboardHandler>()); AddSettingsPageUIHandler( base::MakeUnique<chromeos::settings::PointerHandler>()); AddSettingsPageUIHandler(
diff --git a/chrome/browser/ui/webui/system_info_ui.cc b/chrome/browser/ui/webui/system_info_ui.cc index ac2190e..e478be7 100644 --- a/chrome/browser/ui/webui/system_info_ui.cc +++ b/chrome/browser/ui/webui/system_info_ui.cc
@@ -23,12 +23,12 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/feedback/system_logs/about_system_logs_fetcher.h" -#include "chrome/browser/feedback/system_logs/system_logs_fetcher.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" +#include "components/feedback/system_logs/system_logs_fetcher.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h"
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc index c3c57bf..4a382e2 100644 --- a/chrome/common/crash_keys.cc +++ b/chrome/common/crash_keys.cc
@@ -231,6 +231,9 @@ // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. // TODO(sunnyps): Remove after fixing https://crbug.com/622080 {kBeginMainFrameHangCompositorState, crash_keys::kSmallSize}, + + // TODO(asvitkine): Remove after fixing https://crbug.com/736675 + {"bad_histogram", kMediumSize}, }; // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 46c07aa..950f544e 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -139,6 +139,8 @@ // TODO(xdai): Change it to chrome://settings/cupsPrinters after M56 since MD // settings is going to launch in Chrome OS in M57. const char kChromeUIMdCupsSettingsURL[] = "chrome://md-settings/cupsPrinters"; +const char kCupsPrintLearnMoreURL[] = + "https://support.google.com/chromebook?p=chromebook_printing"; #endif // defined(OS_CHROMEOS) #if defined(OS_WIN)
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index 9ba18fdc..ec9a397 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -127,6 +127,7 @@ extern const char kChromeUITermsOemURL[]; extern const char kChromeUIUserImageURL[]; extern const char kChromeUIMdCupsSettingsURL[]; +extern const char kCupsPrintLearnMoreURL[]; #endif // defined(OS_CHROMEOS) #if defined(OS_WIN)
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index efbc55d8..8f0a534 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3623,6 +3623,7 @@ "../browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc", "../browser/resource_coordinator/background_tab_navigation_throttle_unittest.cc", "../browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc", + "../browser/resource_coordinator/tab_manager_stats_collector_unittest.cc", "../browser/resource_coordinator/tab_manager_unittest.cc", "../browser/resource_coordinator/tab_manager_web_contents_data_unittest.cc",
diff --git a/chrome/test/data/extensions/lock_screen_apps/data_provider/background.js b/chrome/test/data/extensions/lock_screen_apps/data_provider/background.js new file mode 100644 index 0000000..1bd759eb --- /dev/null +++ b/chrome/test/data/extensions/lock_screen_apps/data_provider/background.js
@@ -0,0 +1,91 @@ +// 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. + +var callbackPass = chrome.test.callbackPass; +var callbackFail = chrome.test.callbackFail; + +chrome.app.runtime.onLaunched.addListener(function(data) { + chrome.test.runTests([ + function launchTest() { + chrome.test.assertTrue(!!data); + chrome.test.assertTrue(!!data.actionData); + chrome.test.assertEq('new_note', data.actionData.actionType); + chrome.test.assertTrue(data.actionData.isLockScreenAction); + + chrome.app.window.create('test.html', { + lockScreenAction: 'new_note' + }, chrome.test.callbackPass(function(createdWindow) { + chrome.test.listenOnce(createdWindow.onClosed, + chrome.test.callbackPass()); + })); + } + ]); +}); + +// Event expected to be fired in regular user context when user session starts, +// or gets unlocked, in case there are data items in lock screen storage. +// The app will run set of tests verifying that the state of the app's lock +// storage matches to the state set in the app's test.html window (i.e. in tests +// run when the app is launched to handle new lock screen note action). +chrome.lockScreen.data.onDataItemsAvailable.addListener(function() { + var itemsInfo = []; + + var sortItems = function(infoList) { + return itemsInfo.sort(function(lhs, rhs) { + if (lhs.content == rhs.content) + return 0; + return lhs.content < rhs.content ? -1 : 1; + }); + }; + + chrome.test.runTests([ + function createNotAvailable() { + chrome.test.assertFalse(!!chrome.lockScreen.data.create); + chrome.test.succeed(); + }, + + function getAll() { + chrome.lockScreen.data.getAll(callbackPass(function(items) { + chrome.test.assertEq(3, items.length); + + items.forEach(function(item) { + var itemInfo = {id: item.id}; + chrome.lockScreen.data.getContent(item.id, callbackPass(function( + content) { + var decoder = new TextDecoder(); + itemInfo.content = decoder.decode(content); + itemsInfo.push(itemInfo); + })); + }); + })); + }, + + function testItemInfo() { + chrome.test.assertEq([{ + content: '' + }, { + content: '1 - Created by the app.' + }, { + content: '2 - Created and updated by the app - final.' + }], sortItems(itemsInfo).map(function(item) { + return { + content: item.content + } + })); + chrome.test.succeed(); + }, + + function deleteItem() { + var sortedItems = sortItems(itemsInfo); + // Sanity check for test preconditions. + chrome.test.assertEq(3, sortedItems.length); + + chrome.lockScreen.data.delete(itemsInfo[0].id, callbackPass(function() { + chrome.lockScreen.data.getAll(callbackPass(function(info) { + chrome.test.assertEq(2, info.length); + })); + })); + } + ]); +});
diff --git a/chrome/test/data/extensions/lock_screen_apps/data_provider/manifest.json b/chrome/test/data/extensions/lock_screen_apps/data_provider/manifest.json new file mode 100644 index 0000000..9a8fd29 --- /dev/null +++ b/chrome/test/data/extensions/lock_screen_apps/data_provider/manifest.json
@@ -0,0 +1,16 @@ +{ + "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA02u2EolNQq2mp/jmpE6tlctinxHNThc5FIsleGtPWsyCOxndLPlNqUKnXpAzllyUahwqtP+hYeYStiq3+0pcSEz4i9dGBF/DRKZ09LvKiDQB26Xvb8+IDxlqwe4Z/z9yQLB7xyg977z5Xi09DMVEtUfyuJTvtWQMcTpwyh5dEhK/F8R/lPrzmMU9bvidzRtruLuXd/DyQOPpNqSQTbN3Tg3dD4xDO54N+4ld8Pot6Nob0P0Yn/wm4c6Ct+5qwESaMP3C3WIIRDJ41rU4RgRSioxEYSdTtyrnO2qSK6KVKEFDmRp5hMxOn0r7C3CsdwMVMS3FXctjNia+1M3/2AMn/wIDAQAB", + "name": "Test lock screen app", + "version": "0.1", + "manifest_version": 2, + "permissions": ["lockScreen"], + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "action_handlers": [{ + "action": "new_note", + "enabled_on_lock_screen": true + }] +}
diff --git a/chrome/test/data/extensions/lock_screen_apps/data_provider/test.html b/chrome/test/data/extensions/lock_screen_apps/data_provider/test.html new file mode 100644 index 0000000..682e3d21 --- /dev/null +++ b/chrome/test/data/extensions/lock_screen_apps/data_provider/test.html
@@ -0,0 +1,5 @@ +<html> +<head> +<script src="test.js"> </script> +</head> +</html>
diff --git a/chrome/test/data/extensions/lock_screen_apps/data_provider/test.js b/chrome/test/data/extensions/lock_screen_apps/data_provider/test.js new file mode 100644 index 0000000..2c07aba --- /dev/null +++ b/chrome/test/data/extensions/lock_screen_apps/data_provider/test.js
@@ -0,0 +1,99 @@ +// 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. + +var callbackPass = chrome.test.callbackPass; +var callbackFail = chrome.test.callbackFail; + +var createdIds = []; +var deletedIds = []; + +chrome.test.runTests([ + function createNote() { + chrome.lockScreen.data.create(callbackPass(function(item) { + chrome.test.assertEq(-1, createdIds.indexOf(item.id)); + createdIds.push(item.id); + + var encoder = new TextEncoder(); + var text = '1 - Created by the app.'; + chrome.lockScreen.data.setContent( + item.id, encoder.encode(text).buffer, callbackPass()); + })); + }, + + function createAndResetNoteContent() { + chrome.lockScreen.data.create(callbackPass(function(item) { + chrome.test.assertEq(-1, createdIds.indexOf(item.id)); + createdIds.push(item.id); + + var encoder = new TextEncoder(); + var text = '2 - Created and updated by the app - initial.'; + chrome.lockScreen.data.setContent( + item.id, encoder.encode(text).buffer, callbackPass(function() { + var text = '2 - Created and updated by the app - final.'; + chrome.lockScreen.data.setContent( + item.id, encoder.encode(text).buffer, callbackPass()); + })); + })); + }, + + function createAndDeleteNote() { + chrome.lockScreen.data.create(callbackPass(function(item) { + chrome.test.assertEq(-1, createdIds.indexOf(item.id)); + createdIds.push(item.id); + deletedIds.push(item.id); + + var encoder = new TextEncoder(); + var text = '3 - Item deleted by the app'; + chrome.lockScreen.data.setContent( + item.id, encoder.encode(text).buffer, callbackPass(function() { + chrome.lockScreen.data.delete(item.id, callbackPass(function() { + chrome.lockScreen.data.setContent( + item.id, encoder.encode('text').buffer, + callbackFail('Not found')); + })); + })); + })); + }, + + function createEmptyNote() { + chrome.lockScreen.data.create(callbackPass(function(item) { + chrome.test.assertEq(-1, createdIds.indexOf(item.id)); + createdIds.push(item.id); + })); + }, + + function getAll() { + var sortItems = function(infoList) { + return infoList.sort(function(lhs, rhs) { + return lhs.id < rhs.id ? -1 : 1; + }); + }; + + chrome.lockScreen.data.getAll(callbackPass(function(items) { + chrome.test.assertEq( + sortItems(createdIds.filter(function(id) { + return deletedIds.indexOf(id) < 0; + }).map(function(id) { + return {id: id}; + })), + sortItems(items)); + })); + }, + + function reportReadyToClose() { + // Notify the test runner the app window is ready to be closed - if the test + // runner replies with 'close', close the current app window. Otherwise, the + // test runner will close the window itself. + // NOTE: Reporting the test success should not wait for this - the test + // runner should be notified of test run success before responding to + // this message to avoid test done message being disregarded due to app + // window clusure. + chrome.test.sendMessage('readyToClose', function(response) { + if (response === 'close') + chrome.app.window.current().close(); + }); + + chrome.test.succeed(); + }, +]);
diff --git a/chrome/test/data/webui/settings/cups_printer_page_tests.js b/chrome/test/data/webui/settings/cups_printer_page_tests.js index aa5d175..48cc53b4 100644 --- a/chrome/test/data/webui/settings/cups_printer_page_tests.js +++ b/chrome/test/data/webui/settings/cups_printer_page_tests.js
@@ -107,10 +107,19 @@ * to add a printer. */ test('DiscoveryShowing', function() { - assertFalse(!!dialog.$$('add-printer-manufacturer-model-dialog')); - assertFalse(!!dialog.$$('add-printer-configuring-dialog')); - assertFalse(!!dialog.$$('add-printer-manually-dialog')); - assertTrue(!!dialog.$$('add-printer-discovery-dialog')); + return PolymerTest.flushTasks().then(function() { + // Discovery is showing. + assertTrue(dialog.showDiscoveryDialog_); + assertTrue(!!dialog.$$('add-printer-discovery-dialog')); + + // All other components are hidden. + assertFalse(dialog.showManufacturerDialog_); + assertFalse(!!dialog.$$('add-printer-manufacturer-model-dialog')); + assertFalse(dialog.showConfiguringDialog_); + assertFalse(!!dialog.$$('add-printer-configuring-dialog')); + assertFalse(dialog.showManuallyAddDialog_); + assertFalse(!!dialog.$$('add-printer-manually-dialog')); + }); }); /** @@ -137,8 +146,17 @@ return cupsPrintersBrowserProxy. whenCalled('getCupsPrinterManufacturersList'). then(function() { - // TODO(skau): Verify other dialogs are hidden. + return PolymerTest.flushTasks(); + }). + then(function() { + // Showing model selection. + assertFalse(!!dialog.$$('add-printer-configuring-dialog')); assertTrue(!!dialog.$$('add-printer-manufacturer-model-dialog')); + + assertTrue(dialog.showManufacturerDialog_); + assertFalse(dialog.showConfiguringDialog_); + assertFalse(dialog.showManuallyAddDialog_); + assertFalse(dialog.showDiscoveryDialog_); }); });
diff --git a/chrome/test/data/webui/settings/people_page_change_picture_test.js b/chrome/test/data/webui/settings/people_page_change_picture_test.js index 3ffc0ca..de8e9bb 100644 --- a/chrome/test/data/webui/settings/people_page_change_picture_test.js +++ b/chrome/test/data/webui/settings/people_page_change_picture_test.js
@@ -16,6 +16,7 @@ 'selectProfileImage', 'photoTaken', 'chooseFile', + 'requestSelectedImage', ]); }; @@ -76,6 +77,11 @@ chooseFile: function() { this.methodCalled('chooseFile'); }, + + /** @override */ + requestSelectedImage: function() { + this.methodCalled('requestSelectedImage'); + }, }; function registerChangePictureTests() { @@ -187,6 +193,8 @@ }); test('ChangePictureOldImage', function() { + assertFalse(!!changePicture.selectedItem_); + // By default there is no old image and the element is hidden. var oldImage = crPictureList.$.oldImage; assertTrue(!!oldImage); @@ -195,15 +203,20 @@ cr.webUIListenerCallback('old-image-changed', 'fake-old-image.jpg'); Polymer.dom.flush(); - // Expect the old image to be selected once an old image is sent via - // the native interface. - expectEquals(CrPicture.SelectionTypes.OLD, - changePicture.selectedItem_.dataset.type); - expectFalse(oldImage.hidden); - expectFalse(crPicturePane.cameraActive_); - var discard = crPicturePane.$$('#discard'); - assertTrue(!!discard); - expectFalse(discard.hidden); + return new Promise(function(resolve) { + changePicture.async(resolve); + }).then(function() { + assertTrue(!!changePicture.selectedItem_); + // Expect the old image to be selected once an old image is sent via + // the native interface. + expectEquals(CrPicture.SelectionTypes.OLD, + changePicture.selectedItem_.dataset.type); + expectFalse(oldImage.hidden); + expectFalse(crPicturePane.cameraActive_); + var discard = crPicturePane.$$('#discard'); + assertTrue(!!discard); + expectFalse(discard.hidden); + }); }); test('ChangePictureSelectFirstDefaultImage', function() {
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index f7e18dc..f384f5f 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -374,6 +374,13 @@ // for any type of user. Should be used only for testing. const char kForceHappinessTrackingSystem[] = "force-happiness-tracking-system"; +// If set, the system is a Chromebook with a "standard Chrome OS keyboard", +// which generally means one with a Search key in the standard Caps Lock +// location above the Left Shift key. It should be unset for Chromebooks with +// both Search and Caps Lock keys (e.g. stout) and for devices like Chromeboxes +// that only use external keyboards. +const char kHasChromeOSKeyboard[] = "has-chromeos-keyboard"; + // If true, the Chromebook has a keyboard with a diamond key. const char kHasChromeOSDiamondKey[] = "has-chromeos-diamond-key";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index be722daf..d837ac860 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -114,6 +114,7 @@ CHROMEOS_EXPORT extern const char kGuestWallpaperSmall[]; CHROMEOS_EXPORT extern const char kForceHappinessTrackingSystem[]; CHROMEOS_EXPORT extern const char kHasChromeOSDiamondKey[]; +CHROMEOS_EXPORT extern const char kHasChromeOSKeyboard[]; CHROMEOS_EXPORT extern const char kHomedir[]; CHROMEOS_EXPORT extern const char kHostPairingOobe[]; CHROMEOS_EXPORT extern const char kIgnoreUserProfileMappingForTests[];
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn index 6fa2b22..343470f 100644 --- a/chromeos/components/tether/BUILD.gn +++ b/chromeos/components/tether/BUILD.gn
@@ -22,6 +22,8 @@ "ble_scanner.h", "connect_tethering_operation.cc", "connect_tethering_operation.h", + "crash_recovery_manager.cc", + "crash_recovery_manager.h", "device_id_tether_network_guid_map.cc", "device_id_tether_network_guid_map.h", "device_status_util.cc", @@ -156,6 +158,7 @@ "ble_connection_manager_unittest.cc", "ble_scanner_unittest.cc", "connect_tethering_operation_unittest.cc", + "crash_recovery_manager_unittest.cc", "device_status_util_unittest.cc", "disconnect_tethering_operation_unittest.cc", "host_connection_metrics_logger_unittest.cc",
diff --git a/chromeos/components/tether/active_host.h b/chromeos/components/tether/active_host.h index 10b24cd7..91a04e4 100644 --- a/chromeos/components/tether/active_host.h +++ b/chromeos/components/tether/active_host.h
@@ -140,6 +140,8 @@ const std::string& new_wifi_network_guid); private: + friend class CrashRecoveryManager; + void SetActiveHost(ActiveHostStatus active_host_status, const std::string& active_host_device_id, const std::string& tether_network_guid,
diff --git a/chromeos/components/tether/crash_recovery_manager.cc b/chromeos/components/tether/crash_recovery_manager.cc new file mode 100644 index 0000000..59b0b34 --- /dev/null +++ b/chromeos/components/tether/crash_recovery_manager.cc
@@ -0,0 +1,151 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/tether/crash_recovery_manager.h" + +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/components/tether/host_scan_cache.h" +#include "chromeos/network/network_state.h" +#include "chromeos/network/network_state_handler.h" +#include "components/cryptauth/remote_device.h" +#include "components/proximity_auth/logging/logging.h" + +namespace chromeos { + +namespace tether { + +CrashRecoveryManager::CrashRecoveryManager( + NetworkStateHandler* network_state_handler, + ActiveHost* active_host, + HostScanCache* host_scan_cache) + : network_state_handler_(network_state_handler), + active_host_(active_host), + host_scan_cache_(host_scan_cache), + weak_ptr_factory_(this) {} + +CrashRecoveryManager::~CrashRecoveryManager() {} + +void CrashRecoveryManager::RestorePreCrashStateIfNecessary( + const base::Closure& on_restoration_finished) { + ActiveHost::ActiveHostStatus status = active_host_->GetActiveHostStatus(); + std::string active_host_device_id = active_host_->GetActiveHostDeviceId(); + std::string wifi_network_guid = active_host_->GetWifiNetworkGuid(); + std::string tether_network_guid = active_host_->GetTetherNetworkGuid(); + + if (status == ActiveHost::ActiveHostStatus::DISCONNECTED) { + // There was no active Tether session, so either the last Tether component + // shutdown occurred normally (i.e., without a crash), or it occurred due + // to a crash and there was no active host at the time of the crash. + on_restoration_finished.Run(); + return; + } + + if (status == ActiveHost::ActiveHostStatus::CONNECTING) { + // If a connection attempt was in progress when the crash occurred, abandon + // the connection attempt. Set ActiveHost back to DISCONNECTED; the user can + // attempt another connection if desired. + // TODO(khorimoto): Explore whether we should attempt to restore an + // in-progress connection attempt. This is a low-priority edge case which is + // difficult to solve. + PA_LOG(WARNING) << "Browser crashed while Tether connection attempt was in " + << "progress. Abandoning connection attempt."; + active_host_->SetActiveHostDisconnected(); + on_restoration_finished.Run(); + return; + } + + RestoreConnectedState(on_restoration_finished, active_host_device_id, + tether_network_guid, wifi_network_guid); +} + +void CrashRecoveryManager::RestoreConnectedState( + const base::Closure& on_restoration_finished, + const std::string& active_host_device_id, + const std::string& tether_network_guid, + const std::string& wifi_network_guid) { + // Since the host was connected, both a Wi-Fi and Tether network GUID are + // expected to be present. + DCHECK(!wifi_network_guid.empty() && !tether_network_guid.empty()); + + if (!host_scan_cache_->ExistsInCache(tether_network_guid)) { + // If a crash occurred, HostScanCache is expected to have restored its state + // via its persistent scan results. If that did not happen correctly, there + // is no way to restore the active host, so abandon the connection. Note + // that this is not an expected error condition. + PA_LOG(ERROR) + << "Browser crashed while a Tether connection was active, " + << "but the scan result for the active host was lost. Setting " + << "the active host to DISCONNECTED."; + active_host_->SetActiveHostDisconnected(); + on_restoration_finished.Run(); + return; + } + + // Since the associated scan result exists in the cache, it is expected to be + // present in the network stack. + const NetworkState* tether_state = + network_state_handler_->GetNetworkStateFromGuid(tether_network_guid); + DCHECK(tether_state); + + const NetworkState* wifi_state = + network_state_handler_->GetNetworkStateFromGuid(wifi_network_guid); + if (!wifi_state || !wifi_state->IsConnectedState()) { + // If the Wi-Fi network corresponding to the Tether hotspot is not present + // or is no longer connected, then this device is no longer truly connected + // to the active host. + PA_LOG(ERROR) << "Browser crashed while a Tether connection was active, " + << "but underlying Wi-Fi network corresponding to the Tether " + << "connection is no longer present. Setting the active host " + << "to DISCONNECTED."; + active_host_->SetActiveHostDisconnected(); + on_restoration_finished.Run(); + return; + } + + // Because the NetworkState object representing the Wi-Fi network was lost + // during the crash, the association between it and the Tether NetworkState + // has been broken. Restore it now. + DCHECK(wifi_state->tether_guid().empty()); + network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork( + tether_network_guid, wifi_network_guid); + + active_host_->GetActiveHost( + base::Bind(&CrashRecoveryManager::OnActiveHostFetched, + weak_ptr_factory_.GetWeakPtr(), on_restoration_finished)); +} + +void CrashRecoveryManager::OnActiveHostFetched( + const base::Closure& on_restoration_finished, + ActiveHost::ActiveHostStatus active_host_status, + std::shared_ptr<cryptauth::RemoteDevice> active_host, + const std::string& tether_network_guid, + const std::string& wifi_network_guid) { + DCHECK(ActiveHost::ActiveHostStatus::CONNECTED == active_host_status); + DCHECK(active_host_); + + // Even though the active host has not actually changed, fire an active host + // changed update so that classes listening on ActiveHost (e.g., + // ActiveHostNetworkStateUpdater and KeepAliveScheduler) will be notified + // that there is an active connection. + // + // Note: SendActiveHostChangedUpdate() is a protected function of ActiveHost + // which is only invoked here because CrashRecoveryManager is a friend class. + // It is invoked directly here because we are sending out a "fake" change + // event which has equal old and new values. + active_host_->SendActiveHostChangedUpdate( + ActiveHost::ActiveHostStatus::CONNECTED /* old_status */, + active_host->GetDeviceId() /* old_active_host_id */, + tether_network_guid /* old_tether_network_guid */, + wifi_network_guid /* old_wifi_network_guid */, + ActiveHost::ActiveHostStatus::CONNECTED /* new_status */, + active_host /* new_active_host */, + tether_network_guid /* new_tether_network_guid */, + wifi_network_guid /* new_wifi_network_guid */); + on_restoration_finished.Run(); +} + +} // namespace tether + +} // namespace chromeos
diff --git a/chromeos/components/tether/crash_recovery_manager.h b/chromeos/components/tether/crash_recovery_manager.h new file mode 100644 index 0000000..998a023 --- /dev/null +++ b/chromeos/components/tether/crash_recovery_manager.h
@@ -0,0 +1,64 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_TETHER_CRASH_RECOVERY_MANAGER_H_ +#define CHROMEOS_COMPONENTS_TETHER_CRASH_RECOVERY_MANAGER_H_ + +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "chromeos/components/tether/active_host.h" + +namespace chromeos { + +class NetworkStateHandler; + +namespace tether { + +class HostScanCache; + +// Restores Tether state after a browser crash. +class CrashRecoveryManager { + public: + CrashRecoveryManager(NetworkStateHandler* network_state_handler, + ActiveHost* active_host, + HostScanCache* host_scan_cache); + virtual ~CrashRecoveryManager(); + + // Restores state which was lost by a browser crash. If a crash did not occur + // the last time that the Tether component was active, this function is a + // no-op. If there was an active Tether connection and the browser crashed, + // this function restores the Tether connection. + // + // This function should only be called during the initialization of the Tether + // component. + void RestorePreCrashStateIfNecessary( + const base::Closure& on_restoration_finished); + + private: + void RestoreConnectedState(const base::Closure& on_restoration_finished, + const std::string& active_host_device_id, + const std::string& tether_network_guid, + const std::string& wifi_network_guid); + void OnActiveHostFetched(const base::Closure& on_restoration_finished, + ActiveHost::ActiveHostStatus active_host_status, + std::shared_ptr<cryptauth::RemoteDevice> active_host, + const std::string& tether_network_guid, + const std::string& wifi_network_guid); + + NetworkStateHandler* network_state_handler_; + ActiveHost* active_host_; + HostScanCache* host_scan_cache_; + + base::WeakPtrFactory<CrashRecoveryManager> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CrashRecoveryManager); +}; + +} // namespace tether + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_TETHER_CRASH_RECOVERY_MANAGER_H_
diff --git a/chromeos/components/tether/crash_recovery_manager_unittest.cc b/chromeos/components/tether/crash_recovery_manager_unittest.cc new file mode 100644 index 0000000..e53e7caf --- /dev/null +++ b/chromeos/components/tether/crash_recovery_manager_unittest.cc
@@ -0,0 +1,191 @@ +// 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 "chromeos/components/tether/crash_recovery_manager.h" + +#include <memory> +#include <sstream> + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/test/scoped_task_environment.h" +#include "chromeos/components/tether/device_id_tether_network_guid_map.h" +#include "chromeos/components/tether/fake_active_host.h" +#include "chromeos/components/tether/fake_host_scan_cache.h" +#include "chromeos/components/tether/host_scan_cache_entry.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/network/network_state_handler.h" +#include "chromeos/network/network_state_test.h" +#include "components/cryptauth/remote_device_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/cros_system_api/dbus/shill/dbus-constants.h" + +namespace chromeos { + +namespace tether { + +namespace { + +constexpr char kWifiNetworkGuid[] = "wifiNetworkGuid"; + +std::string CreateConfigurationJsonString(bool is_connected) { + std::string connection_state = + is_connected ? shill::kStateOnline : shill::kStateIdle; + + std::stringstream ss; + ss << "{" + << " \"GUID\": \"" << kWifiNetworkGuid << "\"," + << " \"Type\": \"" << shill::kTypeWifi << "\"," + << " \"State\": \"" << connection_state << "\"" + << "}"; + return ss.str(); +} + +} // namespace + +class CrashRecoveryManagerTest : public NetworkStateTest { + protected: + CrashRecoveryManagerTest() + : test_device_(cryptauth::GenerateTestRemoteDevices(1u)[0]) {} + ~CrashRecoveryManagerTest() override {} + + void SetUp() override { + DBusThreadManager::Initialize(); + NetworkStateTest::SetUp(); + network_state_handler()->SetTetherTechnologyState( + NetworkStateHandler::TECHNOLOGY_ENABLED); + + is_restoration_finished_ = false; + + fake_active_host_ = base::MakeUnique<FakeActiveHost>(); + fake_host_scan_cache_ = base::MakeUnique<FakeHostScanCache>(); + + crash_recovery_manager_ = base::MakeUnique<CrashRecoveryManager>( + network_state_handler(), fake_active_host_.get(), + fake_host_scan_cache_.get()); + + device_id_tether_network_guid_map_ = + base::MakeUnique<DeviceIdTetherNetworkGuidMap>(); + } + + void TearDown() override { + ShutdownNetworkState(); + NetworkStateTest::TearDown(); + DBusThreadManager::Shutdown(); + } + + std::string GetTetherNetworkGuid() { + return device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( + test_device_.GetDeviceId()); + } + + void SetConnected() { + fake_active_host_->SetActiveHostConnected( + test_device_.GetDeviceId(), GetTetherNetworkGuid(), kWifiNetworkGuid); + } + + void AddScanEntry() { + fake_host_scan_cache_->SetHostScanResult( + *HostScanCacheEntry::Builder() + .SetTetherNetworkGuid(GetTetherNetworkGuid()) + .SetDeviceName("deviceName") + .SetCarrier("carrier") + .SetBatteryPercentage(100) + .SetSignalStrength(100) + .SetSetupRequired(false) + .Build()); + + network_state_handler()->AddTetherNetworkState( + GetTetherNetworkGuid(), "deviceName", "carrier", + 100 /* battery_percentage */, 100 /* signal_strength */, + false /* has_connected_to_host */); + } + + void AddWifiNetwork(bool is_connected) { + ConfigureService(CreateConfigurationJsonString(is_connected)); + } + + void StartRestoration() { + crash_recovery_manager_->RestorePreCrashStateIfNecessary( + base::Bind(&CrashRecoveryManagerTest::OnRestorationFinished, + base::Unretained(this))); + } + + void OnRestorationFinished() { is_restoration_finished_ = true; } + + void VerifyDisconnectedAfterRestoration() { + EXPECT_TRUE(is_restoration_finished_); + EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, + fake_active_host_->GetActiveHostStatus()); + } + + const base::test::ScopedTaskEnvironment scoped_task_environment_; + const cryptauth::RemoteDevice test_device_; + + std::unique_ptr<FakeActiveHost> fake_active_host_; + std::unique_ptr<FakeHostScanCache> fake_host_scan_cache_; + + // TODO(hansberry): Use a fake for this when a real mapping scheme is created. + std::unique_ptr<DeviceIdTetherNetworkGuidMap> + device_id_tether_network_guid_map_; + + bool is_restoration_finished_; + + std::unique_ptr<CrashRecoveryManager> crash_recovery_manager_; + + private: + DISALLOW_COPY_AND_ASSIGN(CrashRecoveryManagerTest); +}; + +TEST_F(CrashRecoveryManagerTest, ActiveHostDisconnected) { + StartRestoration(); + VerifyDisconnectedAfterRestoration(); +} + +TEST_F(CrashRecoveryManagerTest, ActiveHostConnecting) { + fake_active_host_->SetActiveHostConnecting(test_device_.GetDeviceId(), + GetTetherNetworkGuid()); + + StartRestoration(); + VerifyDisconnectedAfterRestoration(); +} + +TEST_F(CrashRecoveryManagerTest, ActiveHostConnected_EntryNotInCache) { + SetConnected(); + + StartRestoration(); + VerifyDisconnectedAfterRestoration(); +} + +TEST_F(CrashRecoveryManagerTest, ActiveHostConnected_WifiNetworkMissing) { + AddScanEntry(); + SetConnected(); + + StartRestoration(); + VerifyDisconnectedAfterRestoration(); +} + +TEST_F(CrashRecoveryManagerTest, ActiveHostConnected_WifiNetworkDisconnected) { + AddScanEntry(); + AddWifiNetwork(false /* is_connected */); + SetConnected(); + + StartRestoration(); + VerifyDisconnectedAfterRestoration(); +} + +TEST_F(CrashRecoveryManagerTest, ActiveHostConnected_RestoreSuccessful) { + AddScanEntry(); + AddWifiNetwork(true /* is_connected */); + SetConnected(); + + StartRestoration(); + EXPECT_TRUE(is_restoration_finished_); + EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTED, + fake_active_host_->GetActiveHostStatus()); +} + +} // namespace tether + +} // namespace chromeos
diff --git a/chromeos/components/tether/initializer.cc b/chromeos/components/tether/initializer.cc index aec888a9..0fd2f85 100644 --- a/chromeos/components/tether/initializer.cc +++ b/chromeos/components/tether/initializer.cc
@@ -8,6 +8,7 @@ #include "chromeos/components/tether/active_host.h" #include "chromeos/components/tether/active_host_network_state_updater.h" #include "chromeos/components/tether/ble_connection_manager.h" +#include "chromeos/components/tether/crash_recovery_manager.h" #include "chromeos/components/tether/device_id_tether_network_guid_map.h" #include "chromeos/components/tether/host_connection_metrics_logger.h" #include "chromeos/components/tether/host_scan_device_prioritizer_impl.h" @@ -248,8 +249,18 @@ network_connection_handler_, tether_connector_.get(), tether_disconnector_.get()); - // Because Initializer is created on each user log in, it's appropriate to - // call this method now. + crash_recovery_manager_ = base::MakeUnique<CrashRecoveryManager>( + network_state_handler_, active_host_.get(), + master_host_scan_cache_.get()); + crash_recovery_manager_->RestorePreCrashStateIfNecessary(base::Bind( + &Initializer::OnPreCrashStateRestored, weak_ptr_factory_.GetWeakPtr())); +} + +void Initializer::OnPreCrashStateRestored() { + // |crash_recovery_manager_| is no longer needed since it has completed. + crash_recovery_manager_.reset(); + + // Start a scan now that the Tether module has started up. host_scan_scheduler_->UserLoggedIn(); }
diff --git a/chromeos/components/tether/initializer.h b/chromeos/components/tether/initializer.h index a62cb00..151611c3 100644 --- a/chromeos/components/tether/initializer.h +++ b/chromeos/components/tether/initializer.h
@@ -37,6 +37,7 @@ class ActiveHost; class ActiveHostNetworkStateUpdater; class BleConnectionManager; +class CrashRecoveryManager; class NetworkConnectionHandlerTetherDelegate; class DeviceIdTetherNetworkGuidMap; class HostScanner; @@ -103,6 +104,7 @@ scoped_refptr<device::BluetoothAdapter> adapter); void OnBluetoothAdapterAdvertisingIntervalError( device::BluetoothAdvertisement::ErrorCode status); + void OnPreCrashStateRestored(); cryptauth::CryptAuthService* cryptauth_service_; std::unique_ptr<NotificationPresenter> notification_presenter_; @@ -145,6 +147,7 @@ network_connection_handler_tether_delegate_; std::unique_ptr<TetherNetworkDisconnectionHandler> tether_network_disconnection_handler_; + std::unique_ptr<CrashRecoveryManager> crash_recovery_manager_; base::WeakPtrFactory<Initializer> weak_ptr_factory_;
diff --git a/chromeos/components/tether/tether_connector.cc b/chromeos/components/tether/tether_connector.cc index fe64790..01faf42 100644 --- a/chromeos/components/tether/tether_connector.cc +++ b/chromeos/components/tether/tether_connector.cc
@@ -60,6 +60,7 @@ PA_LOG(INFO) << "Attempting to connect to network with GUID " << tether_network_guid << "."; + notification_presenter_->RemoveConnectionToHostFailedNotification(); const std::string device_id = device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid( @@ -244,6 +245,13 @@ host_connection_metrics_logger_->RecordConnectionToHostResult( connection_to_host_result); + + if (error_name == NetworkConnectionHandler::kErrorConnectFailed) { + // Only show notification if the error is kErrorConnectFailed. Other error + // names (e.g., kErrorConnectCanceled) are a result of user interaction and + // should not result in any error UI. + notification_presenter_->NotifyConnectionToHostFailed(); + } } void TetherConnector::SetConnectionSucceeded(
diff --git a/chromeos/components/tether/tether_connector_unittest.cc b/chromeos/components/tether/tether_connector_unittest.cc index d4a2513..d95bde0 100644 --- a/chromeos/components/tether/tether_connector_unittest.cc +++ b/chromeos/components/tether/tether_connector_unittest.cc
@@ -287,6 +287,8 @@ fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); + EXPECT_TRUE(fake_notification_presenter_ + ->is_connection_failed_notification_shown()); } std::string GetResultAndReset() { @@ -346,6 +348,8 @@ EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); + EXPECT_TRUE( + fake_notification_presenter_->is_connection_failed_notification_shown()); } TEST_F(TetherConnectorTest, TestCancelWhileOperationActive) { @@ -378,6 +382,8 @@ fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, GetResultAndReset()); + EXPECT_FALSE( + fake_notification_presenter_->is_connection_failed_notification_shown()); } TEST_F(TetherConnectorTest, @@ -429,6 +435,17 @@ CONNECTION_RESULT_FAILURE_TETHERING_TIMED_OUT_FIRST_TIME_SETUP_WAS_REQUIRED); } +TEST_F(TetherConnectorTest, + ConnectionToHostFailedNotificationRemovedWhenConnectionStarts) { + // Start with the "connection to host failed" notification showing. + fake_notification_presenter_->NotifyConnectionToHostFailed(); + + // Starting a connection should result in it being removed. + CallConnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); + EXPECT_FALSE( + fake_notification_presenter_->is_connection_failed_notification_shown()); +} + TEST_F(TetherConnectorTest, TestConnectingToWifiFails) { EXPECT_CALL(*mock_host_connection_metrics_logger_, RecordConnectionToHostResult( @@ -468,6 +485,8 @@ EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); + EXPECT_TRUE( + fake_notification_presenter_->is_connection_failed_notification_shown()); } TEST_F(TetherConnectorTest, TestCancelWhileConnectingToWifi) { @@ -504,6 +523,8 @@ fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, GetResultAndReset()); + EXPECT_FALSE( + fake_notification_presenter_->is_connection_failed_notification_shown()); } TEST_F(TetherConnectorTest, TestSuccessfulConnection) { @@ -553,6 +574,8 @@ EXPECT_EQ(kWifiNetworkGuid, fake_active_host_->GetWifiNetworkGuid()); EXPECT_EQ(kSuccessResult, GetResultAndReset()); + EXPECT_FALSE( + fake_notification_presenter_->is_connection_failed_notification_shown()); } TEST_F(TetherConnectorTest, TestSuccessfulConnection_SetupRequired) { @@ -588,6 +611,8 @@ fake_notification_presenter_->is_setup_required_notification_shown()); EXPECT_EQ(kSuccessResult, GetResultAndReset()); + EXPECT_FALSE( + fake_notification_presenter_->is_connection_failed_notification_shown()); } TEST_F(TetherConnectorTest, @@ -607,6 +632,8 @@ // error. EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, GetResultAndReset()); + EXPECT_FALSE( + fake_notification_presenter_->is_connection_failed_notification_shown()); // Now invoke the callbacks. An operation should have been created for the // device 1, not device 0. @@ -645,6 +672,8 @@ // error. EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, GetResultAndReset()); + EXPECT_FALSE( + fake_notification_presenter_->is_connection_failed_notification_shown()); fake_tether_host_fetcher_->InvokePendingCallbacks(); // Now, the active host should be the second device. @@ -708,6 +737,8 @@ // error. EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, GetResultAndReset()); + EXPECT_FALSE( + fake_notification_presenter_->is_connection_failed_notification_shown()); fake_tether_host_fetcher_->InvokePendingCallbacks(); // Connect successfully to the first Wi-Fi network. Even though a temporary
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc index dd901d8..b74684a 100644 --- a/components/exo/buffer.cc +++ b/components/exo/buffer.cc
@@ -21,9 +21,9 @@ #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" -#include "cc/output/context_provider.h" #include "cc/resources/single_release_callback.h" #include "components/exo/layer_tree_frame_sink_holder.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/quads/resource_format.h" #include "components/viz/common/quads/texture_mailbox.h" #include "gpu/command_buffer/client/context_support.h" @@ -99,9 +99,9 @@ class Buffer::Texture : public ui::ContextFactoryObserver { public: Texture(ui::ContextFactory* context_factory, - cc::ContextProvider* context_provider); + viz::ContextProvider* context_provider); Texture(ui::ContextFactory* context_factory, - cc::ContextProvider* context_provider, + viz::ContextProvider* context_provider, gfx::GpuMemoryBuffer* gpu_memory_buffer, unsigned texture_target, unsigned query_type); @@ -148,7 +148,7 @@ gfx::GpuMemoryBuffer* const gpu_memory_buffer_; ui::ContextFactory* context_factory_; - scoped_refptr<cc::ContextProvider> context_provider_; + scoped_refptr<viz::ContextProvider> context_provider_; const unsigned texture_target_; const unsigned query_type_; const GLenum internalformat_; @@ -165,7 +165,7 @@ }; Buffer::Texture::Texture(ui::ContextFactory* context_factory, - cc::ContextProvider* context_provider) + viz::ContextProvider* context_provider) : gpu_memory_buffer_(nullptr), context_factory_(context_factory), context_provider_(context_provider), @@ -182,7 +182,7 @@ } Buffer::Texture::Texture(ui::ContextFactory* context_factory, - cc::ContextProvider* context_provider, + viz::ContextProvider* context_provider, gfx::GpuMemoryBuffer* gpu_memory_buffer, unsigned texture_target, unsigned query_type) @@ -429,7 +429,7 @@ ui::ContextFactory* context_factory = aura::Env::GetInstance()->context_factory(); // Note: This can fail if GPU acceleration has been disabled. - scoped_refptr<cc::ContextProvider> context_provider = + scoped_refptr<viz::ContextProvider> context_provider = context_factory->SharedMainThreadContextProvider(); if (!context_provider) { DLOG(WARNING) << "Failed to acquire a context provider";
diff --git a/components/exo/buffer_unittest.cc b/components/exo/buffer_unittest.cc index d5ce3d2..bf562f98 100644 --- a/components/exo/buffer_unittest.cc +++ b/components/exo/buffer_unittest.cc
@@ -5,12 +5,12 @@ #include <GLES2/gl2extchromium.h> #include "base/bind.h" -#include "cc/output/context_provider.h" #include "cc/resources/single_release_callback.h" #include "components/exo/buffer.h" #include "components/exo/surface_tree_host.h" #include "components/exo/test/exo_test_base.h" #include "components/exo/test/exo_test_helper.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/khronos/GLES2/gl2.h" @@ -81,7 +81,7 @@ &resource); ASSERT_TRUE(rv); - scoped_refptr<cc::ContextProvider> context_provider = + scoped_refptr<viz::ContextProvider> context_provider = aura::Env::GetInstance() ->context_factory() ->SharedMainThreadContextProvider();
diff --git a/components/feedback/BUILD.gn b/components/feedback/BUILD.gn index 28cae94..e92d5d0 100644 --- a/components/feedback/BUILD.gn +++ b/components/feedback/BUILD.gn
@@ -24,6 +24,10 @@ "feedback_uploader_factory.h", "feedback_util.cc", "feedback_util.h", + "system_logs/system_logs_fetcher.cc", + "system_logs/system_logs_fetcher.h", + "system_logs/system_logs_source.cc", + "system_logs/system_logs_source.h", "tracing_manager.cc", "tracing_manager.h", ]
diff --git a/chrome/browser/feedback/system_logs/system_logs_fetcher.cc b/components/feedback/system_logs/system_logs_fetcher.cc similarity index 94% rename from chrome/browser/feedback/system_logs/system_logs_fetcher.cc rename to components/feedback/system_logs/system_logs_fetcher.cc index 2705636..4e7e510 100644 --- a/chrome/browser/feedback/system_logs/system_logs_fetcher.cc +++ b/components/feedback/system_logs/system_logs_fetcher.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 "chrome/browser/feedback/system_logs/system_logs_fetcher.h" +#include "components/feedback/system_logs/system_logs_fetcher.h" #include <utility> @@ -20,9 +20,7 @@ // List of keys in the SystemLogsResponse map whose corresponding values will // not be anonymized. constexpr const char* const kWhitelistedKeysOfUUIDs[] = { - "CHROMEOS_BOARD_APPID", - "CHROMEOS_CANARY_APPID", - "CHROMEOS_RELEASE_APPID", + "CHROMEOS_BOARD_APPID", "CHROMEOS_CANARY_APPID", "CHROMEOS_RELEASE_APPID", "CLIENT_ID", };
diff --git a/chrome/browser/feedback/system_logs/system_logs_fetcher.h b/components/feedback/system_logs/system_logs_fetcher.h similarity index 90% rename from chrome/browser/feedback/system_logs/system_logs_fetcher.h rename to components/feedback/system_logs/system_logs_fetcher.h index 4edb8358..1799d4f 100644 --- a/chrome/browser/feedback/system_logs/system_logs_fetcher.h +++ b/components/feedback/system_logs/system_logs_fetcher.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 CHROME_BROWSER_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_FETCHER_H_ -#define CHROME_BROWSER_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_FETCHER_H_ +#ifndef COMPONENTS_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_FETCHER_H_ +#define COMPONENTS_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_FETCHER_H_ #include <stddef.h> @@ -15,9 +15,9 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/feedback/system_logs/system_logs_source.h" #include "components/feedback/anonymizer_tool.h" #include "components/feedback/feedback_common.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs { @@ -80,4 +80,4 @@ } // namespace system_logs -#endif // CHROME_BROWSER_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_FETCHER_H_ +#endif // COMPONENTS_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_FETCHER_H_
diff --git a/chrome/browser/feedback/system_logs/system_logs_source.cc b/components/feedback/system_logs/system_logs_source.cc similarity index 84% rename from chrome/browser/feedback/system_logs/system_logs_source.cc rename to components/feedback/system_logs/system_logs_source.cc index adc9cec..f32cb2f1 100644 --- a/chrome/browser/feedback/system_logs/system_logs_source.cc +++ b/components/feedback/system_logs/system_logs_source.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 "chrome/browser/feedback/system_logs/system_logs_source.h" +#include "components/feedback/system_logs/system_logs_source.h" namespace system_logs {
diff --git a/chrome/browser/feedback/system_logs/system_logs_source.h b/components/feedback/system_logs/system_logs_source.h similarity index 84% rename from chrome/browser/feedback/system_logs/system_logs_source.h rename to components/feedback/system_logs/system_logs_source.h index 7135721..6b267ef 100644 --- a/chrome/browser/feedback/system_logs/system_logs_source.h +++ b/components/feedback/system_logs/system_logs_source.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 CHROME_BROWSER_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_SOURCE_H_ -#define CHROME_BROWSER_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_SOURCE_H_ +#ifndef COMPONENTS_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_SOURCE_H_ +#define COMPONENTS_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_SOURCE_H_ #include <string> @@ -36,4 +36,4 @@ } // namespace system_logs -#endif // CHROME_BROWSER_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_SOURCE_H_ +#endif // COMPONENTS_FEEDBACK_SYSTEM_LOGS_SYSTEM_LOGS_SOURCE_H_
diff --git a/components/find_in_page_strings.grdp b/components/find_in_page_strings.grdp index a1fd5422..fa48a79 100644 --- a/components/find_in_page_strings.grdp +++ b/components/find_in_page_strings.grdp
@@ -2,7 +2,7 @@ <grit-part> <message name="IDS_FIND_IN_PAGE_COUNT" desc="How many matches found and what item we are showing"> - <ph name="ACTIVE_MATCH">$1<ex>1</ex></ph> of <ph name="TOTAL_MATCHCOUNT">$2<ex>5</ex></ph> + <ph name="ACTIVE_MATCH">$1</ph>/<ph name="TOTAL_MATCHCOUNT">$2</ph> </message> <message name="IDS_FIND_IN_PAGE_PREVIOUS_TOOLTIP" desc="The tooltip for the previous button"> Previous
diff --git a/components/safe_browsing/BUILD.gn b/components/safe_browsing/BUILD.gn index 7b090bc..f09e7c6 100644 --- a/components/safe_browsing/BUILD.gn +++ b/components/safe_browsing/BUILD.gn
@@ -28,6 +28,7 @@ "//base:base", "//base:i18n", "//components/safe_browsing/common:safe_browsing_prefs", + "//components/safe_browsing/web_ui:constants", "//components/safe_browsing_db:database_manager", "//components/security_interstitials/core:core", "//content/public/browser:browser",
diff --git a/components/safe_browsing/base_resource_throttle.cc b/components/safe_browsing/base_resource_throttle.cc index 63907f2b..8de2554 100644 --- a/components/safe_browsing/base_resource_throttle.cc +++ b/components/safe_browsing/base_resource_throttle.cc
@@ -10,6 +10,7 @@ #include "base/trace_event/trace_event.h" #include "base/values.h" #include "components/safe_browsing/base_ui_manager.h" +#include "components/safe_browsing/web_ui/constants.h" #include "components/safe_browsing_db/util.h" #include "components/security_interstitials/content/unsafe_resource.h" #include "content/public/browser/browser_thread.h" @@ -349,6 +350,10 @@ UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes2.Checked", resource_type_, content::RESOURCE_TYPE_LAST_TYPE); + if (CheckWebUIUrls(url)) { + return false; + } + if (database_manager_->CheckBrowseUrl(url, threat_types_, this)) { threat_type_ = SB_THREAT_TYPE_SAFE; ui_manager_->LogPauseDelay(base::TimeDelta()); // No delay. @@ -369,6 +374,28 @@ return false; } +bool BaseResourceThrottle::CheckWebUIUrls(const GURL& url) { + DCHECK(threat_type_ == safe_browsing::SB_THREAT_TYPE_SAFE); + if (url == kChromeUISafeBrowsingMatchMalwareUrl) { + threat_type_ = safe_browsing::SB_THREAT_TYPE_URL_MALWARE; + } else if (url == kChromeUISafeBrowsingMatchPhishingUrl) { + threat_type_ = safe_browsing::SB_THREAT_TYPE_URL_PHISHING; + } else if (url == kChromeUISafeBrowsingMatchUnwantedUrl) { + threat_type_ = safe_browsing::SB_THREAT_TYPE_URL_UNWANTED; + } + + if (threat_type_ != safe_browsing::SB_THREAT_TYPE_SAFE) { + state_ = STATE_CHECKING_URL; + url_being_checked_ = url; + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&BaseResourceThrottle::OnCheckBrowseUrlResult, AsWeakPtr(), + url, threat_type_, ThreatMetadata())); + return true; + } + return false; +} + void BaseResourceThrottle::OnCheckUrlTimeout() { CHECK_EQ(state_, STATE_CHECKING_URL);
diff --git a/components/safe_browsing/base_resource_throttle.h b/components/safe_browsing/base_resource_throttle.h index 2ae5070..249be76f 100644 --- a/components/safe_browsing/base_resource_throttle.h +++ b/components/safe_browsing/base_resource_throttle.h
@@ -129,6 +129,11 @@ DEFERRED_PROCESSING, }; + // Checks if |url| is one of the hardcoded WebUI match URLs. Returns true if + // the URL is one of the hardcoded URLs and will post a task to + // OnCheckBrowseUrlResult. + bool CheckWebUIUrls(const GURL& url); + scoped_refptr<BaseUIManager> ui_manager_; // Starts running |url| through the safe browsing check. Returns true if the
diff --git a/components/safe_browsing/web_ui/constants.cc b/components/safe_browsing/web_ui/constants.cc index 881c1cc..4088770 100644 --- a/components/safe_browsing/web_ui/constants.cc +++ b/components/safe_browsing/web_ui/constants.cc
@@ -10,5 +10,11 @@ const char kChromeUISafeBrowsingHost[] = "safe-browsing"; const char kSbUnderConstruction[] = "The safe browsing page is under construction."; +extern const char kChromeUISafeBrowsingMatchMalwareUrl[] = + "chrome://safe-browsing/match?type=malware"; +extern const char kChromeUISafeBrowsingMatchPhishingUrl[] = + "chrome://safe-browsing/match?type=phishing"; +extern const char kChromeUISafeBrowsingMatchUnwantedUrl[] = + "chrome://safe-browsing/match?type=unwanted"; } // namespace safe_browsing
diff --git a/components/safe_browsing/web_ui/constants.h b/components/safe_browsing/web_ui/constants.h index 6169e065..fc1cf9be 100644 --- a/components/safe_browsing/web_ui/constants.h +++ b/components/safe_browsing/web_ui/constants.h
@@ -10,6 +10,9 @@ extern const char kChromeUISafeBrowsingURL[]; extern const char kChromeUISafeBrowsingHost[]; extern const char kSbUnderConstruction[]; +extern const char kChromeUISafeBrowsingMatchMalwareUrl[]; +extern const char kChromeUISafeBrowsingMatchPhishingUrl[]; +extern const char kChromeUISafeBrowsingMatchUnwantedUrl[]; } // namespace safe_browsing
diff --git a/components/ssl_config/ssl_config_service_manager_pref.cc b/components/ssl_config/ssl_config_service_manager_pref.cc index f6aaa9a..62bec0f 100644 --- a/components/ssl_config/ssl_config_service_manager_pref.cc +++ b/components/ssl_config/ssl_config_service_manager_pref.cc
@@ -213,6 +213,13 @@ local_state->SetDefaultPrefValue( ssl_config::prefs::kSSLVersionMax, new base::Value(switches::kSSLVersionTLSv13)); + } else if (tls13_variant == "record-type") { + local_state->SetDefaultPrefValue( + ssl_config::prefs::kTLS13Variant, + new base::Value(switches::kTLS13VariantRecordTypeExperiment)); + local_state->SetDefaultPrefValue( + ssl_config::prefs::kSSLVersionMax, + new base::Value(switches::kSSLVersionTLSv13)); } PrefChangeRegistrar::NamedChangeCallback local_state_callback =
diff --git a/components/ssl_config/ssl_config_switches.cc b/components/ssl_config/ssl_config_switches.cc index 691bb89..68c277c3 100644 --- a/components/ssl_config/ssl_config_switches.cc +++ b/components/ssl_config/ssl_config_switches.cc
@@ -27,5 +27,6 @@ const char kTLS13VariantDisabled[] = "disabled"; const char kTLS13VariantDraft[] = "draft"; const char kTLS13VariantExperiment[] = "experiment"; +const char kTLS13VariantRecordTypeExperiment[] = "record-type"; } // namespace switches
diff --git a/components/ssl_config/ssl_config_switches.h b/components/ssl_config/ssl_config_switches.h index 2d115dd3..8b67424 100644 --- a/components/ssl_config/ssl_config_switches.h +++ b/components/ssl_config/ssl_config_switches.h
@@ -17,6 +17,7 @@ extern const char kTLS13VariantDisabled[]; extern const char kTLS13VariantDraft[]; extern const char kTLS13VariantExperiment[]; +extern const char kTLS13VariantRecordTypeExperiment[]; } // namespace switches
diff --git a/components/viz/client/client_layer_tree_frame_sink.cc b/components/viz/client/client_layer_tree_frame_sink.cc index ca6af71..0cfef14 100644 --- a/components/viz/client/client_layer_tree_frame_sink.cc +++ b/components/viz/client/client_layer_tree_frame_sink.cc
@@ -15,8 +15,8 @@ namespace viz { ClientLayerTreeFrameSink::ClientLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, SharedBitmapManager* shared_bitmap_manager, std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source,
diff --git a/components/viz/client/client_layer_tree_frame_sink.h b/components/viz/client/client_layer_tree_frame_sink.h index 22562c6c..4a709aa 100644 --- a/components/viz/client/client_layer_tree_frame_sink.h +++ b/components/viz/client/client_layer_tree_frame_sink.h
@@ -8,9 +8,9 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "cc/ipc/compositor_frame_sink.mojom.h" -#include "cc/output/context_provider.h" #include "cc/output/layer_tree_frame_sink.h" #include "cc/scheduler/begin_frame_source.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/local_surface_id_allocator.h" #include "components/viz/common/surfaces/surface_id.h" #include "mojo/public/cpp/bindings/binding.h" @@ -25,8 +25,8 @@ public cc::ExternalBeginFrameSourceClient { public: ClientLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, SharedBitmapManager* shared_bitmap_manager, std::unique_ptr<cc::SyntheticBeginFrameSource>
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index b074c74..4681b20 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -5,7 +5,11 @@ import("//components/viz/viz.gni") import("//testing/test.gni") -viz_source_set("common") { +viz_component("common") { + output_name = "viz_common" + + defines = [ "VIZ_COMMON_IMPLEMENTATION" ] + sources = [ "gl_helper.cc", "gl_helper.h", @@ -13,6 +17,12 @@ "gl_helper_readback_support.h", "gl_helper_scaling.cc", "gl_helper_scaling.h", + "gpu/context_cache_controller.cc", + "gpu/context_cache_controller.h", + "gpu/context_provider.cc", + "gpu/context_provider.h", + "gpu/in_process_context_provider.cc", + "gpu/in_process_context_provider.h", "hit_test/aggregated_hit_test_region.h", "quads/resource_format.h", "quads/shared_bitmap.cc", @@ -44,11 +54,17 @@ "surfaces/surface_sequence.h", "surfaces/surface_sequence_generator.cc", "surfaces/surface_sequence_generator.h", + "viz_common_export.h", ] deps = [ "//base", + "//gpu", + "//gpu/command_buffer/client:gles2_implementation", "//gpu/command_buffer/client:gles2_interface", + "//gpu/command_buffer/service", + "//gpu/ipc:gl_in_process_context", + "//gpu/skia_bindings:skia_bindings", "//mojo/public/cpp/bindings", "//skia", "//ui/gfx:color_space",
diff --git a/components/viz/common/DEPS b/components/viz/common/DEPS index fb3a69c8..4efdc769 100644 --- a/components/viz/common/DEPS +++ b/components/viz/common/DEPS
@@ -4,6 +4,7 @@ "+gpu/GLES2", "+gpu/command_buffer/client", "+gpu/command_buffer/common", + "+gpu/command_buffer/service", "+gpu/ipc/common", "+mojo/public/cpp/bindings", "+ui/gfx/geometry",
diff --git a/components/viz/common/gl_helper.h b/components/viz/common/gl_helper.h index 6e6bed7..931b8549 100644 --- a/components/viz/common/gl_helper.h +++ b/components/viz/common/gl_helper.h
@@ -10,6 +10,7 @@ #include "base/atomicops.h" #include "base/callback.h" #include "base/macros.h" +#include "components/viz/common/viz_common_export.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -133,7 +134,7 @@ // Provides higher level operations on top of the gpu::gles2::GLES2Interface // interfaces. -class GLHelper { +class VIZ_COMMON_EXPORT GLHelper { public: GLHelper(gpu::gles2::GLES2Interface* gl, gpu::ContextSupport* context_support);
diff --git a/components/viz/common/gl_helper_scaling.h b/components/viz/common/gl_helper_scaling.h index 6a5a03f..a37ea91 100644 --- a/components/viz/common/gl_helper_scaling.h +++ b/components/viz/common/gl_helper_scaling.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "components/viz/common/gl_helper.h" +#include "components/viz/common/viz_common_export.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -23,7 +24,7 @@ // Implements GPU texture scaling methods. // Note that you should probably not use this class directly. // See gl_helper.cc::CreateScaler instead. -class GLHelperScaling { +class VIZ_COMMON_EXPORT GLHelperScaling { public: enum ShaderType { SHADER_BILINEAR,
diff --git a/components/viz/common/gpu/DEPS b/components/viz/common/gpu/DEPS new file mode 100644 index 0000000..945aba3f --- /dev/null +++ b/components/viz/common/gpu/DEPS
@@ -0,0 +1,12 @@ +include_rules = [ + "+cc/output", + "+cc/resources", + "+gpu/command_buffer", + "+gpu/GLES2/gl2extchromium.h", + "+gpu/ipc", + "+gpu/skia_bindings", + "+ui/gfx", + "+third_party/khronos/GLES2/gl2.h", + "+third_party/khronos/GLES2/gl2ext.h", + "+third_party/skia/include/gpu", +]
diff --git a/cc/output/context_cache_controller.cc b/components/viz/common/gpu/context_cache_controller.cc similarity index 97% rename from cc/output/context_cache_controller.cc rename to components/viz/common/gpu/context_cache_controller.cc index de178771..d49abb7 100644 --- a/cc/output/context_cache_controller.cc +++ b/components/viz/common/gpu/context_cache_controller.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 "cc/output/context_cache_controller.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "base/bind.h" #include "base/logging.h" @@ -11,7 +11,7 @@ #include "gpu/command_buffer/client/context_support.h" #include "third_party/skia/include/gpu/GrContext.h" -namespace cc { +namespace viz { namespace { static const int kIdleCleanupDelaySeconds = 1; } // namespace @@ -172,4 +172,4 @@ context_lock_->Release(); } -} // namespace cc +} // namespace viz
diff --git a/cc/output/context_cache_controller.h b/components/viz/common/gpu/context_cache_controller.h similarity index 90% rename from cc/output/context_cache_controller.h rename to components/viz/common/gpu/context_cache_controller.h index 614ec0d..feea7f33 100644 --- a/cc/output/context_cache_controller.h +++ b/components/viz/common/gpu/context_cache_controller.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 CC_OUTPUT_CONTEXT_CACHE_CONTROLLER_H_ -#define CC_OUTPUT_CONTEXT_CACHE_CONTROLLER_H_ +#ifndef COMPONENTS_VIZ_COMMON_GPU_CONTEXT_CACHE_CONTROLLER_H_ +#define COMPONENTS_VIZ_COMMON_GPU_CONTEXT_CACHE_CONTROLLER_H_ #include <cstdint> #include <memory> @@ -12,7 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" -#include "cc/cc_export.h" +#include "components/viz/common/viz_common_export.h" class GrContext; @@ -24,7 +24,7 @@ class ContextSupport; } -namespace cc { +namespace viz { // ContextCacheController manages clearing cached data on ContextProvider when // appropriate. Currently, cache clearing is triggered when the Context @@ -32,9 +32,9 @@ // ContextProvider may have multiple clients, ContextCacheController tracks // visibility and idle status across all clients and only cleans up when // appropriate. -class CC_EXPORT ContextCacheController { +class VIZ_COMMON_EXPORT ContextCacheController { public: - class CC_EXPORT ScopedToken { + class VIZ_COMMON_EXPORT ScopedToken { public: ~ScopedToken(); @@ -105,6 +105,6 @@ base::WeakPtrFactory<ContextCacheController> weak_factory_; }; -} // namespace cc +} // namespace viz -#endif // CC_OUTPUT_CONTEXT_CACHE_CONTROLLER_H_ +#endif // COMPONENTS_VIZ_COMMON_GPU_CONTEXT_CACHE_CONTROLLER_H_
diff --git a/cc/output/context_provider.cc b/components/viz/common/gpu/context_provider.cc similarity index 89% rename from cc/output/context_provider.cc rename to components/viz/common/gpu/context_provider.cc index 7842136..b54a430 100644 --- a/cc/output/context_provider.cc +++ b/components/viz/common/gpu/context_provider.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" -namespace cc { +namespace viz { ContextProvider::ScopedContextLock::ScopedContextLock( ContextProvider* context_provider) @@ -23,4 +23,4 @@ context_provider_->DetachFromThread(); } -} // namespace cc +} // namespace viz
diff --git a/cc/output/context_provider.h b/components/viz/common/gpu/context_provider.h similarity index 85% rename from cc/output/context_provider.h rename to components/viz/common/gpu/context_provider.h index 44c6941..35cc27f 100644 --- a/cc/output/context_provider.h +++ b/components/viz/common/gpu/context_provider.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 CC_OUTPUT_CONTEXT_PROVIDER_H_ -#define CC_OUTPUT_CONTEXT_PROVIDER_H_ +#ifndef COMPONENTS_VIZ_COMMON_GPU_CONTEXT_PROVIDER_H_ +#define COMPONENTS_VIZ_COMMON_GPU_CONTEXT_PROVIDER_H_ #include <stddef.h> #include <stdint.h> @@ -11,8 +11,8 @@ #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "cc/cc_export.h" -#include "cc/output/context_cache_controller.h" +#include "components/viz/common/gpu/context_cache_controller.h" +#include "components/viz/common/viz_common_export.h" #include "gpu/command_buffer/common/capabilities.h" class GrContext; @@ -23,19 +23,22 @@ namespace gpu { class ContextSupport; -namespace gles2 { class GLES2Interface; } +namespace gles2 { +class GLES2Interface; } +} // namespace gpu -namespace cc { +namespace viz { -class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> { +class VIZ_COMMON_EXPORT ContextProvider + : public base::RefCountedThreadSafe<ContextProvider> { public: // Hold an instance of this lock while using a context across multiple // threads. This only works for ContextProviders that will return a valid // lock from GetLock(), so is not always supported. Most use of // ContextProvider should be single-thread only on the thread that // BindToCurrentThread is run on. - class CC_EXPORT ScopedContextLock { + class VIZ_COMMON_EXPORT ScopedContextLock { public: explicit ScopedContextLock(ContextProvider* context_provider); ~ScopedContextLock(); @@ -96,6 +99,6 @@ virtual ~ContextProvider() {} }; -} // namespace cc +} // namespace viz -#endif // CC_OUTPUT_CONTEXT_PROVIDER_H_ +#endif // COMPONENTS_VIZ_COMMON_GPU_CONTEXT_PROVIDER_H_
diff --git a/cc/output/in_process_context_provider.cc b/components/viz/common/gpu/in_process_context_provider.cc similarity index 97% rename from cc/output/in_process_context_provider.cc rename to components/viz/common/gpu/in_process_context_provider.cc index cd53faa..bd20e254 100644 --- a/cc/output/in_process_context_provider.cc +++ b/components/viz/common/gpu/in_process_context_provider.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 "cc/output/in_process_context_provider.h" +#include "components/viz/common/gpu/in_process_context_provider.h" #include <stdint.h> @@ -31,7 +31,7 @@ #include "third_party/skia/include/gpu/gl/GrGLInterface.h" #include "ui/gfx/native_widget_types.h" -namespace cc { +namespace viz { namespace { @@ -151,4 +151,4 @@ context_->SetUpdateVSyncParametersCallback(callback); } -} // namespace cc +} // namespace viz
diff --git a/cc/output/in_process_context_provider.h b/components/viz/common/gpu/in_process_context_provider.h similarity index 81% rename from cc/output/in_process_context_provider.h rename to components/viz/common/gpu/in_process_context_provider.h index 0a355d2..493191f 100644 --- a/cc/output/in_process_context_provider.h +++ b/components/viz/common/gpu/in_process_context_provider.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 CC_OUTPUT_IN_PROCESS_CONTEXT_PROVIDER_H_ -#define CC_OUTPUT_IN_PROCESS_CONTEXT_PROVIDER_H_ +#ifndef COMPONENTS_VIZ_COMMON_GPU_IN_PROCESS_CONTEXT_PROVIDER_H_ +#define COMPONENTS_VIZ_COMMON_GPU_IN_PROCESS_CONTEXT_PROVIDER_H_ #include <stdint.h> @@ -11,9 +11,9 @@ #include "base/compiler_specific.h" #include "base/synchronization/lock.h" -#include "cc/cc_export.h" -#include "cc/output/context_cache_controller.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_cache_controller.h" +#include "components/viz/common/gpu/context_provider.h" +#include "components/viz/common/viz_common_export.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/ipc/in_process_command_buffer.h" #include "ui/gfx/native_widget_types.h" @@ -25,15 +25,15 @@ class GpuMemoryBufferManager; class ImageFactory; struct SharedMemoryLimits; -} +} // namespace gpu namespace skia_bindings { class GrContextForGLES2Interface; } -namespace cc { +namespace viz { -class CC_EXPORT InProcessContextProvider +class VIZ_COMMON_EXPORT InProcessContextProvider : public NON_EXPORTED_BASE(ContextProvider) { public: InProcessContextProvider( @@ -78,6 +78,6 @@ std::unique_ptr<ContextCacheController> cache_controller_; }; -} // namespace cc +} // namespace viz -#endif // CC_OUTPUT_IN_PROCESS_CONTEXT_PROVIDER_H_ +#endif // COMPONENTS_VIZ_COMMON_GPU_IN_PROCESS_CONTEXT_PROVIDER_H_
diff --git a/components/viz/common/quads/shared_bitmap.h b/components/viz/common/quads/shared_bitmap.h index 98e9cca..0d5fa83 100644 --- a/components/viz/common/quads/shared_bitmap.h +++ b/components/viz/common/quads/shared_bitmap.h
@@ -11,6 +11,7 @@ #include "base/hash.h" #include "base/macros.h" #include "base/trace_event/memory_allocator_dump.h" +#include "components/viz/common/viz_common_export.h" #include "gpu/command_buffer/common/mailbox.h" #include "ui/gfx/geometry/size.h" @@ -27,10 +28,10 @@ } }; -base::trace_event::MemoryAllocatorDumpGuid GetSharedBitmapGUIDForTracing( - const SharedBitmapId& bitmap_id); +VIZ_COMMON_EXPORT base::trace_event::MemoryAllocatorDumpGuid +GetSharedBitmapGUIDForTracing(const SharedBitmapId& bitmap_id); -class SharedBitmap { +class VIZ_COMMON_EXPORT SharedBitmap { public: SharedBitmap(uint8_t* pixels, const SharedBitmapId& id,
diff --git a/components/viz/common/quads/texture_mailbox.h b/components/viz/common/quads/texture_mailbox.h index 7136d7e..3c24f3b 100644 --- a/components/viz/common/quads/texture_mailbox.h +++ b/components/viz/common/quads/texture_mailbox.h
@@ -12,6 +12,7 @@ #include "base/memory/shared_memory.h" #include "build/build_config.h" +#include "components/viz/common/viz_common_export.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "mojo/public/cpp/bindings/struct_traits.h" #include "ui/gfx/color_space.h" @@ -29,7 +30,7 @@ // TODO(skaslev, danakj) Rename this class more apropriately since now it // can hold a shared memory resource as well as a texture mailbox. -class TextureMailbox { +class VIZ_COMMON_EXPORT TextureMailbox { public: TextureMailbox(); TextureMailbox(const TextureMailbox& other);
diff --git a/components/viz/common/resources/buffer_to_texture_target_map.h b/components/viz/common/resources/buffer_to_texture_target_map.h index b8b7364..27539475 100644 --- a/components/viz/common/resources/buffer_to_texture_target_map.h +++ b/components/viz/common/resources/buffer_to_texture_target_map.h
@@ -8,6 +8,7 @@ #include <map> #include <string> +#include "components/viz/common/viz_common_export.h" #include "ui/gfx/buffer_types.h" namespace viz { @@ -18,17 +19,18 @@ // Converts a serialized ImageTextureTargetsMap back to the runtime format. // Serialization takes the form: // "usage,format,target;usage,format,target;...;usage,format,target" -BufferToTextureTargetMap StringToBufferToTextureTargetMap( - const std::string& str); +VIZ_COMMON_EXPORT BufferToTextureTargetMap +StringToBufferToTextureTargetMap(const std::string& str); // Converts an ImageTextureTargetsMap to a string representation of the format: // "usage,format,target;usage,format,target;...;usage,format,target" -std::string BufferToTextureTargetMapToString( +VIZ_COMMON_EXPORT std::string BufferToTextureTargetMapToString( const BufferToTextureTargetMap& map); // Returns a default-initialized BufferToTextureTargetsMap where every entry // maps to GL_TEXTURE_2D. -BufferToTextureTargetMap DefaultBufferToTextureTargetMapForTesting(); +VIZ_COMMON_EXPORT BufferToTextureTargetMap +DefaultBufferToTextureTargetMapForTesting(); } // namespace viz
diff --git a/components/viz/common/resources/resource_format_utils.h b/components/viz/common/resources/resource_format_utils.h index 923357e..935ccc8 100644 --- a/components/viz/common/resources/resource_format_utils.h +++ b/components/viz/common/resources/resource_format_utils.h
@@ -6,19 +6,21 @@ #define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FORMAT_UTILS_H_ #include "components/viz/common/quads/resource_format.h" +#include "components/viz/common/viz_common_export.h" #include "third_party/skia/include/core/SkImageInfo.h" namespace viz { -SkColorType ResourceFormatToClosestSkColorType(ResourceFormat format); -int BitsPerPixel(ResourceFormat format); -GLenum GLDataType(ResourceFormat format); -GLenum GLDataFormat(ResourceFormat format); -GLenum GLInternalFormat(ResourceFormat format); -GLenum GLCopyTextureInternalFormat(ResourceFormat format); -gfx::BufferFormat BufferFormat(ResourceFormat format); -bool IsResourceFormatCompressed(ResourceFormat format); -bool DoesResourceFormatSupportAlpha(ResourceFormat format); +VIZ_COMMON_EXPORT SkColorType +ResourceFormatToClosestSkColorType(ResourceFormat format); +VIZ_COMMON_EXPORT int BitsPerPixel(ResourceFormat format); +VIZ_COMMON_EXPORT GLenum GLDataType(ResourceFormat format); +VIZ_COMMON_EXPORT GLenum GLDataFormat(ResourceFormat format); +VIZ_COMMON_EXPORT GLenum GLInternalFormat(ResourceFormat format); +VIZ_COMMON_EXPORT GLenum GLCopyTextureInternalFormat(ResourceFormat format); +VIZ_COMMON_EXPORT gfx::BufferFormat BufferFormat(ResourceFormat format); +VIZ_COMMON_EXPORT bool IsResourceFormatCompressed(ResourceFormat format); +VIZ_COMMON_EXPORT bool DoesResourceFormatSupportAlpha(ResourceFormat format); } // namespace viz
diff --git a/components/viz/common/resources/resource_settings.h b/components/viz/common/resources/resource_settings.h index e20fe8f..31ab9d0 100644 --- a/components/viz/common/resources/resource_settings.h +++ b/components/viz/common/resources/resource_settings.h
@@ -6,12 +6,13 @@ #define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_SETTINGS_H_ #include "components/viz/common/resources/buffer_to_texture_target_map.h" +#include "components/viz/common/viz_common_export.h" namespace viz { // ResourceSettings contains all the settings that are needed to create a // ResourceProvider. -class ResourceSettings { +class VIZ_COMMON_EXPORT ResourceSettings { public: ResourceSettings(); ResourceSettings(const ResourceSettings& other);
diff --git a/components/viz/common/surfaces/frame_sink_id.h b/components/viz/common/surfaces/frame_sink_id.h index 8657f1e..30319d7b 100644 --- a/components/viz/common/surfaces/frame_sink_id.h +++ b/components/viz/common/surfaces/frame_sink_id.h
@@ -12,10 +12,11 @@ #include <tuple> #include "base/hash.h" +#include "components/viz/common/viz_common_export.h" namespace viz { -class FrameSinkId { +class VIZ_COMMON_EXPORT FrameSinkId { public: constexpr FrameSinkId() : client_id_(0), sink_id_(0) {} @@ -51,7 +52,8 @@ uint32_t sink_id_; }; -std::ostream& operator<<(std::ostream& out, const FrameSinkId& frame_sink_id); +VIZ_COMMON_EXPORT std::ostream& operator<<(std::ostream& out, + const FrameSinkId& frame_sink_id); struct FrameSinkIdHash { size_t operator()(const FrameSinkId& key) const { return key.hash(); }
diff --git a/components/viz/common/surfaces/local_surface_id.h b/components/viz/common/surfaces/local_surface_id.h index 43bd9b7..450386c6 100644 --- a/components/viz/common/surfaces/local_surface_id.h +++ b/components/viz/common/surfaces/local_surface_id.h
@@ -13,6 +13,7 @@ #include "base/hash.h" #include "base/unguessable_token.h" +#include "components/viz/common/viz_common_export.h" #include "mojo/public/cpp/bindings/struct_traits.h" namespace cc { @@ -23,7 +24,7 @@ namespace viz { -class LocalSurfaceId { +class VIZ_COMMON_EXPORT LocalSurfaceId { public: constexpr LocalSurfaceId() : local_id_(0) {} @@ -71,8 +72,9 @@ base::UnguessableToken nonce_; }; -std::ostream& operator<<(std::ostream& out, - const LocalSurfaceId& local_surface_id); +VIZ_COMMON_EXPORT std::ostream& operator<<( + std::ostream& out, + const LocalSurfaceId& local_surface_id); struct LocalSurfaceIdHash { size_t operator()(const LocalSurfaceId& key) const { return key.hash(); }
diff --git a/components/viz/common/surfaces/local_surface_id_allocator.h b/components/viz/common/surfaces/local_surface_id_allocator.h index a1034939..bc01fd5 100644 --- a/components/viz/common/surfaces/local_surface_id_allocator.h +++ b/components/viz/common/surfaces/local_surface_id_allocator.h
@@ -9,13 +9,14 @@ #include "base/macros.h" #include "components/viz/common/surfaces/surface_id.h" +#include "components/viz/common/viz_common_export.h" namespace viz { // This is a helper class for generating local surface IDs for a single // FrameSink. This is not threadsafe, to use from multiple threads wrap this // class in a mutex. -class LocalSurfaceIdAllocator { +class VIZ_COMMON_EXPORT LocalSurfaceIdAllocator { public: LocalSurfaceIdAllocator(); ~LocalSurfaceIdAllocator();
diff --git a/components/viz/common/surfaces/sequence_surface_reference_factory.h b/components/viz/common/surfaces/sequence_surface_reference_factory.h index 9c2096b..93fa953 100644 --- a/components/viz/common/surfaces/sequence_surface_reference_factory.h +++ b/components/viz/common/surfaces/sequence_surface_reference_factory.h
@@ -7,11 +7,12 @@ #include "components/viz/common/surfaces/surface_reference_factory.h" #include "components/viz/common/surfaces/surface_sequence.h" +#include "components/viz/common/viz_common_export.h" namespace viz { // A surface reference factory that uses SurfaceSequence. -class SequenceSurfaceReferenceFactory +class VIZ_COMMON_EXPORT SequenceSurfaceReferenceFactory : public NON_EXPORTED_BASE(SurfaceReferenceFactory) { public: SequenceSurfaceReferenceFactory() = default;
diff --git a/components/viz/common/surfaces/surface_id.h b/components/viz/common/surfaces/surface_id.h index ae5d4731..b008aba 100644 --- a/components/viz/common/surfaces/surface_id.h +++ b/components/viz/common/surfaces/surface_id.h
@@ -14,6 +14,7 @@ #include "base/hash.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/local_surface_id.h" +#include "components/viz/common/viz_common_export.h" #include "mojo/public/cpp/bindings/struct_traits.h" namespace cc { @@ -24,7 +25,7 @@ namespace viz { -class SurfaceId { +class VIZ_COMMON_EXPORT SurfaceId { public: constexpr SurfaceId() = default; @@ -75,7 +76,8 @@ LocalSurfaceId local_surface_id_; }; -std::ostream& operator<<(std::ostream& out, const SurfaceId& surface_id); +VIZ_COMMON_EXPORT std::ostream& operator<<(std::ostream& out, + const SurfaceId& surface_id); struct SurfaceIdHash { size_t operator()(const SurfaceId& key) const { return key.hash(); }
diff --git a/components/viz/common/surfaces/surface_sequence_generator.h b/components/viz/common/surfaces/surface_sequence_generator.h index c9e104b..1bed7d5 100644 --- a/components/viz/common/surfaces/surface_sequence_generator.h +++ b/components/viz/common/surfaces/surface_sequence_generator.h
@@ -13,11 +13,12 @@ #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/surface_sequence.h" +#include "components/viz/common/viz_common_export.h" namespace viz { // Generates unique surface sequences for a surface client id. -class SurfaceSequenceGenerator { +class VIZ_COMMON_EXPORT SurfaceSequenceGenerator { public: SurfaceSequenceGenerator(); ~SurfaceSequenceGenerator();
diff --git a/components/viz/common/viz_common_export.h b/components/viz/common/viz_common_export.h new file mode 100644 index 0000000..9e58b13 --- /dev/null +++ b/components/viz/common/viz_common_export.h
@@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIZ_COMMON_VIZ_COMMON_EXPORT_H_ +#define COMPONENTS_VIZ_COMMON_VIZ_COMMON_EXPORT_H_ + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(VIZ_COMMON_IMPLEMENTATION) +#define VIZ_COMMON_EXPORT __declspec(dllexport) +#else +#define VIZ_COMMON_EXPORT __declspec(dllimport) +#endif // defined(VIZ_COMMON_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(VIZ_COMMON_IMPLEMENTATION) +#define VIZ_COMMON_EXPORT __attribute__((visibility("default"))) +#else +#define VIZ_COMMON_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define VIZ_COMMON_EXPORT +#endif + +#endif // COMPONENTS_VIZ_COMMON_VIZ_COMMON_EXPORT_H_
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index e15a3d7..c65121a0 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -138,6 +138,7 @@ "frame_sinks/direct_layer_tree_frame_sink_unittest.cc", "frame_sinks/frame_sink_manager_unittest.cc", "frame_sinks/referenced_surface_tracker_unittest.cc", + "frame_sinks/surface_references_unittest.cc", "frame_sinks/surface_synchronization_unittest.cc", "hit_test/hit_test_aggregator_unittest.cc", ]
diff --git a/components/viz/service/display_embedder/display_output_surface.cc b/components/viz/service/display_embedder/display_output_surface.cc index 04cf8f1..23905232 100644 --- a/components/viz/service/display_embedder/display_output_surface.cc +++ b/components/viz/service/display_embedder/display_output_surface.cc
@@ -9,17 +9,17 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" -#include "cc/output/context_provider.h" #include "cc/output/output_surface_client.h" #include "cc/output/output_surface_frame.h" #include "cc/scheduler/begin_frame_source.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" namespace viz { DisplayOutputSurface::DisplayOutputSurface( - scoped_refptr<cc::InProcessContextProvider> context_provider, + scoped_refptr<InProcessContextProvider> context_provider, cc::SyntheticBeginFrameSource* synthetic_begin_frame_source) : cc::OutputSurface(context_provider), synthetic_begin_frame_source_(synthetic_begin_frame_source), @@ -94,7 +94,7 @@ uint32_t DisplayOutputSurface::GetFramebufferCopyTextureFormat() { // TODO(danakj): What attributes are used for the default framebuffer here? - // Can it have alpha? cc::InProcessContextProvider doesn't take any + // Can it have alpha? InProcessContextProvider doesn't take any // attributes. return GL_RGB; }
diff --git a/components/viz/service/display_embedder/display_output_surface.h b/components/viz/service/display_embedder/display_output_surface.h index 0dad061e..032db0fa 100644 --- a/components/viz/service/display_embedder/display_output_surface.h +++ b/components/viz/service/display_embedder/display_output_surface.h
@@ -7,8 +7,8 @@ #include <memory> -#include "cc/output/in_process_context_provider.h" #include "cc/output/output_surface.h" +#include "components/viz/common/gpu/in_process_context_provider.h" #include "ui/latency/latency_tracker.h" namespace cc { @@ -22,7 +22,7 @@ class DisplayOutputSurface : public cc::OutputSurface { public: DisplayOutputSurface( - scoped_refptr<cc::InProcessContextProvider> context_provider, + scoped_refptr<InProcessContextProvider> context_provider, cc::SyntheticBeginFrameSource* synthetic_begin_frame_source); ~DisplayOutputSurface() override;
diff --git a/components/viz/service/display_embedder/display_output_surface_ozone.cc b/components/viz/service/display_embedder/display_output_surface_ozone.cc index a9d2dc5..1558ad2b 100644 --- a/components/viz/service/display_embedder/display_output_surface_ozone.cc +++ b/components/viz/service/display_embedder/display_output_surface_ozone.cc
@@ -8,10 +8,10 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" -#include "cc/output/context_provider.h" #include "cc/output/output_surface_client.h" #include "cc/output/output_surface_frame.h" #include "cc/scheduler/begin_frame_source.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/service/display_embedder/buffer_queue.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" @@ -20,7 +20,7 @@ namespace viz { DisplayOutputSurfaceOzone::DisplayOutputSurfaceOzone( - scoped_refptr<cc::InProcessContextProvider> context_provider, + scoped_refptr<InProcessContextProvider> context_provider, gfx::AcceleratedWidget widget, cc::SyntheticBeginFrameSource* synthetic_begin_frame_source, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
diff --git a/components/viz/service/display_embedder/display_output_surface_ozone.h b/components/viz/service/display_embedder/display_output_surface_ozone.h index 46999009..3715e39d 100644 --- a/components/viz/service/display_embedder/display_output_surface_ozone.h +++ b/components/viz/service/display_embedder/display_output_surface_ozone.h
@@ -8,10 +8,10 @@ #include <memory> #include "base/memory/weak_ptr.h" -#include "cc/output/context_provider.h" -#include "cc/output/in_process_context_provider.h" #include "cc/output/output_surface.h" #include "components/viz/common/gl_helper.h" +#include "components/viz/common/gpu/context_provider.h" +#include "components/viz/common/gpu/in_process_context_provider.h" #include "components/viz/service/display_embedder/display_output_surface.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_widget_types.h" @@ -37,7 +37,7 @@ class DisplayOutputSurfaceOzone : public DisplayOutputSurface { public: DisplayOutputSurfaceOzone( - scoped_refptr<cc::InProcessContextProvider> context_provider, + scoped_refptr<InProcessContextProvider> context_provider, gfx::AcceleratedWidget widget, cc::SyntheticBeginFrameSource* synthetic_begin_frame_source, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
diff --git a/components/viz/service/display_embedder/gpu_display_provider.cc b/components/viz/service/display_embedder/gpu_display_provider.cc index 0891a9f..df1cb39 100644 --- a/components/viz/service/display_embedder/gpu_display_provider.cc +++ b/components/viz/service/display_embedder/gpu_display_provider.cc
@@ -10,9 +10,9 @@ #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" #include "cc/base/switches.h" -#include "cc/output/in_process_context_provider.h" #include "cc/output/texture_mailbox_deleter.h" #include "cc/scheduler/begin_frame_source.h" +#include "components/viz/common/gpu/in_process_context_provider.h" #include "components/viz/service/display/display.h" #include "components/viz/service/display/display_scheduler.h" #include "components/viz/service/display_embedder/display_output_surface.h" @@ -59,11 +59,11 @@ base::MakeUnique<cc::DelayBasedBeginFrameSource>( base::MakeUnique<cc::DelayBasedTimeSource>(task_runner_.get())); - scoped_refptr<cc::InProcessContextProvider> context_provider = - new cc::InProcessContextProvider( - gpu_service_, surface_handle, gpu_memory_buffer_manager_.get(), - image_factory_, gpu::SharedMemoryLimits(), - nullptr /* shared_context */); + scoped_refptr<InProcessContextProvider> context_provider = + new InProcessContextProvider(gpu_service_, surface_handle, + gpu_memory_buffer_manager_.get(), + image_factory_, gpu::SharedMemoryLimits(), + nullptr /* shared_context */); // TODO(rjkroege): If there is something better to do than CHECK, add it. CHECK(context_provider->BindToCurrentThread());
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index 7863532..10be06a 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -53,7 +53,7 @@ EvictCurrentSurface(); frame_sink_manager_->UnregisterFrameSinkManagerClient(frame_sink_id_); if (handles_frame_sink_id_invalidation_) - frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id_); + surface_manager_->InvalidateFrameSinkId(frame_sink_id_); } void CompositorFrameSinkSupport::SetDestructionCallback( @@ -318,7 +318,7 @@ frame_sink_manager_ = frame_sink_manager; surface_manager_ = frame_sink_manager->surface_manager(); if (handles_frame_sink_id_invalidation_) - frame_sink_manager_->RegisterFrameSinkId(frame_sink_id_); + surface_manager_->RegisterFrameSinkId(frame_sink_id_); frame_sink_manager_->RegisterFrameSinkManagerClient(frame_sink_id_, this); }
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc index 52f64483..71475e5 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
@@ -586,7 +586,8 @@ local_surface_id); local_surface_id_ = LocalSurfaceId(); - manager_.RegisterFrameSinkId(kYetAnotherArbitraryFrameSinkId); + manager_.surface_manager()->RegisterFrameSinkId( + kYetAnotherArbitraryFrameSinkId); SurfaceId surface_id(kAnotherArbitraryFrameSinkId, local_surface_id); cc::Surface* surface = GetSurfaceForId(surface_id); @@ -648,7 +649,7 @@ support_->SubmitCompositorFrame(local_surface_id, cc::test::MakeCompositorFrame()); - manager_.RegisterFrameSinkId(frame_sink_id); + manager_.surface_manager()->RegisterFrameSinkId(frame_sink_id); GetSurfaceForId(id)->AddDestructionDependency( SurfaceSequence(frame_sink_id, 4)); @@ -657,7 +658,7 @@ // Verify the dependency has prevented the surface from getting destroyed. EXPECT_TRUE(GetSurfaceForId(id)); - manager_.InvalidateFrameSinkId(frame_sink_id); + manager_.surface_manager()->InvalidateFrameSinkId(frame_sink_id); // Verify that the invalidated namespace caused the unsatisfied sequence // to be ignored. @@ -670,7 +671,7 @@ auto support2 = CompositorFrameSinkSupport::Create( &fake_support_client_, &manager_, kYetAnotherArbitraryFrameSinkId, kIsChildRoot, kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints); - manager_.RegisterFrameSinkId(kAnotherArbitraryFrameSinkId); + manager_.surface_manager()->RegisterFrameSinkId(kAnotherArbitraryFrameSinkId); // Give local_surface_id_ an initial frame so another client can refer to // that surface. {
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc index 4c6b389..4cb312e8 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -21,8 +21,8 @@ CompositorFrameSinkSupportManager* support_manager, FrameSinkManager* frame_sink_manager, Display* display, - scoped_refptr<cc::ContextProvider> context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, SharedBitmapManager* shared_bitmap_manager) : LayerTreeFrameSink(std::move(context_provider),
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h index 30391ff..e132436c 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
@@ -39,8 +39,8 @@ CompositorFrameSinkSupportManager* support_manager, FrameSinkManager* frame_sink_manager, Display* display, - scoped_refptr<cc::ContextProvider> context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, SharedBitmapManager* shared_bitmap_manager); DirectLayerTreeFrameSink(
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc index fc5fd11d..0769d88 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
@@ -73,8 +73,6 @@ display_rect_(display_size_), support_manager_(&frame_sink_manager_), context_provider_(cc::TestContextProvider::Create()) { - frame_sink_manager_.RegisterFrameSinkId(kArbitraryFrameSinkId); - auto display_output_surface = cc::FakeOutputSurface::Create3d(); display_output_surface_ = display_output_surface.get();
diff --git a/components/viz/service/frame_sinks/frame_sink_manager.cc b/components/viz/service/frame_sinks/frame_sink_manager.cc index bed468a..41683c9 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager.cc
@@ -34,14 +34,6 @@ DCHECK_EQ(registered_sources_.size(), 0u); } -void FrameSinkManager::RegisterFrameSinkId(const FrameSinkId& frame_sink_id) { - surface_manager_.RegisterFrameSinkId(frame_sink_id); -} - -void FrameSinkManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) { - surface_manager_.InvalidateFrameSinkId(frame_sink_id); -} - void FrameSinkManager::RegisterFrameSinkManagerClient( const FrameSinkId& frame_sink_id, FrameSinkManagerClient* client) { @@ -237,8 +229,4 @@ RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first); } -void FrameSinkManager::DropTemporaryReference(const SurfaceId& surface_id) { - surface_manager_.DropTemporaryReference(surface_id); -} - } // namespace viz
diff --git a/components/viz/service/frame_sinks/frame_sink_manager.h b/components/viz/service/frame_sinks/frame_sink_manager.h index 18a0700..716d955 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager.h +++ b/components/viz/service/frame_sinks/frame_sink_manager.h
@@ -41,12 +41,6 @@ cc::SurfaceManager::LifetimeType::SEQUENCES); ~FrameSinkManager(); - void RegisterFrameSinkId(const FrameSinkId& frame_sink_id); - - // Invalidate a frame_sink_id that might still have associated sequences, - // possibly because a renderer process has crashed. - void InvalidateFrameSinkId(const FrameSinkId& frame_sink_id); - // CompositorFrameSinkSupport, hierarchy, and BeginFrameSource can be // registered and unregistered in any order with respect to each other. // @@ -82,11 +76,6 @@ void UnregisterFrameSinkHierarchy(const FrameSinkId& parent_frame_sink_id, const FrameSinkId& child_frame_sink_id); - // Drops the temporary reference for |surface_id|. If a surface reference has - // already been added from the parent to |surface_id| then this will do - // nothing. - void DropTemporaryReference(const SurfaceId& surface_id); - cc::SurfaceManager* surface_manager() { return &surface_manager_; } private:
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index 795212fd..3ee3655 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -105,7 +105,7 @@ } void FrameSinkManagerImpl::DropTemporaryReference(const SurfaceId& surface_id) { - manager_.DropTemporaryReference(surface_id); + manager_.surface_manager()->DropTemporaryReference(surface_id); } void FrameSinkManagerImpl::DestroyCompositorFrameSink(FrameSinkId sink_id) {
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc index 977351c..b8a7ebf4 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
@@ -66,20 +66,9 @@ class FrameSinkManagerTest : public testing::Test { public: - // These tests don't care about namespace registration, so just preregister - // a set of namespaces that tests can use freely without worrying if they're - // valid or not. - enum { MAX_FRAME_SINK = 10 }; + FrameSinkManagerTest() = default; - FrameSinkManagerTest() { - for (size_t i = 0; i < MAX_FRAME_SINK; ++i) - manager_.RegisterFrameSinkId(FrameSinkId(i, i)); - } - - ~FrameSinkManagerTest() override { - for (size_t i = 0; i < MAX_FRAME_SINK; ++i) - manager_.InvalidateFrameSinkId(FrameSinkId(i, i)); - } + ~FrameSinkManagerTest() override = default; protected: FrameSinkManager manager_;
diff --git a/cc/surfaces/surface_manager_ref_unittest.cc b/components/viz/service/frame_sinks/surface_references_unittest.cc similarity index 72% rename from cc/surfaces/surface_manager_ref_unittest.cc rename to components/viz/service/frame_sinks/surface_references_unittest.cc index 58972b0..dff1b14c 100644 --- a/cc/surfaces/surface_manager_ref_unittest.cc +++ b/components/viz/service/frame_sinks/surface_references_unittest.cc
@@ -23,86 +23,89 @@ using testing::SizeIs; using testing::UnorderedElementsAre; -namespace cc { +namespace viz { +namespace test { namespace { -constexpr viz::FrameSinkId kFrameSink1(1, 0); -constexpr viz::FrameSinkId kFrameSink2(2, 0); -constexpr viz::FrameSinkId kFrameSink3(3, 0); +constexpr FrameSinkId kFrameSink1(1, 0); +constexpr FrameSinkId kFrameSink2(2, 0); +constexpr FrameSinkId kFrameSink3(3, 0); } // namespace -// Tests for reference tracking in SurfaceManager. -class SurfaceManagerRefTest : public testing::Test { +// Tests for reference tracking in CompositorFrameSinkSupport and +// cc::SurfaceManager. +class SurfaceReferencesTest : public testing::Test { public: - SurfaceManager& GetSurfaceManager() { return *manager_->surface_manager(); } + cc::SurfaceManager& GetSurfaceManager() { + return *manager_->surface_manager(); + } // Creates a new Surface with the provided |frame_sink_id| and |local_id|. // Will first create a Surfacesupport for |frame_sink_id| if necessary. - viz::SurfaceId CreateSurface(const viz::FrameSinkId& frame_sink_id, - uint32_t local_id) { - viz::LocalSurfaceId local_surface_id( - local_id, base::UnguessableToken::Deserialize(0, 1u)); + SurfaceId CreateSurface(const FrameSinkId& frame_sink_id, uint32_t local_id) { + LocalSurfaceId local_surface_id(local_id, + base::UnguessableToken::Deserialize(0, 1u)); GetCompositorFrameSinkSupport(frame_sink_id) - .SubmitCompositorFrame(local_surface_id, test::MakeCompositorFrame()); - return viz::SurfaceId(frame_sink_id, local_surface_id); + .SubmitCompositorFrame(local_surface_id, + cc::test::MakeCompositorFrame()); + return SurfaceId(frame_sink_id, local_surface_id); } // Destroy Surface with |surface_id|. - void DestroySurface(const viz::SurfaceId& surface_id) { + void DestroySurface(const SurfaceId& surface_id) { GetCompositorFrameSinkSupport(surface_id.frame_sink_id()) .EvictCurrentSurface(); } - viz::CompositorFrameSinkSupport& GetCompositorFrameSinkSupport( - const viz::FrameSinkId& frame_sink_id) { + CompositorFrameSinkSupport& GetCompositorFrameSinkSupport( + const FrameSinkId& frame_sink_id) { auto& support_ptr = supports_[frame_sink_id]; if (!support_ptr) { constexpr bool is_root = false; constexpr bool handles_frame_sink_id_invalidation = true; constexpr bool needs_sync_points = true; - support_ptr = viz::CompositorFrameSinkSupport::Create( + support_ptr = CompositorFrameSinkSupport::Create( nullptr, manager_.get(), frame_sink_id, is_root, handles_frame_sink_id_invalidation, needs_sync_points); } return *support_ptr; } - void DestroyCompositorFrameSinkSupport( - const viz::FrameSinkId& frame_sink_id) { + void DestroyCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id) { auto support_ptr = supports_.find(frame_sink_id); ASSERT_NE(support_ptr, supports_.end()); supports_.erase(support_ptr); } - void RemoveSurfaceReference(const viz::SurfaceId& parent_id, - const viz::SurfaceId& child_id) { + void RemoveSurfaceReference(const SurfaceId& parent_id, + const SurfaceId& child_id) { manager_->surface_manager()->RemoveSurfaceReferences( - {SurfaceReference(parent_id, child_id)}); + {cc::SurfaceReference(parent_id, child_id)}); } - void AddSurfaceReference(const viz::SurfaceId& parent_id, - const viz::SurfaceId& child_id) { + void AddSurfaceReference(const SurfaceId& parent_id, + const SurfaceId& child_id) { manager_->surface_manager()->AddSurfaceReferences( - {SurfaceReference(parent_id, child_id)}); + {cc::SurfaceReference(parent_id, child_id)}); } // Returns all the references where |surface_id| is the parent. - const base::flat_set<viz::SurfaceId>& GetReferencesFrom( - const viz::SurfaceId& surface_id) { + const base::flat_set<SurfaceId>& GetReferencesFrom( + const SurfaceId& surface_id) { return GetSurfaceManager().GetSurfacesReferencedByParent(surface_id); } // Returns all the references where |surface_id| is the child. - const base::flat_set<viz::SurfaceId>& GetReferencesFor( - const viz::SurfaceId& surface_id) { + const base::flat_set<SurfaceId>& GetReferencesFor( + const SurfaceId& surface_id) { return GetSurfaceManager().GetSurfacesThatReferenceChild(surface_id); } - // Temporary references are stored as a map in SurfaceManager. This method + // Temporary references are stored as a map in cc::SurfaceManager. This method // converts the map to a vector. - std::vector<viz::SurfaceId> GetAllTempReferences() { - std::vector<viz::SurfaceId> temp_references; + std::vector<SurfaceId> GetAllTempReferences() { + std::vector<SurfaceId> temp_references; for (auto& map_entry : GetSurfaceManager().temporary_references_) temp_references.push_back(map_entry.first); return temp_references; @@ -111,9 +114,9 @@ protected: // testing::Test: void SetUp() override { - // Start each test with a fresh SurfaceManager instance. - manager_ = base::MakeUnique<viz::FrameSinkManager>( - SurfaceManager::LifetimeType::REFERENCES); + // Start each test with a fresh cc::SurfaceManager instance. + manager_ = base::MakeUnique<FrameSinkManager>( + cc::SurfaceManager::LifetimeType::REFERENCES); } void TearDown() override { for (auto& support : supports_) @@ -122,15 +125,15 @@ manager_.reset(); } - std::unordered_map<viz::FrameSinkId, - std::unique_ptr<viz::CompositorFrameSinkSupport>, - viz::FrameSinkIdHash> + std::unordered_map<FrameSinkId, + std::unique_ptr<CompositorFrameSinkSupport>, + FrameSinkIdHash> supports_; - std::unique_ptr<viz::FrameSinkManager> manager_; + std::unique_ptr<FrameSinkManager> manager_; }; -TEST_F(SurfaceManagerRefTest, AddReference) { - viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); +TEST_F(SurfaceReferencesTest, AddReference) { + SurfaceId id1 = CreateSurface(kFrameSink1, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), id1); EXPECT_THAT(GetReferencesFor(id1), @@ -138,9 +141,9 @@ EXPECT_THAT(GetReferencesFrom(id1), IsEmpty()); } -TEST_F(SurfaceManagerRefTest, AddRemoveReference) { - viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); - viz::SurfaceId id2 = CreateSurface(kFrameSink2, 1); +TEST_F(SurfaceReferencesTest, AddRemoveReference) { + SurfaceId id1 = CreateSurface(kFrameSink1, 1); + SurfaceId id2 = CreateSurface(kFrameSink2, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), id1); AddSurfaceReference(id1, id2); @@ -157,10 +160,10 @@ EXPECT_THAT(GetReferencesFrom(id2), IsEmpty()); } -TEST_F(SurfaceManagerRefTest, NewSurfaceFromFrameSink) { - viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); - viz::SurfaceId id2 = CreateSurface(kFrameSink2, 1); - viz::SurfaceId id3 = CreateSurface(kFrameSink3, 1); +TEST_F(SurfaceReferencesTest, NewSurfaceFromFrameSink) { + SurfaceId id1 = CreateSurface(kFrameSink1, 1); + SurfaceId id2 = CreateSurface(kFrameSink2, 1); + SurfaceId id3 = CreateSurface(kFrameSink3, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), id1); AddSurfaceReference(id1, id2); @@ -168,7 +171,7 @@ // |kFramesink2| received a CompositorFrame with a new size, so it destroys // |id2| and creates |id2_next|. No reference have been removed yet. - viz::SurfaceId id2_next = CreateSurface(kFrameSink2, 2); + SurfaceId id2_next = CreateSurface(kFrameSink2, 2); EXPECT_NE(nullptr, GetSurfaceManager().GetSurfaceForId(id2)); EXPECT_NE(nullptr, GetSurfaceManager().GetSurfaceForId(id2_next)); @@ -190,10 +193,10 @@ EXPECT_NE(nullptr, GetSurfaceManager().GetSurfaceForId(id3)); } -TEST_F(SurfaceManagerRefTest, ReferenceCycleGetsDeleted) { - viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); - viz::SurfaceId id2 = CreateSurface(kFrameSink2, 1); - viz::SurfaceId id3 = CreateSurface(kFrameSink3, 1); +TEST_F(SurfaceReferencesTest, ReferenceCycleGetsDeleted) { + SurfaceId id1 = CreateSurface(kFrameSink1, 1); + SurfaceId id2 = CreateSurface(kFrameSink2, 1); + SurfaceId id3 = CreateSurface(kFrameSink3, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), id1); AddSurfaceReference(id1, id2); @@ -215,9 +218,9 @@ EXPECT_EQ(nullptr, GetSurfaceManager().GetSurfaceForId(id3)); } -TEST_F(SurfaceManagerRefTest, SurfacesAreDeletedDuringGarbageCollection) { - viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); - viz::SurfaceId id2 = CreateSurface(kFrameSink2, 1); +TEST_F(SurfaceReferencesTest, SurfacesAreDeletedDuringGarbageCollection) { + SurfaceId id1 = CreateSurface(kFrameSink1, 1); + SurfaceId id2 = CreateSurface(kFrameSink2, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), id1); AddSurfaceReference(id1, id2); @@ -241,10 +244,10 @@ EXPECT_EQ(nullptr, GetSurfaceManager().GetSurfaceForId(id1)); } -TEST_F(SurfaceManagerRefTest, GarbageCollectionWorksRecusively) { - viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); - viz::SurfaceId id2 = CreateSurface(kFrameSink2, 1); - viz::SurfaceId id3 = CreateSurface(kFrameSink3, 1); +TEST_F(SurfaceReferencesTest, GarbageCollectionWorksRecusively) { + SurfaceId id1 = CreateSurface(kFrameSink1, 1); + SurfaceId id2 = CreateSurface(kFrameSink2, 1); + SurfaceId id3 = CreateSurface(kFrameSink3, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), id1); AddSurfaceReference(id1, id2); @@ -269,9 +272,9 @@ EXPECT_EQ(nullptr, GetSurfaceManager().GetSurfaceForId(id3)); } -TEST_F(SurfaceManagerRefTest, TryAddReferenceSameReferenceTwice) { - viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); - viz::SurfaceId id2 = CreateSurface(kFrameSink2, 1); +TEST_F(SurfaceReferencesTest, TryAddReferenceSameReferenceTwice) { + SurfaceId id1 = CreateSurface(kFrameSink1, 1); + SurfaceId id2 = CreateSurface(kFrameSink2, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), id1); AddSurfaceReference(id1, id2); @@ -284,8 +287,8 @@ EXPECT_THAT(GetReferencesFrom(id1), SizeIs(1)); } -TEST_F(SurfaceManagerRefTest, AddingSelfReferenceFails) { - viz::SurfaceId id1 = CreateSurface(kFrameSink2, 1); +TEST_F(SurfaceReferencesTest, AddingSelfReferenceFails) { + SurfaceId id1 = CreateSurface(kFrameSink2, 1); // A temporary reference must exist to |id1|. EXPECT_THAT(GetAllTempReferences(), ElementsAre(id1)); @@ -302,9 +305,9 @@ EXPECT_THAT(GetReferencesFor(id1), IsEmpty()); } -TEST_F(SurfaceManagerRefTest, RemovingNonexistantReferenceFails) { - viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); - viz::SurfaceId id2 = CreateSurface(kFrameSink2, 1); +TEST_F(SurfaceReferencesTest, RemovingNonexistantReferenceFails) { + SurfaceId id1 = CreateSurface(kFrameSink1, 1); + SurfaceId id2 = CreateSurface(kFrameSink2, 1); // Removing non-existent reference should be ignored. AddSurfaceReference(id1, id2); @@ -313,15 +316,15 @@ EXPECT_THAT(GetReferencesFor(id2), SizeIs(1)); } -TEST_F(SurfaceManagerRefTest, AddSurfaceThenReference) { +TEST_F(SurfaceReferencesTest, AddSurfaceThenReference) { // Create a new surface. - const viz::SurfaceId surface_id = CreateSurface(kFrameSink2, 1); + const SurfaceId surface_id = CreateSurface(kFrameSink2, 1); // A temporary reference must be added to |surface_id|. EXPECT_THAT(GetAllTempReferences(), ElementsAre(surface_id)); // Create |parent_id| and add a real reference from it to |surface_id|. - const viz::SurfaceId parent_id = CreateSurface(kFrameSink1, 1); + const SurfaceId parent_id = CreateSurface(kFrameSink1, 1); AddSurfaceReference(parent_id, surface_id); // The temporary reference to |surface_id| should be gone. @@ -331,9 +334,9 @@ EXPECT_THAT(GetReferencesFrom(parent_id), ElementsAre(surface_id)); } -TEST_F(SurfaceManagerRefTest, AddSurfaceThenRootReference) { +TEST_F(SurfaceReferencesTest, AddSurfaceThenRootReference) { // Create a new surface. - const viz::SurfaceId surface_id = CreateSurface(kFrameSink1, 1); + const SurfaceId surface_id = CreateSurface(kFrameSink1, 1); // Temporary reference should be added to |surface_id|. EXPECT_THAT(GetAllTempReferences(), ElementsAre(surface_id)); @@ -348,17 +351,17 @@ ElementsAre(surface_id)); } -TEST_F(SurfaceManagerRefTest, AddTwoSurfacesThenOneReference) { +TEST_F(SurfaceReferencesTest, AddTwoSurfacesThenOneReference) { // Create two surfaces with different FrameSinkIds. - const viz::SurfaceId surface_id1 = CreateSurface(kFrameSink2, 1); - const viz::SurfaceId surface_id2 = CreateSurface(kFrameSink3, 1); + const SurfaceId surface_id1 = CreateSurface(kFrameSink2, 1); + const SurfaceId surface_id2 = CreateSurface(kFrameSink3, 1); // Temporary reference should be added for both surfaces. EXPECT_THAT(GetAllTempReferences(), UnorderedElementsAre(surface_id1, surface_id2)); // Create |parent_id| and add a real reference from it to |surface_id1|. - const viz::SurfaceId parent_id = CreateSurface(kFrameSink1, 1); + const SurfaceId parent_id = CreateSurface(kFrameSink1, 1); AddSurfaceReference(parent_id, surface_id1); // Real reference must be added to |surface_id1| and the temporary reference @@ -370,12 +373,12 @@ EXPECT_THAT(GetReferencesFrom(parent_id), ElementsAre(surface_id1)); } -TEST_F(SurfaceManagerRefTest, AddSurfacesSkipReference) { - // Add two surfaces that have the same viz::FrameSinkId. This would happen +TEST_F(SurfaceReferencesTest, AddSurfacesSkipReference) { + // Add two surfaces that have the same FrameSinkId. This would happen // when a client submits two CompositorFrames before parent submits a new // CompositorFrame. - const viz::SurfaceId surface_id1 = CreateSurface(kFrameSink2, 2); - const viz::SurfaceId surface_id2 = CreateSurface(kFrameSink2, 1); + const SurfaceId surface_id1 = CreateSurface(kFrameSink2, 2); + const SurfaceId surface_id2 = CreateSurface(kFrameSink2, 1); // Temporary references should be added for both surfaces and they should be // stored in the order of creation. @@ -384,7 +387,7 @@ // Create |parent_id| and add a reference from it to |surface_id2| which was // created later. - const viz::SurfaceId parent_id = CreateSurface(kFrameSink1, 1); + const SurfaceId parent_id = CreateSurface(kFrameSink1, 1); AddSurfaceReference(parent_id, surface_id2); // The real reference should be added for |surface_id2| and the temporary @@ -394,11 +397,11 @@ EXPECT_THAT(GetReferencesFrom(parent_id), ElementsAre(surface_id2)); } -TEST_F(SurfaceManagerRefTest, RemoveFirstTempReferenceOnly) { - // Add two surfaces that have the same viz::FrameSinkId. This would happen +TEST_F(SurfaceReferencesTest, RemoveFirstTempReferenceOnly) { + // Add two surfaces that have the same FrameSinkId. This would happen // when a client submits two CFs before parent submits a new CF. - const viz::SurfaceId surface_id1 = CreateSurface(kFrameSink2, 1); - const viz::SurfaceId surface_id2 = CreateSurface(kFrameSink2, 2); + const SurfaceId surface_id1 = CreateSurface(kFrameSink2, 1); + const SurfaceId surface_id2 = CreateSurface(kFrameSink2, 2); // Temporary references should be added for both surfaces and they should be // stored in the order of creation. @@ -407,7 +410,7 @@ // Create |parent_id| and add a reference from it to |surface_id1| which was // created earlier. - const viz::SurfaceId parent_id = CreateSurface(kFrameSink1, 1); + const SurfaceId parent_id = CreateSurface(kFrameSink1, 1); AddSurfaceReference(parent_id, surface_id1); // The real reference should be added for |surface_id1| and its temporary @@ -418,13 +421,13 @@ EXPECT_THAT(GetReferencesFrom(parent_id), ElementsAre(surface_id1)); } -TEST_F(SurfaceManagerRefTest, SurfaceWithTemporaryReferenceIsNotDeleted) { - const viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); +TEST_F(SurfaceReferencesTest, SurfaceWithTemporaryReferenceIsNotDeleted) { + const SurfaceId id1 = CreateSurface(kFrameSink1, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), id1); // We create |id2| and never add a real reference to it. This leaves the // temporary reference. - const viz::SurfaceId id2 = CreateSurface(kFrameSink2, 1); + const SurfaceId id2 = CreateSurface(kFrameSink2, 1); ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id2)); EXPECT_NE(nullptr, GetSurfaceManager().GetSurfaceForId(id2)); @@ -443,9 +446,9 @@ // Checks that when a temporary reference is assigned an owner, if the owner is // invalidated then the temporary reference is also removed. -TEST_F(SurfaceManagerRefTest, InvalidateTempReferenceOwnerRemovesReference) { +TEST_F(SurfaceReferencesTest, InvalidateTempReferenceOwnerRemovesReference) { // Surface |id1| should have a temporary reference on creation. - const viz::SurfaceId id1 = CreateSurface(kFrameSink2, 1); + const SurfaceId id1 = CreateSurface(kFrameSink2, 1); ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1)); // |id1| should have a temporary reference after an owner is assigned. @@ -459,11 +462,11 @@ // Checks that adding a surface reference clears the temporary reference and // ownership. Invalidating the old owner shouldn't do anything. -TEST_F(SurfaceManagerRefTest, InvalidateHasNoEffectOnSurfaceReferences) { - const viz::SurfaceId parent_id = CreateSurface(kFrameSink1, 1); +TEST_F(SurfaceReferencesTest, InvalidateHasNoEffectOnSurfaceReferences) { + const SurfaceId parent_id = CreateSurface(kFrameSink1, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), parent_id); - const viz::SurfaceId id1 = CreateSurface(kFrameSink2, 1); + const SurfaceId id1 = CreateSurface(kFrameSink2, 1); GetSurfaceManager().AssignTemporaryReference(id1, kFrameSink1); ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1)); @@ -478,8 +481,8 @@ ASSERT_THAT(GetReferencesFor(id1), UnorderedElementsAre(parent_id)); } -TEST_F(SurfaceManagerRefTest, CheckDropTemporaryReferenceWorks) { - const viz::SurfaceId id1 = CreateSurface(kFrameSink1, 1); +TEST_F(SurfaceReferencesTest, CheckDropTemporaryReferenceWorks) { + const SurfaceId id1 = CreateSurface(kFrameSink1, 1); ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1)); // An example of why this could happen is the window server doesn't know the @@ -492,12 +495,12 @@ // Checks that we handle ownership and temporary references correctly when there // are multiple temporary references. This tests something like the parent // client crashing, so it's -TEST_F(SurfaceManagerRefTest, TempReferencesWithClientCrash) { - const viz::SurfaceId parent_id = CreateSurface(kFrameSink1, 1); +TEST_F(SurfaceReferencesTest, TempReferencesWithClientCrash) { + const SurfaceId parent_id = CreateSurface(kFrameSink1, 1); AddSurfaceReference(GetSurfaceManager().GetRootSurfaceId(), parent_id); - const viz::SurfaceId id1a = CreateSurface(kFrameSink2, 1); - const viz::SurfaceId id1b = CreateSurface(kFrameSink2, 2); + const SurfaceId id1a = CreateSurface(kFrameSink2, 1); + const SurfaceId id1b = CreateSurface(kFrameSink2, 2); ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1a, id1b)); @@ -507,7 +510,7 @@ ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1a, id1b)); // If the parent client crashes then the FrameSink connection will be closed - // and the viz::FrameSinkId invalidated. The temporary reference |kFrameSink1| + // and the FrameSinkId invalidated. The temporary reference |kFrameSink1| // owns to |id2a| will be removed. DestroyCompositorFrameSinkSupport(kFrameSink1); ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1b)); @@ -519,4 +522,5 @@ ASSERT_THAT(GetAllTempReferences(), IsEmpty()); } -} // namespace cc +} // namespace test +} // namespace viz
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc index c1708a1..a6f60dbe 100644 --- a/components/viz/test/test_layer_tree_frame_sink.cc +++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -22,8 +22,8 @@ static constexpr FrameSinkId kLayerTreeFrameSinkId(1, 1); TestLayerTreeFrameSink::TestLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> compositor_context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider, SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const cc::RendererSettings& renderer_settings,
diff --git a/components/viz/test/test_layer_tree_frame_sink.h b/components/viz/test/test_layer_tree_frame_sink.h index 5ee1e80..e78b3d22 100644 --- a/components/viz/test/test_layer_tree_frame_sink.h +++ b/components/viz/test/test_layer_tree_frame_sink.h
@@ -35,7 +35,7 @@ // This passes the ContextProvider being used by LayerTreeHostImpl which // can be used for the OutputSurface optionally. virtual std::unique_ptr<cc::OutputSurface> CreateDisplayOutputSurface( - scoped_refptr<cc::ContextProvider> compositor_context_provider) = 0; + scoped_refptr<ContextProvider> compositor_context_provider) = 0; virtual void DisplayReceivedLocalSurfaceId( const LocalSurfaceId& local_surface_id) = 0; @@ -56,8 +56,8 @@ // Pass true for |force_disable_reclaim_resources| to act like the Display // is out-of-process and can't return resources synchronously. TestLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> compositor_context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider, SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const cc::RendererSettings& renderer_settings,
diff --git a/content/browser/blob_storage/blob_dispatcher_host.cc b/content/browser/blob_storage/blob_dispatcher_host.cc index bea813d..dd7209c 100644 --- a/content/browser/blob_storage/blob_dispatcher_host.cc +++ b/content/browser/blob_storage/blob_dispatcher_host.cc
@@ -7,12 +7,14 @@ #include <algorithm> #include "base/bind.h" +#include "base/feature_list.h" #include "base/metrics/histogram_macros.h" #include "content/browser/bad_message.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/fileapi/browser_file_system_helper.h" #include "content/common/fileapi/webblob_messages.h" +#include "content/public/common/content_features.h" #include "ipc/ipc_platform_file.h" #include "storage/browser/blob/blob_data_handle.h" #include "storage/browser/blob/blob_entry.h" @@ -355,7 +357,12 @@ } bool BlobDispatcherHost::IsInUseInHost(const std::string& uuid) { - return base::ContainsKey(blobs_inuse_map_, uuid); + // IsInUseInHost is not a security check, as renderers can arbitrarily start + // using blobs by sending an IncrementRefCount IPC. Furthermore with mojo + // blobs it doesn't make sense anymore to try to decide if a blob is in use in + // a process, so just always return true in that case. + return base::FeatureList::IsEnabled(features::kMojoBlobs) || + base::ContainsKey(blobs_inuse_map_, uuid); } bool BlobDispatcherHost::IsUrlRegisteredInHost(const GURL& blob_url) {
diff --git a/content/browser/blob_storage/blob_storage_browsertest.cc b/content/browser/blob_storage/blob_storage_browsertest.cc index ac516a8..9296e86 100644 --- a/content/browser/blob_storage/blob_storage_browsertest.cc +++ b/content/browser/blob_storage/blob_storage_browsertest.cc
@@ -3,11 +3,13 @@ // found in the LICENSE file. #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/sequenced_worker_pool.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" @@ -103,4 +105,36 @@ RunAllBlockingPoolTasksUntilIdle(); } +class MojoBlobStorageBrowserTest : public BlobStorageBrowserTest { + public: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature(features::kMojoBlobs); + BlobStorageBrowserTest::SetUp(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(MojoBlobStorageBrowserTest, BlobCombinations) { + SetBlobLimits(); + SimpleTest(GetTestUrl("blob_storage", "blob_creation_and_slicing.html")); + storage::BlobMemoryController* memory_controller = GetMemoryController(); + ASSERT_TRUE(memory_controller); + // Our exact usages depend on IPC message ordering & garbage collection. + // Since this is basically random, we just check bounds. + EXPECT_LT(0u, memory_controller->memory_usage()); + EXPECT_LT(0ul, memory_controller->disk_usage()); + EXPECT_GT(memory_controller->disk_usage(), + static_cast<uint64_t>(memory_controller->memory_usage())); + EXPECT_GT(limits_.max_blob_in_memory_space, + memory_controller->memory_usage()); + EXPECT_GT(limits_.effective_max_disk_space, memory_controller->disk_usage()); + shell()->Close(); + + // Make sure we run all file / io tasks. + base::RunLoop().RunUntilIdle(); + RunAllBlockingPoolTasksUntilIdle(); +} + } // namespace content
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 5d8124c..0c48b7f0 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -875,6 +875,16 @@ RenderProcessHost::SetRunRendererInProcess(true); #endif + // Initialize origins that are whitelisted for process isolation. Must be + // done after base::FeatureList is initialized, but before any navigations + // can happen. + std::vector<url::Origin> origins = + GetContentClient()->browser()->GetOriginsRequiringDedicatedProcess(); + ChildProcessSecurityPolicyImpl* policy = + ChildProcessSecurityPolicyImpl::GetInstance(); + for (auto origin : origins) + policy->AddIsolatedOrigin(origin); + EVP_set_buggy_rsa_parser( base::FeatureList::IsEnabled(features::kBuggyRSAParser));
diff --git a/content/browser/compositor/browser_compositor_output_surface.cc b/content/browser/compositor/browser_compositor_output_surface.cc index cdf87e5..888ceb4 100644 --- a/content/browser/compositor/browser_compositor_output_surface.cc +++ b/content/browser/compositor/browser_compositor_output_surface.cc
@@ -20,7 +20,7 @@ namespace content { BrowserCompositorOutputSurface::BrowserCompositorOutputSurface( - scoped_refptr<cc::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, const UpdateVSyncParametersCallback& update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator)
diff --git a/content/browser/compositor/browser_compositor_output_surface.h b/content/browser/compositor/browser_compositor_output_surface.h index 84d56910d1..fabf348 100644 --- a/content/browser/compositor/browser_compositor_output_surface.h +++ b/content/browser/compositor/browser_compositor_output_surface.h
@@ -50,7 +50,7 @@ protected: // Constructor used by the accelerated implementation. BrowserCompositorOutputSurface( - scoped_refptr<cc::ContextProvider> context, + scoped_refptr<viz::ContextProvider> context, const UpdateVSyncParametersCallback& update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator);
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index 2e19825..7492ff0 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -104,7 +104,7 @@ #include "content/browser/compositor/vulkan_browser_compositor_output_surface.h" #endif -using cc::ContextProvider; +using viz::ContextProvider; using gpu::gles2::GLES2Interface; namespace { @@ -830,8 +830,7 @@ viz::GLHelper* GpuProcessTransportFactory::GetGLHelper() { if (!gl_helper_ && !per_compositor_data_.empty()) { - scoped_refptr<cc::ContextProvider> provider = - SharedMainThreadContextProvider(); + scoped_refptr<ContextProvider> provider = SharedMainThreadContextProvider(); if (provider.get()) gl_helper_.reset( new viz::GLHelper(provider->ContextGL(), provider->ContextSupport())); @@ -859,7 +858,7 @@ } #endif -scoped_refptr<cc::ContextProvider> +scoped_refptr<ContextProvider> GpuProcessTransportFactory::SharedMainThreadContextProvider() { if (shared_main_thread_contexts_) return shared_main_thread_contexts_; @@ -934,7 +933,7 @@ // new resources are created if needed. // Kill shared contexts for both threads in tandem so they are always in // the same share group. - scoped_refptr<cc::ContextProvider> lost_shared_main_thread_contexts = + scoped_refptr<ContextProvider> lost_shared_main_thread_contexts = shared_main_thread_contexts_; shared_main_thread_contexts_ = NULL;
diff --git a/content/browser/compositor/gpu_process_transport_factory.h b/content/browser/compositor/gpu_process_transport_factory.h index f209923..52175d0 100644 --- a/content/browser/compositor/gpu_process_transport_factory.h +++ b/content/browser/compositor/gpu_process_transport_factory.h
@@ -54,7 +54,8 @@ // ui::ContextFactory implementation. void CreateLayerTreeFrameSink( base::WeakPtr<ui::Compositor> compositor) override; - scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider() override; + scoped_refptr<viz::ContextProvider> SharedMainThreadContextProvider() + override; double GetRefreshRate() const override; gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override; cc::TaskGraphRunner* GetTaskGraphRunner() override;
diff --git a/content/browser/compositor/image_transport_factory_browsertest.cc b/content/browser/compositor/image_transport_factory_browsertest.cc index 4042b70..768d897 100644 --- a/content/browser/compositor/image_transport_factory_browsertest.cc +++ b/content/browser/compositor/image_transport_factory_browsertest.cc
@@ -6,7 +6,7 @@ #include "base/run_loop.h" #include "build/build_config.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "content/browser/compositor/owned_mailbox.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/test/content_browser_test.h"
diff --git a/content/browser/compositor/reflector_impl_unittest.cc b/content/browser/compositor/reflector_impl_unittest.cc index f1879dd8..cb14b1c 100644 --- a/content/browser/compositor/reflector_impl_unittest.cc +++ b/content/browser/compositor/reflector_impl_unittest.cc
@@ -78,7 +78,7 @@ class TestOutputSurface : public BrowserCompositorOutputSurface { public: - TestOutputSurface(scoped_refptr<cc::ContextProvider> context_provider) + TestOutputSurface(scoped_refptr<viz::ContextProvider> context_provider) : BrowserCompositorOutputSurface(std::move(context_provider), UpdateVSyncParametersCallback(), CreateTestValidatorOzone()) {}
diff --git a/content/browser/compositor/reflector_texture.cc b/content/browser/compositor/reflector_texture.cc index 5301a3a..35dcfff 100644 --- a/content/browser/compositor/reflector_texture.cc +++ b/content/browser/compositor/reflector_texture.cc
@@ -12,7 +12,7 @@ namespace content { -ReflectorTexture::ReflectorTexture(cc::ContextProvider* context_provider) +ReflectorTexture::ReflectorTexture(viz::ContextProvider* context_provider) : texture_id_(0) { viz::GLHelper* shared_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
diff --git a/content/browser/compositor/reflector_texture.h b/content/browser/compositor/reflector_texture.h index a111b6fa..d5531a36 100644 --- a/content/browser/compositor/reflector_texture.h +++ b/content/browser/compositor/reflector_texture.h
@@ -14,16 +14,13 @@ #include "content/browser/compositor/owned_mailbox.h" #include "content/common/content_export.h" -namespace cc { -class ContextProvider; -} - namespace gfx { class Rect; class Size; } namespace viz { +class ContextProvider; class GLHelper; } @@ -32,7 +29,7 @@ // Create and manages texture mailbox to be used by Reflector. class CONTENT_EXPORT ReflectorTexture { public: - explicit ReflectorTexture(cc::ContextProvider* provider); + explicit ReflectorTexture(viz::ContextProvider* provider); ~ReflectorTexture(); void CopyTextureFullImage(const gfx::Size& size);
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.cc b/content/browser/compositor/test/no_transport_image_transport_factory.cc index cc12f631..e579b158 100644 --- a/content/browser/compositor/test/no_transport_image_transport_factory.cc +++ b/content/browser/compositor/test/no_transport_image_transport_factory.cc
@@ -9,9 +9,9 @@ #include "base/memory/ptr_util.h" #include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" -#include "cc/output/context_provider.h" #include "cc/surfaces/surface_manager.h" #include "components/viz/common/gl_helper.h" +#include "components/viz/common/gpu/context_provider.h" #include "content/browser/compositor/surface_utils.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "ui/compositor/compositor.h"
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.h b/content/browser/compositor/test/no_transport_image_transport_factory.h index e0e3766..17a8688 100644 --- a/content/browser/compositor/test/no_transport_image_transport_factory.h +++ b/content/browser/compositor/test/no_transport_image_transport_factory.h
@@ -15,14 +15,14 @@ #include "content/browser/compositor/image_transport_factory.h" #include "ui/compositor/test/in_process_context_factory.h" -namespace cc { -class ContextProvider; -} - namespace ui { class InProcessContextFactory; } +namespace viz { +class ContextProvider; +} + namespace content { // An ImageTransportFactory that disables transport. @@ -47,7 +47,7 @@ viz::FrameSinkManagerImpl frame_sink_manager_; viz::HostFrameSinkManager host_frame_sink_manager_; ui::InProcessContextFactory context_factory_; - scoped_refptr<cc::ContextProvider> context_provider_; + scoped_refptr<viz::ContextProvider> context_provider_; std::unique_ptr<viz::GLHelper> gl_helper_; DISALLOW_COPY_AND_ASSIGN(NoTransportImageTransportFactory);
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 7e78825..8e8aac3b 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -66,7 +66,8 @@ background_color_(SK_ColorWHITE), weak_factory_(this) { if (!service_manager::ServiceManagerIsRemote()) { - GetFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_); + GetFrameSinkManager()->surface_manager()->RegisterFrameSinkId( + frame_sink_id_); CreateCompositorFrameSinkSupport(); } } @@ -74,8 +75,10 @@ RenderWidgetHostViewChildFrame::~RenderWidgetHostViewChildFrame() { if (!service_manager::ServiceManagerIsRemote()) { ResetCompositorFrameSinkSupport(); - if (GetFrameSinkManager()) - GetFrameSinkManager()->InvalidateFrameSinkId(frame_sink_id_); + if (GetFrameSinkManager()) { + GetFrameSinkManager()->surface_manager()->InvalidateFrameSinkId( + frame_sink_id_); + } } }
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index ae765ed..4f18ae6 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -32,7 +32,6 @@ #include "cc/input/input_handler.h" #include "cc/layers/layer.h" #include "cc/output/compositor_frame.h" -#include "cc/output/context_provider.h" #include "cc/output/output_surface.h" #include "cc/output/output_surface_client.h" #include "cc/output/output_surface_frame.h" @@ -43,6 +42,7 @@ #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "components/viz/common/gl_helper.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/display/display.h" @@ -465,7 +465,7 @@ num_successive_context_creation_failures_(0), layer_tree_frame_sink_request_pending_(false), weak_factory_(this) { - GetFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_); + GetFrameSinkManager()->surface_manager()->RegisterFrameSinkId(frame_sink_id_); DCHECK(client); DCHECK(root_window); DCHECK(root_window->GetLayer() == nullptr); @@ -483,7 +483,8 @@ root_window_->SetLayer(nullptr); // Clean-up any surface references. SetSurface(NULL); - GetFrameSinkManager()->InvalidateFrameSinkId(frame_sink_id_); + GetFrameSinkManager()->surface_manager()->InvalidateFrameSinkId( + frame_sink_id_); } bool CompositorImpl::IsForSubframe() { @@ -783,7 +784,7 @@ shared_context, ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT); if (!context_provider->BindToCurrentThread()) { - LOG(ERROR) << "Failed to init ContextProvider for compositor."; + LOG(ERROR) << "Failed to init viz::ContextProvider for compositor."; LOG_IF(FATAL, ++num_successive_context_creation_failures_ >= 2) << "Too many context creation failures. Giving up... "; HandlePendingLayerTreeFrameSinkRequest(); @@ -801,7 +802,7 @@ void CompositorImpl::InitializeDisplay( std::unique_ptr<cc::OutputSurface> display_output_surface, scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider, - scoped_refptr<cc::ContextProvider> context_provider) { + scoped_refptr<viz::ContextProvider> context_provider) { DCHECK(layer_tree_frame_sink_request_pending_); pending_frames_ = 0;
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 98c6c16..b55dc2a 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -134,7 +134,7 @@ void InitializeDisplay( std::unique_ptr<cc::OutputSurface> display_output_surface, scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider, - scoped_refptr<cc::ContextProvider> context_provider); + scoped_refptr<viz::ContextProvider> context_provider); void DidSwapBuffers(); bool HavePendingReadbacks();
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index a27268b..44a3a36 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -56,6 +56,7 @@ factory->GetContextFactory()->AddObserver(this); factory->GetContextFactoryPrivate() ->GetFrameSinkManager() + ->surface_manager() ->RegisterFrameSinkId(frame_sink_id_); CreateCompositorFrameSinkSupport(); } @@ -768,6 +769,7 @@ factory->GetContextFactoryPrivate() ->GetFrameSinkManager() + ->surface_manager() ->InvalidateFrameSinkId(frame_sink_id_); DCHECK(!vsync_manager_.get());
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index 069e484..31e7f8e 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -45,6 +45,7 @@ "shape_detection::mojom::FaceDetectionProvider", "resource_coordinator::mojom::CoordinationUnit", "shape_detection::mojom::TextDetection", + "storage::mojom::BlobRegistry", "ui::mojom::Gpu" ], "geolocation_config": [
diff --git a/content/public/browser/android/compositor.h b/content/public/browser/android/compositor.h index 42213059..618bbf5 100644 --- a/content/public/browser/android/compositor.h +++ b/content/public/browser/android/compositor.h
@@ -15,7 +15,6 @@ #include "ui/gfx/native_widget_types.h" namespace cc { -class ContextProvider; class Layer; } @@ -32,6 +31,10 @@ class UIResourceProvider; } +namespace viz { +class ContextProvider; +} + namespace content { class CompositorClient; @@ -47,7 +50,7 @@ // Creates a GL context for the provided |handle|. If a null handle is passed, // an offscreen context is created. This must be called on the UI thread. using ContextProviderCallback = - base::Callback<void(scoped_refptr<cc::ContextProvider>)>; + base::Callback<void(scoped_refptr<viz::ContextProvider>)>; static void CreateContextProvider( gpu::SurfaceHandle handle, gpu::gles2::ContextCreationAttribHelper attributes,
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index e32549dd..5193ae1 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -23,6 +23,7 @@ #include "storage/browser/quota/quota_manager.h" #include "ui/gfx/image/image_skia.h" #include "url/gurl.h" +#include "url/origin.h" namespace content { @@ -139,6 +140,11 @@ return true; } +std::vector<url::Origin> +ContentBrowserClient::GetOriginsRequiringDedicatedProcess() { + return std::vector<url::Origin>(); +} + std::string ContentBrowserClient::GetApplicationLocale() { return "en-US"; }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 41cd656e..7cd8c69b 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -310,6 +310,10 @@ // current SiteInstance, if it does not yet have a site. virtual bool ShouldAssignSiteForURL(const GURL& url); + // Allows the embedder to provide a list of origins that require a dedicated + // process. + virtual std::vector<url::Origin> GetOriginsRequiringDedicatedProcess(); + // Allows the embedder to pass extra command line flags. // switches::kProcessType will already be set at this point. virtual void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 4c4ce6e..88b0b0f 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -265,6 +265,11 @@ const base::Feature kSharedArrayBuffer{"SharedArrayBuffer", base::FEATURE_ENABLED_BY_DEFAULT}; +// An experiment to require process isolation for the sign-in origin, +// https://accounts.google.com. Launch bug: https://crbug.com/739418. +const base::Feature kSignInProcessIsolation{"sign-in-process-isolation", + base::FEATURE_DISABLED_BY_DEFAULT}; + // An experiment for skipping compositing small scrollers. const base::Feature kSkipCompositingSmallScrollers{ "SkipCompositingSmallScrollers", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 1c49647..ea57fb06 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -71,6 +71,7 @@ CONTENT_EXPORT extern const base::Feature kServiceWorkerNavigationPreload; CONTENT_EXPORT extern const base::Feature kServiceWorkerScriptStreaming; CONTENT_EXPORT extern const base::Feature kSharedArrayBuffer; +CONTENT_EXPORT extern const base::Feature kSignInProcessIsolation; CONTENT_EXPORT extern const base::Feature kSkipCompositingSmallScrollers; CONTENT_EXPORT extern const base::Feature kSlimmingPaintInvalidation; CONTENT_EXPORT extern const base::Feature kTimerThrottlingForHiddenFrames;
diff --git a/content/renderer/DEPS b/content/renderer/DEPS index a77566d..ba452da 100644 --- a/content/renderer/DEPS +++ b/content/renderer/DEPS
@@ -10,7 +10,6 @@ "+components/variations/child_process_field_trial_syncer.h", "+components/viz/client", "+components/viz/common", - "+cc/blink", "+content/public/child", "+content/public/renderer",
diff --git a/content/renderer/android/DEPS b/content/renderer/android/DEPS index 3f8f3da..c6c21da5 100644 --- a/content/renderer/android/DEPS +++ b/content/renderer/android/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/viz/common/gpu", "+components/viz/service/display", "+components/viz/service/frame_sinks", "+third_party/libphonenumber", # For phone number detection.
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.cc b/content/renderer/android/synchronous_layer_tree_frame_sink.cc index 63a7623..3707818 100644 --- a/content/renderer/android/synchronous_layer_tree_frame_sink.cc +++ b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -14,7 +14,6 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "cc/output/compositor_frame.h" -#include "cc/output/context_provider.h" #include "cc/output/layer_tree_frame_sink_client.h" #include "cc/output/output_surface.h" #include "cc/output/output_surface_frame.h" @@ -23,6 +22,7 @@ #include "cc/output/texture_mailbox_deleter.h" #include "cc/quads/render_pass.h" #include "cc/quads/surface_draw_quad.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/local_surface_id_allocator.h" #include "components/viz/service/display/display.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" @@ -106,8 +106,8 @@ }; SynchronousLayerTreeFrameSink::SynchronousLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<viz::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, viz::SharedBitmapManager* shared_bitmap_manager, int routing_id,
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.h b/content/renderer/android/synchronous_layer_tree_frame_sink.h index 3718d31..8a869c1 100644 --- a/content/renderer/android/synchronous_layer_tree_frame_sink.h +++ b/content/renderer/android/synchronous_layer_tree_frame_sink.h
@@ -27,7 +27,6 @@ namespace cc { class BeginFrameSource; -class ContextProvider; } // namespace cc namespace IPC { @@ -37,6 +36,7 @@ namespace viz { class CompositorFrameSinkSupport; +class ContextProvider; class Display; class FrameSinkManager; class LocalSurfaceIdAllocator; @@ -71,8 +71,8 @@ public viz::CompositorFrameSinkSupportClient { public: SynchronousLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<viz::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, viz::SharedBitmapManager* shared_bitmap_manager, int routing_id,
diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index 3192c99e..fde1f53 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc
@@ -10,11 +10,11 @@ #include "cc/layers/picture_image_layer.h" #include "cc/layers/solid_color_layer.h" #include "cc/layers/surface_layer.h" -#include "cc/output/context_provider.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/paint/paint_image.h" #include "cc/resources/single_release_callback.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "content/child/thread_safe_sender.h" #include "content/common/browser_plugin/browser_plugin_messages.h"
diff --git a/content/renderer/layout_test_dependencies.h b/content/renderer/layout_test_dependencies.h index df8feef..2367e4a6 100644 --- a/content/renderer/layout_test_dependencies.h +++ b/content/renderer/layout_test_dependencies.h
@@ -11,7 +11,6 @@ #include "base/memory/ref_counted.h" namespace cc { -class ContextProvider; class CopyOutputRequest; class LayerTreeFrameSink; class SwapPromise; @@ -22,6 +21,10 @@ class GpuMemoryBufferManager; } +namespace viz { +class ContextProvider; +} + namespace content { class CompositorDependencies; @@ -32,8 +35,8 @@ virtual std::unique_ptr<cc::LayerTreeFrameSink> CreateLayerTreeFrameSink( int32_t routing_id, scoped_refptr<gpu::GpuChannelHost> gpu_channel, - scoped_refptr<cc::ContextProvider> compositor_context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, CompositorDependencies* deps) = 0;
diff --git a/content/renderer/media/android/stream_texture_factory.cc b/content/renderer/media/android/stream_texture_factory.cc index fd8521e0..395455cd 100644 --- a/content/renderer/media/android/stream_texture_factory.cc +++ b/content/renderer/media/android/stream_texture_factory.cc
@@ -6,7 +6,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "cc/output/context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/ipc/client/command_buffer_proxy_impl.h" #include "gpu/ipc/client/gpu_channel_host.h"
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc index 3a48e80..a3972d1 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -11,7 +11,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/unguessable_token.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/resources/buffer_to_texture_target_map.h" #include "content/child/child_thread_impl.h" #include "content/public/common/service_names.mojom.h" @@ -98,7 +98,7 @@ if (context_provider_) { bool release_context_provider = false; { - cc::ContextProvider::ScopedContextLock lock(context_provider_); + viz::ContextProvider::ScopedContextLock lock(context_provider_); if (lock.ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { context_provider_ = nullptr; release_context_provider = true; @@ -181,7 +181,7 @@ if (CheckContextLost()) return false; - cc::ContextProvider::ScopedContextLock lock(context_provider_); + viz::ContextProvider::ScopedContextLock lock(context_provider_); gpu::gles2::GLES2Interface* gles2 = lock.ContextGL(); texture_ids->resize(count); texture_mailboxes->resize(count); @@ -217,14 +217,14 @@ if (CheckContextLost()) return; - cc::ContextProvider::ScopedContextLock lock(context_provider_); + viz::ContextProvider::ScopedContextLock lock(context_provider_); gpu::gles2::GLES2Interface* gles2 = lock.ContextGL(); gles2->DeleteTextures(1, &texture_id); DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); } gpu::SyncToken GpuVideoAcceleratorFactoriesImpl::CreateSyncToken() { - cc::ContextProvider::ScopedContextLock lock(context_provider_); + viz::ContextProvider::ScopedContextLock lock(context_provider_); gpu::gles2::GLES2Interface* gl = lock.ContextGL(); gpu::SyncToken sync_token; const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM(); @@ -239,7 +239,7 @@ if (CheckContextLost()) return; - cc::ContextProvider::ScopedContextLock lock(context_provider_); + viz::ContextProvider::ScopedContextLock lock(context_provider_); gpu::gles2::GLES2Interface* gles2 = lock.ContextGL(); gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); @@ -253,7 +253,7 @@ if (CheckContextLost()) return; - cc::ContextProvider::ScopedContextLock lock(context_provider_); + viz::ContextProvider::ScopedContextLock lock(context_provider_); gpu::gles2::GLES2Interface* gles2 = lock.ContextGL(); gles2->ShallowFlushCHROMIUM(); } @@ -286,7 +286,7 @@ DCHECK(task_runner_->BelongsToCurrentThread()); if (CheckContextLost()) return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED; - cc::ContextProvider::ScopedContextLock lock(context_provider_); + viz::ContextProvider::ScopedContextLock lock(context_provider_); auto capabilities = context_provider_->ContextCapabilities(); if (capabilities.image_ycbcr_420v) return media::GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB; @@ -301,12 +301,12 @@ class ScopedGLContextLockImpl : public media::GpuVideoAcceleratorFactories::ScopedGLContextLock { public: - ScopedGLContextLockImpl(cc::ContextProvider* context_provider) + ScopedGLContextLockImpl(viz::ContextProvider* context_provider) : lock_(context_provider) {} gpu::gles2::GLES2Interface* ContextGL() override { return lock_.ContextGL(); } private: - cc::ContextProvider::ScopedContextLock lock_; + viz::ContextProvider::ScopedContextLock lock_; }; } // namespace
diff --git a/content/renderer/mus/renderer_window_tree_client.cc b/content/renderer/mus/renderer_window_tree_client.cc index ec83c24..f10b79e 100644 --- a/content/renderer/mus/renderer_window_tree_client.cc +++ b/content/renderer/mus/renderer_window_tree_client.cc
@@ -50,7 +50,7 @@ } void RendererWindowTreeClient::RequestLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const LayerTreeFrameSinkCallback& callback) { DCHECK(pending_layer_tree_frame_sink_callback_.is_null()); @@ -74,7 +74,7 @@ } void RendererWindowTreeClient::RequestLayerTreeFrameSinkInternal( - scoped_refptr<cc::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const LayerTreeFrameSinkCallback& callback) { cc::mojom::CompositorFrameSinkPtrInfo sink_info;
diff --git a/content/renderer/mus/renderer_window_tree_client.h b/content/renderer/mus/renderer_window_tree_client.h index 63f61e2..89d618a 100644 --- a/content/renderer/mus/renderer_window_tree_client.h +++ b/content/renderer/mus/renderer_window_tree_client.h
@@ -12,13 +12,16 @@ namespace cc { class LayerTreeFrameSink; -class ContextProvider; } namespace gpu { class GpuMemoryBufferManager; } +namespace viz { +class ContextProvider; +} + namespace content { // ui.mojom.WindowTreeClient implementation for RenderWidget. This lives and @@ -43,7 +46,7 @@ using LayerTreeFrameSinkCallback = base::Callback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>; void RequestLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const LayerTreeFrameSinkCallback& callback); @@ -52,7 +55,7 @@ ~RendererWindowTreeClient() override; void RequestLayerTreeFrameSinkInternal( - scoped_refptr<cc::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const LayerTreeFrameSinkCallback& callback); @@ -160,7 +163,7 @@ const int routing_id_; ui::Id root_window_id_; - scoped_refptr<cc::ContextProvider> pending_context_provider_; + scoped_refptr<viz::ContextProvider> pending_context_provider_; gpu::GpuMemoryBufferManager* pending_gpu_memory_buffer_manager_ = nullptr; LayerTreeFrameSinkCallback pending_layer_tree_frame_sink_callback_; ui::mojom::WindowTreePtr tree_;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index e22d4f20..e0c03b8 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1413,7 +1413,7 @@ scoped_refptr<ui::ContextProviderCommandBuffer> shared_context_provider = gpu_factories_.back()->ContextProviderMainThread(); if (shared_context_provider) { - cc::ContextProvider::ScopedContextLock lock( + viz::ContextProvider::ScopedContextLock lock( shared_context_provider.get()); if (lock.ContextGL()->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { return gpu_factories_.back().get(); @@ -2390,7 +2390,7 @@ // Try to reuse existing shared worker context provider. if (shared_worker_context_provider_) { // Note: If context is lost, delete reference after releasing the lock. - cc::ContextProvider::ScopedContextLock lock( + viz::ContextProvider::ScopedContextLock lock( shared_worker_context_provider_.get()); if (shared_worker_context_provider_->ContextGL() ->GetGraphicsResetStatusKHR() == GL_NO_ERROR)
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index cf5b1b2..dc5d5dd4 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -334,8 +334,8 @@ std::unique_ptr<cc::LayerTreeFrameSink> CreateLayerTreeFrameSink( int32_t routing_id, scoped_refptr<gpu::GpuChannelHost> gpu_channel, - scoped_refptr<cc::ContextProvider> compositor_context_provider, - scoped_refptr<cc::ContextProvider> worker_context_provider, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, CompositorDependencies* deps) override { // This could override the GpuChannel for a LayerTreeFrameSink that was @@ -386,7 +386,8 @@ // TestLayerTreeFrameSinkClient implementation. std::unique_ptr<cc::OutputSurface> CreateDisplayOutputSurface( - scoped_refptr<cc::ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { // This is for an offscreen context for the compositor. So the default // framebuffer doesn't need alpha, depth, stencil, antialiasing. gpu::gles2::ContextCreationAttribHelper attributes;
diff --git a/content/test/test_render_view_host.cc b/content/test/test_render_view_host.cc index 0388136..5f16fa9 100644 --- a/content/test/test_render_view_host.cc +++ b/content/test/test_render_view_host.cc
@@ -69,12 +69,13 @@ background_color_(SK_ColorWHITE) { #if defined(OS_ANDROID) frame_sink_id_ = AllocateFrameSinkId(); - GetFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_); + GetFrameSinkManager()->surface_manager()->RegisterFrameSinkId(frame_sink_id_); #else // Not all tests initialize or need an image transport factory. if (ImageTransportFactory::GetInstance()) { frame_sink_id_ = AllocateFrameSinkId(); - GetFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_); + GetFrameSinkManager()->surface_manager()->RegisterFrameSinkId( + frame_sink_id_); } #endif @@ -91,7 +92,7 @@ TestRenderWidgetHostView::~TestRenderWidgetHostView() { viz::FrameSinkManager* manager = GetFrameSinkManager(); if (manager) { - manager->InvalidateFrameSinkId(frame_sink_id_); + manager->surface_manager()->InvalidateFrameSinkId(frame_sink_id_); } }
diff --git a/extensions/browser/api/lock_screen_data/lock_screen_item_storage.h b/extensions/browser/api/lock_screen_data/lock_screen_item_storage.h index b7d593b..88768e4 100644 --- a/extensions/browser/api/lock_screen_data/lock_screen_item_storage.h +++ b/extensions/browser/api/lock_screen_data/lock_screen_item_storage.h
@@ -131,6 +131,8 @@ ItemFactoryCallback* factory_callback, ItemStoreDeleter* deleter_callback); + const std::string& crypto_key_for_testing() const { return crypto_key_; } + private: // Maps a data item ID to the data item instance. using DataItemMap =
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 9e954a4..0632fc0a 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -244,25 +244,23 @@ content_watcher_(new ContentWatcher()), source_map_(&ResourceBundle::GetSharedInstance()), v8_schema_registry_(new V8SchemaRegistry), - ipc_message_sender_(IPCMessageSender::CreateMainThreadIPCMessageSender()), user_script_set_manager_observer_(this), activity_logging_enabled_(false) { const base::CommandLine& command_line = *(base::CommandLine::ForCurrentProcess()); + std::unique_ptr<IPCMessageSender> ipc_message_sender = + IPCMessageSender::CreateMainThreadIPCMessageSender(); if (FeatureSwitch::native_crx_bindings()->IsEnabled()) { // This Unretained is safe because the IPCMessageSender is guaranteed to // outlive the bindings system. auto system = base::MakeUnique<NativeExtensionBindingsSystem>( - base::Bind(&IPCMessageSender::SendRequestIPC, - base::Unretained(ipc_message_sender_.get())), - base::Bind(&SendEventListenersIPC)); + std::move(ipc_message_sender), base::Bind(&SendEventListenersIPC)); delegate_->InitializeBindingsSystem(this, system->api_system()); bindings_system_ = std::move(system); } else { bindings_system_ = base::MakeUnique<JsExtensionBindingsSystem>( - &source_map_, - base::MakeUnique<RequestSender>(ipc_message_sender_.get())); + &source_map_, std::move(ipc_message_sender)); } set_idle_notifications_ = @@ -648,7 +646,6 @@ const base::ListValue& response, const std::string& error) { bindings_system_->HandleResponse(request_id, success, response, error); - ipc_message_sender_->SendOnRequestResponseReceivedIPC(request_id); } void Dispatcher::DispatchEvent(const std::string& extension_id,
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h index 8b3763e6..25800fb 100644 --- a/extensions/renderer/dispatcher.h +++ b/extensions/renderer/dispatcher.h
@@ -56,7 +56,6 @@ class ContentWatcher; class DispatcherDelegate; class ExtensionBindingsSystem; -class IPCMessageSender; class ScriptContext; class ScriptInjectionManager; struct EventFilteringInfo; @@ -280,9 +279,6 @@ // Cache for the v8 representation of extension API schemas. std::unique_ptr<V8SchemaRegistry> v8_schema_registry_; - // A helper to dispatch event and request IPCs. - std::unique_ptr<IPCMessageSender> ipc_message_sender_; - // The bindings system associated with the main thread. std::unique_ptr<ExtensionBindingsSystem> bindings_system_;
diff --git a/extensions/renderer/extension_bindings_system.h b/extensions/renderer/extension_bindings_system.h index dc16a81..ff32b4a 100644 --- a/extensions/renderer/extension_bindings_system.h +++ b/extensions/renderer/extension_bindings_system.h
@@ -12,6 +12,7 @@ } namespace extensions { +class IPCMessageSender; class RequestSender; class ScriptContext; struct EventFilteringInfo; @@ -54,6 +55,9 @@ const base::ListValue& response, const std::string& error) = 0; + // Returns the associated IPC message sender. + virtual IPCMessageSender* GetIPCMessageSender() = 0; + // Returns the associated RequestSender, if any. // TODO(devlin): Factor this out. virtual RequestSender* GetRequestSender() = 0;
diff --git a/extensions/renderer/js_extension_bindings_system.cc b/extensions/renderer/js_extension_bindings_system.cc index de7e589..2e3b575 100644 --- a/extensions/renderer/js_extension_bindings_system.cc +++ b/extensions/renderer/js_extension_bindings_system.cc
@@ -5,6 +5,7 @@ #include "extensions/renderer/js_extension_bindings_system.h" #include "base/command_line.h" +#include "base/memory/ptr_util.h" #include "base/strings/string_split.h" #include "content/public/child/v8_value_converter.h" #include "content/public/common/content_switches.h" @@ -18,7 +19,9 @@ #include "extensions/common/manifest_handlers/externally_connectable.h" #include "extensions/renderer/binding_generating_native_handler.h" #include "extensions/renderer/event_bindings.h" +#include "extensions/renderer/ipc_message_sender.h" #include "extensions/renderer/renderer_extension_registry.h" +#include "extensions/renderer/request_sender.h" #include "extensions/renderer/resource_bundle_source_map.h" #include "extensions/renderer/script_context.h" #include "gin/converter.h" @@ -134,8 +137,11 @@ JsExtensionBindingsSystem::JsExtensionBindingsSystem( ResourceBundleSourceMap* source_map, - std::unique_ptr<RequestSender> request_sender) - : source_map_(source_map), request_sender_(std::move(request_sender)) {} + std::unique_ptr<IPCMessageSender> ipc_message_sender) + : source_map_(source_map), + ipc_message_sender_(std::move(ipc_message_sender)), + request_sender_( + base::MakeUnique<RequestSender>(ipc_message_sender_.get())) {} JsExtensionBindingsSystem::~JsExtensionBindingsSystem() {} @@ -224,12 +230,17 @@ const base::ListValue& response, const std::string& error) { request_sender_->HandleResponse(request_id, success, response, error); + ipc_message_sender_->SendOnRequestResponseReceivedIPC(request_id); } RequestSender* JsExtensionBindingsSystem::GetRequestSender() { return request_sender_.get(); } +IPCMessageSender* JsExtensionBindingsSystem::GetIPCMessageSender() { + return ipc_message_sender_.get(); +} + void JsExtensionBindingsSystem::DispatchEventInContext( const std::string& event_name, const base::ListValue* event_args,
diff --git a/extensions/renderer/js_extension_bindings_system.h b/extensions/renderer/js_extension_bindings_system.h index a51f36d..d9754167 100644 --- a/extensions/renderer/js_extension_bindings_system.h +++ b/extensions/renderer/js_extension_bindings_system.h
@@ -12,14 +12,14 @@ #include "extensions/renderer/extension_bindings_system.h" namespace extensions { -class RequestSender; +class IPCMessageSender; class ResourceBundleSourceMap; // The bindings system using the traditional JS-injection style bindings. class JsExtensionBindingsSystem : public ExtensionBindingsSystem { public: JsExtensionBindingsSystem(ResourceBundleSourceMap* source_map, - std::unique_ptr<RequestSender> request_sender); + std::unique_ptr<IPCMessageSender> request_sender); ~JsExtensionBindingsSystem() override; // ExtensionBindingsSystem: @@ -37,6 +37,7 @@ const base::ListValue& response, const std::string& error) override; RequestSender* GetRequestSender() override; + IPCMessageSender* GetIPCMessageSender() override; private: void RegisterBinding(const std::string& api_name, @@ -45,6 +46,8 @@ ResourceBundleSourceMap* source_map_ = nullptr; + std::unique_ptr<IPCMessageSender> ipc_message_sender_; + std::unique_ptr<RequestSender> request_sender_; DISALLOW_COPY_AND_ASSIGN(JsExtensionBindingsSystem);
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc index 750c20ef..b0b4727 100644 --- a/extensions/renderer/native_extension_bindings_system.cc +++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -21,6 +21,7 @@ #include "extensions/renderer/console.h" #include "extensions/renderer/content_setting.h" #include "extensions/renderer/declarative_content_hooks_delegate.h" +#include "extensions/renderer/ipc_message_sender.h" #include "extensions/renderer/module_system.h" #include "extensions/renderer/script_context.h" #include "extensions/renderer/script_context_set.h" @@ -349,9 +350,9 @@ } // namespace NativeExtensionBindingsSystem::NativeExtensionBindingsSystem( - const SendRequestIPCMethod& send_request_ipc, + std::unique_ptr<IPCMessageSender> ipc_message_sender, const SendEventListenerIPCMethod& send_event_listener_ipc) - : send_request_ipc_(send_request_ipc), + : ipc_message_sender_(std::move(ipc_message_sender)), send_event_listener_ipc_(send_event_listener_ipc), api_system_( base::Bind(&CallJsFunction), @@ -559,12 +560,17 @@ api_system_.CompleteRequest( request_id, response, !success && error.empty() ? "Unknown error." : error); + ipc_message_sender_->SendOnRequestResponseReceivedIPC(request_id); } RequestSender* NativeExtensionBindingsSystem::GetRequestSender() { return nullptr; } +IPCMessageSender* NativeExtensionBindingsSystem::GetIPCMessageSender() { + return ipc_message_sender_.get(); +} + void NativeExtensionBindingsSystem::BindingAccessor( v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { @@ -733,7 +739,8 @@ params->worker_thread_id = -1; params->service_worker_version_id = kInvalidServiceWorkerVersionId; - send_request_ipc_.Run(script_context, std::move(params), request->thread); + ipc_message_sender_->SendRequestIPC(script_context, std::move(params), + request->thread); } void NativeExtensionBindingsSystem::OnEventListenerChanged(
diff --git a/extensions/renderer/native_extension_bindings_system.h b/extensions/renderer/native_extension_bindings_system.h index 9d0b64aa5..ff71317 100644 --- a/extensions/renderer/native_extension_bindings_system.h +++ b/extensions/renderer/native_extension_bindings_system.h
@@ -16,9 +16,8 @@ #include "extensions/renderer/extension_bindings_system.h" #include "v8/include/v8.h" -struct ExtensionHostMsg_Request_Params; - namespace extensions { +class IPCMessageSender; class ScriptContext; // The implementation of the Bindings System for extensions code with native @@ -29,11 +28,6 @@ // Designed to be used in a single thread, but for all contexts on that thread. class NativeExtensionBindingsSystem : public ExtensionBindingsSystem { public: - // TODO(devlin): Instead, pass in an IPCMessageSender. - using SendRequestIPCMethod = - base::Callback<void(ScriptContext*, - std::unique_ptr<ExtensionHostMsg_Request_Params>, - binding::RequestThread)>; using SendEventListenerIPCMethod = base::Callback<void(binding::EventListenersChanged, ScriptContext*, @@ -42,7 +36,7 @@ bool was_manual)>; NativeExtensionBindingsSystem( - const SendRequestIPCMethod& send_request_ipc, + std::unique_ptr<IPCMessageSender> ipc_message_sender, const SendEventListenerIPCMethod& send_event_listener_ipc); ~NativeExtensionBindingsSystem() override; @@ -61,6 +55,7 @@ const base::ListValue& response, const std::string& error) override; RequestSender* GetRequestSender() override; + IPCMessageSender* GetIPCMessageSender() override; APIBindingsSystem* api_system() { return &api_system_; } @@ -101,8 +96,7 @@ void GetJSBindingUtil(v8::Local<v8::Context> context, v8::Local<v8::Value>* binding_util_out); - // Handler to send request IPCs. Abstracted out for testing purposes. - SendRequestIPCMethod send_request_ipc_; + std::unique_ptr<IPCMessageSender> ipc_message_sender_; // Handler to notify the browser of event registrations. Abstracted out for // testing purposes.
diff --git a/extensions/renderer/native_extension_bindings_system_unittest.cc b/extensions/renderer/native_extension_bindings_system_unittest.cc index ee707bf..3c45e0bb 100644 --- a/extensions/renderer/native_extension_bindings_system_unittest.cc +++ b/extensions/renderer/native_extension_bindings_system_unittest.cc
@@ -18,6 +18,7 @@ #include "extensions/renderer/bindings/api_binding_test.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "extensions/renderer/bindings/api_invocation_errors.h" +#include "extensions/renderer/ipc_message_sender.h" #include "extensions/renderer/module_system.h" #include "extensions/renderer/safe_builtins.h" #include "extensions/renderer/script_context.h" @@ -88,6 +89,29 @@ return !value->IsUndefined(); }; +class TestIPCMessageSender : public IPCMessageSender { + public: + TestIPCMessageSender() {} + ~TestIPCMessageSender() override {} + + // IPCMessageSender: + void SendRequestIPC(ScriptContext* context, + std::unique_ptr<ExtensionHostMsg_Request_Params> params, + binding::RequestThread thread) override { + last_params_ = std::move(params); + } + void SendOnRequestResponseReceivedIPC(int request_id) override {} + + const ExtensionHostMsg_Request_Params* last_params() const { + return last_params_.get(); + } + + private: + std::unique_ptr<ExtensionHostMsg_Request_Params> last_params_; + + DISALLOW_COPY_AND_ASSIGN(TestIPCMessageSender); +}; + } // namespace class NativeExtensionBindingsSystemUnittest : public APIBindingTest { @@ -105,9 +129,10 @@ void SetUp() override { render_thread_ = base::MakeUnique<content::MockRenderThread>(); script_context_set_ = base::MakeUnique<ScriptContextSet>(&extension_ids_); + auto ipc_message_sender = base::MakeUnique<TestIPCMessageSender>(); + ipc_message_sender_ = ipc_message_sender.get(); bindings_system_ = base::MakeUnique<NativeExtensionBindingsSystem>( - base::Bind(&NativeExtensionBindingsSystemUnittest::MockSendRequestIPC, - base::Unretained(this)), + std::move(ipc_message_sender), base::Bind(&NativeExtensionBindingsSystemUnittest::MockSendListenerIPC, base::Unretained(this))); APIBindingTest::SetUp(); @@ -131,13 +156,6 @@ APIBindingTest::TearDown(); } - void MockSendRequestIPC( - ScriptContext* context, - std::unique_ptr<ExtensionHostMsg_Request_Params> params, - binding::RequestThread thread) { - last_params_ = std::move(params); - } - void MockSendListenerIPC(binding::EventListenersChanged changed, ScriptContext* context, const std::string& event_name, @@ -187,8 +205,10 @@ NativeExtensionBindingsSystem* bindings_system() { return bindings_system_.get(); } - bool has_last_params() const { return !!last_params_; } - const ExtensionHostMsg_Request_Params& last_params() { return *last_params_; } + bool has_last_params() const { return !!ipc_message_sender_->last_params(); } + const ExtensionHostMsg_Request_Params& last_params() { + return *ipc_message_sender_->last_params(); + } StringSourceMap* source_map() { return &source_map_; } MockEventChangeHandler* event_change_handler() { return event_change_handler_.get(); @@ -200,6 +220,8 @@ std::unique_ptr<ScriptContextSet> script_context_set_; std::vector<ScriptContext*> raw_script_contexts_; std::unique_ptr<NativeExtensionBindingsSystem> bindings_system_; + // The TestIPCMessageSender; owned by the bindings system. + TestIPCMessageSender* ipc_message_sender_ = nullptr; std::unique_ptr<ExtensionHostMsg_Request_Params> last_params_; std::unique_ptr<MockEventChangeHandler> event_change_handler_;
diff --git a/extensions/renderer/service_worker_data.cc b/extensions/renderer/service_worker_data.cc index b20986a..357c2888 100644 --- a/extensions/renderer/service_worker_data.cc +++ b/extensions/renderer/service_worker_data.cc
@@ -5,19 +5,16 @@ #include "extensions/renderer/service_worker_data.h" #include "extensions/renderer/extension_bindings_system.h" -#include "extensions/renderer/ipc_message_sender.h" namespace extensions { ServiceWorkerData::ServiceWorkerData( int64_t service_worker_version_id, ScriptContext* context, - std::unique_ptr<ExtensionBindingsSystem> bindings_system, - std::unique_ptr<IPCMessageSender> ipc_message_sender) + std::unique_ptr<ExtensionBindingsSystem> bindings_system) : service_worker_version_id_(service_worker_version_id), context_(context), v8_schema_registry_(new V8SchemaRegistry), - ipc_message_sender_(std::move(ipc_message_sender)), bindings_system_(std::move(bindings_system)) {} ServiceWorkerData::~ServiceWorkerData() {}
diff --git a/extensions/renderer/service_worker_data.h b/extensions/renderer/service_worker_data.h index 8f448b11..d9d780a 100644 --- a/extensions/renderer/service_worker_data.h +++ b/extensions/renderer/service_worker_data.h
@@ -12,7 +12,6 @@ namespace extensions { class ExtensionBindingsSystem; -class IPCMessageSender; class ScriptContext; // Per ServiceWorker data in worker thread. @@ -21,8 +20,7 @@ public: ServiceWorkerData(int64_t service_worker_version_id, ScriptContext* context, - std::unique_ptr<ExtensionBindingsSystem> bindings_system, - std::unique_ptr<IPCMessageSender> ipc_message_sender); + std::unique_ptr<ExtensionBindingsSystem> bindings_system); ~ServiceWorkerData(); V8SchemaRegistry* v8_schema_registry() { return v8_schema_registry_.get(); } @@ -31,14 +29,12 @@ return service_worker_version_id_; } ScriptContext* context() const { return context_; } - IPCMessageSender* ipc_message_sender() { return ipc_message_sender_.get(); } private: const int64_t service_worker_version_id_; ScriptContext* const context_; std::unique_ptr<V8SchemaRegistry> v8_schema_registry_; - std::unique_ptr<IPCMessageSender> ipc_message_sender_; std::unique_ptr<ExtensionBindingsSystem> bindings_system_; DISALLOW_COPY_AND_ASSIGN(ServiceWorkerData);
diff --git a/extensions/renderer/worker_thread_dispatcher.cc b/extensions/renderer/worker_thread_dispatcher.cc index 8da4ad3..8455c10 100644 --- a/extensions/renderer/worker_thread_dispatcher.cc +++ b/extensions/renderer/worker_thread_dispatcher.cc
@@ -135,7 +135,6 @@ ServiceWorkerData* data = g_data_tls.Pointer()->Get(); data->bindings_system()->HandleResponse(request_id, succeeded, response, error); - data->ipc_message_sender()->SendOnRequestResponseReceivedIPC(request_id); } void WorkerThreadDispatcher::OnDispatchEvent( @@ -165,17 +164,13 @@ // The Unretained below is safe since the IPC message sender outlives the // bindings system. bindings_system = base::MakeUnique<NativeExtensionBindingsSystem>( - base::Bind(&IPCMessageSender::SendRequestIPC, - base::Unretained(ipc_message_sender.get())), - base::Bind(&SendEventListenersIPC)); + std::move(ipc_message_sender), base::Bind(&SendEventListenersIPC)); } else { bindings_system = base::MakeUnique<JsExtensionBindingsSystem>( - source_map, - base::MakeUnique<RequestSender>(ipc_message_sender.get())); + source_map, std::move(ipc_message_sender)); } ServiceWorkerData* new_data = new ServiceWorkerData( - service_worker_version_id, context, std::move(bindings_system), - std::move(ipc_message_sender)); + service_worker_version_id, context, std::move(bindings_system)); g_data_tls.Pointer()->Set(new_data); }
diff --git a/gpu/ipc/BUILD.gn b/gpu/ipc/BUILD.gn index 57571f8ae..7774238 100644 --- a/gpu/ipc/BUILD.gn +++ b/gpu/ipc/BUILD.gn
@@ -23,6 +23,7 @@ } target(link_target_type, "command_buffer_sources") { visibility = [ "//gpu/*" ] + sources = [ "gpu_in_process_thread_service.cc", "gpu_in_process_thread_service.h",
diff --git a/ipc/ipc_mojo_perftest.cc b/ipc/ipc_mojo_perftest.cc index 70d3381e..b491abf1 100644 --- a/ipc/ipc_mojo_perftest.cc +++ b/ipc/ipc_mojo_perftest.cc
@@ -1,786 +1,744 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <memory> - -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/process/process_metrics.h" -#include "base/run_loop.h" -#include "base/strings/stringprintf.h" -#include "base/test/perf_time_logger.h" -#include "base/test/test_io_thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "build/build_config.h" -#include "ipc/ipc_channel_mojo.h" -#include "ipc/ipc_test.mojom.h" -#include "ipc/ipc_test_base.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/edk/embedder/platform_channel_pair.h" -#include "mojo/edk/test/mojo_test_base.h" -#include "mojo/edk/test/multiprocess_test_helper.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/system/message_pipe.h" - -namespace IPC { -namespace { - -// This class simply collects stats about abstract "events" (each of which has a -// start time and an end time). -class EventTimeTracker { - public: - explicit EventTimeTracker(const char* name) : name_(name), count_(0) {} - - void AddEvent(const base::TimeTicks& start, const base::TimeTicks& end) { - DCHECK(end >= start); - count_++; - base::TimeDelta duration = end - start; - total_duration_ += duration; - max_duration_ = std::max(max_duration_, duration); - } - - void ShowResults() const { - VLOG(1) << name_ << " count: " << count_; - VLOG(1) << name_ << " total duration: " << total_duration_.InMillisecondsF() - << " ms"; - VLOG(1) << name_ << " average duration: " - << (total_duration_.InMillisecondsF() / static_cast<double>(count_)) - << " ms"; - VLOG(1) << name_ << " maximum duration: " << max_duration_.InMillisecondsF() - << " ms"; - } - - void Reset() { - count_ = 0; - total_duration_ = base::TimeDelta(); - max_duration_ = base::TimeDelta(); - } - - private: - const std::string name_; - - uint64_t count_; - base::TimeDelta total_duration_; - base::TimeDelta max_duration_; - - DISALLOW_COPY_AND_ASSIGN(EventTimeTracker); -}; - -class PerformanceChannelListener : public Listener { - public: - explicit PerformanceChannelListener(const std::string& label) - : label_(label), - sender_(NULL), - msg_count_(0), - msg_size_(0), - count_down_(0), - latency_tracker_("Server messages") { - VLOG(1) << "Server listener up"; - } - - ~PerformanceChannelListener() override { VLOG(1) << "Server listener down"; } - - void Init(Sender* sender) { - DCHECK(!sender_); - sender_ = sender; - } - - // Call this before running the message loop. - void SetTestParams(int msg_count, size_t msg_size) { - DCHECK_EQ(0, count_down_); - msg_count_ = msg_count; - msg_size_ = msg_size; - count_down_ = msg_count_; - payload_ = std::string(msg_size_, 'a'); - } - - bool OnMessageReceived(const Message& message) override { - CHECK(sender_); - - base::PickleIterator iter(message); - int64_t time_internal; - EXPECT_TRUE(iter.ReadInt64(&time_internal)); - int msgid; - EXPECT_TRUE(iter.ReadInt(&msgid)); - std::string reflected_payload; - EXPECT_TRUE(iter.ReadString(&reflected_payload)); - - // Include message deserialization in latency. - base::TimeTicks now = base::TimeTicks::Now(); - - if (reflected_payload == "hello") { - // Start timing on hello. - latency_tracker_.Reset(); - DCHECK(!perf_logger_.get()); - std::string test_name = - base::StringPrintf("IPC_%s_Perf_%dx_%u", label_.c_str(), msg_count_, - static_cast<unsigned>(msg_size_)); - perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); - } else { - DCHECK_EQ(payload_.size(), reflected_payload.size()); - - latency_tracker_.AddEvent( - base::TimeTicks::FromInternalValue(time_internal), now); - - CHECK(count_down_ > 0); - count_down_--; - if (count_down_ == 0) { - perf_logger_.reset(); // Stop the perf timer now. - latency_tracker_.ShowResults(); - base::MessageLoop::current()->QuitWhenIdle(); - return true; - } - } - - Message* msg = new Message(0, 2, Message::PRIORITY_NORMAL); - msg->WriteInt64(base::TimeTicks::Now().ToInternalValue()); - msg->WriteInt(count_down_); - msg->WriteString(payload_); - sender_->Send(msg); - return true; - } - - private: - std::string label_; - Sender* sender_; - int msg_count_; - size_t msg_size_; - - int count_down_; - std::string payload_; - EventTimeTracker latency_tracker_; - std::unique_ptr<base::PerfTimeLogger> perf_logger_; -}; - -// This channel listener just replies to all messages with the exact same -// message. It assumes each message has one string parameter. When the string -// "quit" is sent, it will exit. -class ChannelReflectorListener : public Listener { - public: - ChannelReflectorListener() - : channel_(NULL), latency_tracker_("Client messages") { - VLOG(1) << "Client listener up"; - } - - ~ChannelReflectorListener() override { - VLOG(1) << "Client listener down"; - latency_tracker_.ShowResults(); - } - - void Init(Channel* channel) { - DCHECK(!channel_); - channel_ = channel; - } - - bool OnMessageReceived(const Message& message) override { - CHECK(channel_); - - base::PickleIterator iter(message); - int64_t time_internal; - EXPECT_TRUE(iter.ReadInt64(&time_internal)); - int msgid; - EXPECT_TRUE(iter.ReadInt(&msgid)); - base::StringPiece payload; - EXPECT_TRUE(iter.ReadStringPiece(&payload)); - - // Include message deserialization in latency. - base::TimeTicks now = base::TimeTicks::Now(); - - if (payload == "hello") { - latency_tracker_.Reset(); - } else if (payload == "quit") { - latency_tracker_.ShowResults(); - base::MessageLoop::current()->QuitWhenIdle(); - return true; - } else { - // Don't track hello and quit messages. - latency_tracker_.AddEvent( - base::TimeTicks::FromInternalValue(time_internal), now); - } - - Message* msg = new Message(0, 2, Message::PRIORITY_NORMAL); - msg->WriteInt64(base::TimeTicks::Now().ToInternalValue()); - msg->WriteInt(msgid); - msg->WriteString(payload); - channel_->Send(msg); - return true; - } - - private: - Channel* channel_; - EventTimeTracker latency_tracker_; -}; - -// This class locks the current thread to a particular CPU core. This is -// important because otherwise the different threads and processes of these -// tests end up on different CPU cores which means that all of the cores are -// lightly loaded so the OS (Windows and Linux) fails to ramp up the CPU -// frequency, leading to unpredictable and often poor performance. -class LockThreadAffinity { - public: - explicit LockThreadAffinity(int cpu_number) : affinity_set_ok_(false) { -#if defined(OS_WIN) - const DWORD_PTR thread_mask = static_cast<DWORD_PTR>(1) << cpu_number; - old_affinity_ = SetThreadAffinityMask(GetCurrentThread(), thread_mask); - affinity_set_ok_ = old_affinity_ != 0; -#elif defined(OS_LINUX) - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(cpu_number, &cpuset); - auto get_result = sched_getaffinity(0, sizeof(old_cpuset_), &old_cpuset_); - DCHECK_EQ(0, get_result); - auto set_result = sched_setaffinity(0, sizeof(cpuset), &cpuset); - // Check for get_result failure, even though it should always succeed. - affinity_set_ok_ = (set_result == 0) && (get_result == 0); -#endif - if (!affinity_set_ok_) - LOG(WARNING) << "Failed to set thread affinity to CPU " << cpu_number; - } - - ~LockThreadAffinity() { - if (!affinity_set_ok_) - return; -#if defined(OS_WIN) - auto set_result = SetThreadAffinityMask(GetCurrentThread(), old_affinity_); - DCHECK_NE(0u, set_result); -#elif defined(OS_LINUX) - auto set_result = sched_setaffinity(0, sizeof(old_cpuset_), &old_cpuset_); - DCHECK_EQ(0, set_result); -#endif - } - - private: - bool affinity_set_ok_; -#if defined(OS_WIN) - DWORD_PTR old_affinity_; -#elif defined(OS_LINUX) - cpu_set_t old_cpuset_; -#endif - - DISALLOW_COPY_AND_ASSIGN(LockThreadAffinity); -}; - -class PingPongTestParams { - public: - PingPongTestParams(size_t size, int count) - : message_size_(size), message_count_(count) {} - - size_t message_size() const { return message_size_; } - int message_count() const { return message_count_; } - - private: - size_t message_size_; - int message_count_; -}; - -std::vector<PingPongTestParams> GetDefaultTestParams() { -// Test several sizes. We use 12^N for message size, and limit the message -// count to keep the test duration reasonable. -#ifdef NDEBUG - const int kMultiplier = 100; -#else - // Debug builds on Windows run these tests orders of magnitude more slowly. - const int kMultiplier = 1; -#endif - std::vector<PingPongTestParams> list; - list.push_back(PingPongTestParams(12, 500 * kMultiplier)); - list.push_back(PingPongTestParams(144, 500 * kMultiplier)); - list.push_back(PingPongTestParams(1728, 500 * kMultiplier)); - list.push_back(PingPongTestParams(20736, 120 * kMultiplier)); - list.push_back(PingPongTestParams(248832, 10 * kMultiplier)); - return list; -} - -// Avoid core 0 due to conflicts with Intel's Power Gadget. -// Setting thread affinity will fail harmlessly on single/dual core machines. -const int kSharedCore = 2; - -class MojoChannelPerfTest : public IPCChannelMojoTestBase { - public: - MojoChannelPerfTest() = default; - ~MojoChannelPerfTest() override = default; - - void RunTestChannelPingPong() { - Init("MojoPerfTestClient"); - - // Set up IPC channel and start client. - PerformanceChannelListener listener("Channel"); - CreateChannel(&listener); - listener.Init(channel()); - ASSERT_TRUE(ConnectChannel()); - - LockThreadAffinity thread_locker(kSharedCore); - std::vector<PingPongTestParams> params = GetDefaultTestParams(); - for (size_t i = 0; i < params.size(); i++) { - listener.SetTestParams(params[i].message_count(), - params[i].message_size()); - - // This initial message will kick-start the ping-pong of messages. - Message* message = new Message(0, 2, Message::PRIORITY_NORMAL); - message->WriteInt64(base::TimeTicks::Now().ToInternalValue()); - message->WriteInt(-1); - message->WriteString("hello"); - sender()->Send(message); - - // Run message loop. - base::RunLoop().Run(); - } - - // Send quit message. - Message* message = new Message(0, 2, Message::PRIORITY_NORMAL); - message->WriteInt64(base::TimeTicks::Now().ToInternalValue()); - message->WriteInt(-1); - message->WriteString("quit"); - sender()->Send(message); - - EXPECT_TRUE(WaitForClientShutdown()); - DestroyChannel(); - } - - void RunTestChannelProxyPingPong() { - io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart)); - - Init("MojoPerfTestClient"); - - // Set up IPC channel and start client. - PerformanceChannelListener listener("ChannelProxy"); - auto channel_proxy = IPC::ChannelProxy::Create( - TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener, - io_thread_->task_runner()); - listener.Init(channel_proxy.get()); - - LockThreadAffinity thread_locker(kSharedCore); - std::vector<PingPongTestParams> params = GetDefaultTestParams(); - for (size_t i = 0; i < params.size(); i++) { - listener.SetTestParams(params[i].message_count(), - params[i].message_size()); - - // This initial message will kick-start the ping-pong of messages. - Message* message = new Message(0, 2, Message::PRIORITY_NORMAL); - message->WriteInt64(base::TimeTicks::Now().ToInternalValue()); - message->WriteInt(-1); - message->WriteString("hello"); - channel_proxy->Send(message); - - // Run message loop. - base::RunLoop().Run(); - } - - // Send quit message. - Message* message = new Message(0, 2, Message::PRIORITY_NORMAL); - message->WriteInt64(base::TimeTicks::Now().ToInternalValue()); - message->WriteInt(-1); - message->WriteString("quit"); - channel_proxy->Send(message); - - EXPECT_TRUE(WaitForClientShutdown()); - channel_proxy.reset(); - - io_thread_.reset(); - } - - scoped_refptr<base::TaskRunner> io_task_runner() { - if (io_thread_) - return io_thread_->task_runner(); - return base::ThreadTaskRunnerHandle::Get(); - } - - private: - std::unique_ptr<base::TestIOThread> io_thread_; -}; - -TEST_F(MojoChannelPerfTest, ChannelPingPong) { - RunTestChannelPingPong(); - - base::RunLoop run_loop; - run_loop.RunUntilIdle(); -} - -TEST_F(MojoChannelPerfTest, ChannelProxyPingPong) { - RunTestChannelProxyPingPong(); - - base::RunLoop run_loop; - run_loop.RunUntilIdle(); -} - -// Test to see how many channels we can create. -TEST_F(MojoChannelPerfTest, DISABLED_MaxChannelCount) { -#if defined(OS_POSIX) - LOG(INFO) << "base::GetMaxFds " << base::GetMaxFds(); - base::SetFdLimit(20000); -#endif - - std::vector<mojo::edk::PlatformChannelPair*> channels; - for (size_t i = 0; i < 10000; ++i) { - LOG(INFO) << "channels size: " << channels.size(); - channels.push_back(new mojo::edk::PlatformChannelPair()); - } -} - -class MojoPerfTestClient { - public: - MojoPerfTestClient() : listener_(new ChannelReflectorListener()) { - mojo::edk::test::MultiprocessTestHelper::ChildSetup(); - } - - ~MojoPerfTestClient() = default; - - int Run(MojoHandle handle) { - handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle)); - LockThreadAffinity thread_locker(kSharedCore); - std::unique_ptr<Channel> channel = ChannelMojo::Create( - std::move(handle_), Channel::MODE_CLIENT, listener_.get()); - listener_->Init(channel.get()); - CHECK(channel->Connect()); - - base::RunLoop().Run(); - return 0; - } - - private: - base::MessageLoopForIO main_message_loop_; - std::unique_ptr<ChannelReflectorListener> listener_; - std::unique_ptr<Channel> channel_; - mojo::ScopedMessagePipeHandle handle_; -}; - -MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) { - MojoPerfTestClient client; - int rv = mojo::edk::test::MultiprocessTestHelper::RunClientMain( - base::Bind(&MojoPerfTestClient::Run, base::Unretained(&client)), - true /* pass_pipe_ownership_to_main */); - - base::RunLoop run_loop; - run_loop.RunUntilIdle(); - - return rv; -} - -class ReflectorImpl : public IPC::mojom::Reflector { - public: - explicit ReflectorImpl(mojo::ScopedMessagePipeHandle handle) - : binding_(this, IPC::mojom::ReflectorRequest(std::move(handle))) {} - ~ReflectorImpl() override { - ignore_result(binding_.Unbind().PassMessagePipe().release()); - } - - private: - // IPC::mojom::Reflector: - void Ping(const std::string& value, PingCallback callback) override { - std::move(callback).Run(value); - } - - void Quit() override { base::MessageLoop::current()->QuitWhenIdle(); } - - mojo::Binding<IPC::mojom::Reflector> binding_; -}; - -class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase { - public: - MojoInterfacePerfTest() : message_count_(0), count_down_(0) {} - - protected: - void RunPingPongServer(MojoHandle mp, const std::string& label) { - label_ = label; - - mojo::MessagePipeHandle mp_handle(mp); - mojo::ScopedMessagePipeHandle scoped_mp(mp_handle); - ping_receiver_.Bind(IPC::mojom::ReflectorPtrInfo(std::move(scoped_mp), 0u)); - - LockThreadAffinity thread_locker(kSharedCore); - std::vector<PingPongTestParams> params = GetDefaultTestParams(); - for (size_t i = 0; i < params.size(); i++) { - ping_receiver_->Ping("hello", base::Bind(&MojoInterfacePerfTest::OnPong, - base::Unretained(this))); - message_count_ = count_down_ = params[i].message_count(); - payload_ = std::string(params[i].message_size(), 'a'); - - base::RunLoop().Run(); - } - - ping_receiver_->Quit(); - - ignore_result(ping_receiver_.PassInterface().PassHandle().release()); - } - - void OnPong(const std::string& value) { - if (value == "hello") { - DCHECK(!perf_logger_.get()); - std::string test_name = - base::StringPrintf("IPC_%s_Perf_%dx_%zu", label_.c_str(), - message_count_, payload_.size()); - perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); - } else { - DCHECK_EQ(payload_.size(), value.size()); - - CHECK(count_down_ > 0); - count_down_--; - if (count_down_ == 0) { - perf_logger_.reset(); - base::MessageLoop::current()->QuitWhenIdle(); - return; - } - } - - ping_receiver_->Ping(payload_, base::Bind(&MojoInterfacePerfTest::OnPong, - base::Unretained(this))); - } - - static int RunPingPongClient(MojoHandle mp) { - mojo::MessagePipeHandle mp_handle(mp); - mojo::ScopedMessagePipeHandle scoped_mp(mp_handle); - - // In single process mode, this is running in a task and by default other - // tasks (in particular, the binding) won't run. To keep the single process - // and multi-process code paths the same, enable nestable tasks. - base::MessageLoop::ScopedNestableTaskAllower nest_loop( - base::MessageLoop::current()); - - LockThreadAffinity thread_locker(kSharedCore); - ReflectorImpl impl(std::move(scoped_mp)); - base::RunLoop().Run(); - return 0; - } - - private: - int message_count_; - int count_down_; - std::string label_; - std::string payload_; - IPC::mojom::ReflectorPtr ping_receiver_; - std::unique_ptr<base::PerfTimeLogger> perf_logger_; - - DISALLOW_COPY_AND_ASSIGN(MojoInterfacePerfTest); -}; - -enum class InProcessMessageMode { - kSerialized, - kUnserialized, -}; - -class MojoInProcessInterfacePerfTest - : public MojoInterfacePerfTest, - public testing::WithParamInterface<InProcessMessageMode> { - public: - MojoInProcessInterfacePerfTest() { - switch (GetParam()) { - case InProcessMessageMode::kSerialized: - mojo::Connector::OverrideDefaultSerializationBehaviorForTesting( - mojo::Connector::OutgoingSerializationMode::kEager, - mojo::Connector::IncomingSerializationMode::kDispatchAsIs); - break; - case InProcessMessageMode::kUnserialized: - mojo::Connector::OverrideDefaultSerializationBehaviorForTesting( - mojo::Connector::OutgoingSerializationMode::kLazy, - mojo::Connector::IncomingSerializationMode::kDispatchAsIs); - break; - } - } -}; - -DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoInterfacePerfTest, h) { - base::MessageLoop main_message_loop; - return RunPingPongClient(h); -} - -// Similar to MojoChannelPerfTest above, but uses a Mojo interface instead of -// raw IPC::Messages. -TEST_F(MojoInterfacePerfTest, MultiprocessPingPong) { - RunTestClient("PingPongClient", [&](MojoHandle h) { - base::MessageLoop main_message_loop; - RunPingPongServer(h, "Multiprocess"); - }); -} - -// A single process version of the above test. -TEST_P(MojoInProcessInterfacePerfTest, MultiThreadPingPong) { - MojoHandle server_handle, client_handle; - CreateMessagePipe(&server_handle, &client_handle); - - base::Thread client_thread("PingPongClient"); - client_thread.Start(); - client_thread.task_runner()->PostTask( - FROM_HERE, - base::Bind(base::IgnoreResult(&RunPingPongClient), client_handle)); - - base::MessageLoop main_message_loop; - RunPingPongServer(server_handle, "SingleProcess"); -} - -TEST_P(MojoInProcessInterfacePerfTest, SingleThreadPingPong) { - MojoHandle server_handle, client_handle; - CreateMessagePipe(&server_handle, &client_handle); - - base::MessageLoop main_message_loop; - mojo::MessagePipeHandle mp_handle(client_handle); - mojo::ScopedMessagePipeHandle scoped_mp(mp_handle); - LockThreadAffinity thread_locker(kSharedCore); - ReflectorImpl impl(std::move(scoped_mp)); - - RunPingPongServer(server_handle, "SingleProcess"); -} - -INSTANTIATE_TEST_CASE_P(, - MojoInProcessInterfacePerfTest, - testing::Values(InProcessMessageMode::kSerialized, - InProcessMessageMode::kUnserialized)); - -class CallbackPerfTest : public testing::Test { - public: - CallbackPerfTest() - : client_thread_("PingPongClient"), message_count_(0), count_down_(0) {} - - protected: - void RunMultiThreadPingPongServer() { - client_thread_.Start(); - - LockThreadAffinity thread_locker(kSharedCore); - std::vector<PingPongTestParams> params = GetDefaultTestParams(); - for (size_t i = 0; i < params.size(); i++) { - std::string hello("hello"); - client_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&CallbackPerfTest::Ping, base::Unretained(this), hello)); - message_count_ = count_down_ = params[i].message_count(); - payload_ = std::string(params[i].message_size(), 'a'); - - base::RunLoop().Run(); - } - } - - void Ping(const std::string& value) { - main_message_loop_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&CallbackPerfTest::OnPong, base::Unretained(this), value)); - } - - void OnPong(const std::string& value) { - if (value == "hello") { - DCHECK(!perf_logger_.get()); - std::string test_name = - base::StringPrintf("Callback_MultiProcess_Perf_%dx_%zu", - message_count_, payload_.size()); - perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); - } else { - DCHECK_EQ(payload_.size(), value.size()); - - CHECK(count_down_ > 0); - count_down_--; - if (count_down_ == 0) { - perf_logger_.reset(); - base::MessageLoop::current()->QuitWhenIdle(); - return; - } - } - - client_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&CallbackPerfTest::Ping, base::Unretained(this), payload_)); - } - - void RunSingleThreadNoPostTaskPingPongServer() { - LockThreadAffinity thread_locker(kSharedCore); - std::vector<PingPongTestParams> params = GetDefaultTestParams(); - base::Callback<void(const std::string&, - const base::Callback<void(const std::string&)>&)> - ping = base::Bind(&CallbackPerfTest::SingleThreadPingNoPostTask, - base::Unretained(this)); - for (size_t i = 0; i < params.size(); i++) { - payload_ = std::string(params[i].message_size(), 'a'); - std::string test_name = - base::StringPrintf("Callback_SingleThreadPostTask_Perf_%dx_%zu", - params[i].message_count(), payload_.size()); - perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); - for (int j = 0; j < params[i].message_count(); ++j) { - ping.Run(payload_, - base::Bind(&CallbackPerfTest::SingleThreadPongNoPostTask, - base::Unretained(this))); - } - perf_logger_.reset(); - } - } - - void SingleThreadPingNoPostTask( - const std::string& value, - const base::Callback<void(const std::string&)>& pong) { - pong.Run(value); - } - - void SingleThreadPongNoPostTask(const std::string& value) {} - - void RunSingleThreadPostTaskPingPongServer() { - LockThreadAffinity thread_locker(kSharedCore); - std::vector<PingPongTestParams> params = GetDefaultTestParams(); - for (size_t i = 0; i < params.size(); i++) { - std::string hello("hello"); - base::MessageLoop::current()->task_runner()->PostTask( - FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask, - base::Unretained(this), hello)); - message_count_ = count_down_ = params[i].message_count(); - payload_ = std::string(params[i].message_size(), 'a'); - - base::RunLoop().Run(); - } - } - - void SingleThreadPingPostTask(const std::string& value) { - base::MessageLoop::current()->task_runner()->PostTask( - FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPongPostTask, - base::Unretained(this), value)); - } - - void SingleThreadPongPostTask(const std::string& value) { - if (value == "hello") { - DCHECK(!perf_logger_.get()); - std::string test_name = - base::StringPrintf("Callback_SingleThreadNoPostTask_Perf_%dx_%zu", - message_count_, payload_.size()); - perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); - } else { - DCHECK_EQ(payload_.size(), value.size()); - - CHECK(count_down_ > 0); - count_down_--; - if (count_down_ == 0) { - perf_logger_.reset(); - base::MessageLoop::current()->QuitWhenIdle(); - return; - } - } - - base::MessageLoop::current()->task_runner()->PostTask( - FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask, - base::Unretained(this), payload_)); - } - - private: - base::Thread client_thread_; - base::MessageLoop main_message_loop_; - int message_count_; - int count_down_; - std::string payload_; - std::unique_ptr<base::PerfTimeLogger> perf_logger_; - - DISALLOW_COPY_AND_ASSIGN(CallbackPerfTest); -}; - -// Sends the same data as above using PostTask to a different thread instead of -// IPCs for comparison. -TEST_F(CallbackPerfTest, MultiThreadPingPong) { - RunMultiThreadPingPongServer(); -} - -// Sends the same data as above using PostTask to the same thread. -TEST_F(CallbackPerfTest, SingleThreadPostTaskPingPong) { - RunSingleThreadPostTaskPingPongServer(); -} - -// Sends the same data as above without using PostTask to the same thread. -TEST_F(CallbackPerfTest, SingleThreadNoPostTaskPingPong) { - RunSingleThreadNoPostTaskPingPongServer(); -} - -} // namespace -} // namespace IPC +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stddef.h> +#include <memory> + +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/process/process_metrics.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/test/perf_time_logger.h" +#include "base/test/test_io_thread.h" +#include "base/threading/thread_task_runner_handle.h" +#include "build/build_config.h" +#include "ipc/ipc_channel_mojo.h" +#include "ipc/ipc_test.mojom.h" +#include "ipc/ipc_test_base.h" +#include "mojo/edk/embedder/embedder.h" +#include "mojo/edk/embedder/platform_channel_pair.h" +#include "mojo/edk/test/mojo_test_base.h" +#include "mojo/edk/test/multiprocess_test_helper.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/message_pipe.h" + +#define IPC_MESSAGE_IMPL +#include "ipc/ipc_message_macros.h" + +#define IPC_MESSAGE_START TestMsgStart + +IPC_MESSAGE_CONTROL0(TestMsg_Hello) +IPC_MESSAGE_CONTROL0(TestMsg_Quit) +IPC_MESSAGE_CONTROL1(TestMsg_Ping, std::string) +IPC_SYNC_MESSAGE_CONTROL1_1(TestMsg_SyncPing, std::string, std::string) + +namespace IPC { +namespace { + +class PerformanceChannelListener : public Listener { + public: + explicit PerformanceChannelListener(const std::string& label) + : label_(label), + sender_(NULL), + msg_count_(0), + msg_size_(0), + sync_(false), + count_down_(0) { + VLOG(1) << "Server listener up"; + } + + ~PerformanceChannelListener() override { VLOG(1) << "Server listener down"; } + + void Init(Sender* sender) { + DCHECK(!sender_); + sender_ = sender; + } + + // Call this before running the message loop. + void SetTestParams(int msg_count, size_t msg_size, bool sync) { + DCHECK_EQ(0, count_down_); + msg_count_ = msg_count; + msg_size_ = msg_size; + sync_ = sync; + count_down_ = msg_count_; + payload_ = std::string(msg_size_, 'a'); + } + + bool OnMessageReceived(const Message& message) override { + CHECK(sender_); + + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PerformanceChannelListener, message) + IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello) + IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; + } + + void OnHello() { + // Start timing on hello. + DCHECK(!perf_logger_.get()); + std::string test_name = + base::StringPrintf("IPC_%s_Perf_%dx_%u", label_.c_str(), msg_count_, + static_cast<unsigned>(msg_size_)); + perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); + if (sync_) { + for (int i = 0; i < count_down_; ++i) { + std::string response; + sender_->Send(new TestMsg_SyncPing(payload_, &response)); + } + base::MessageLoop::current()->QuitWhenIdle(); + } else { + SendPong(); + } + } + + void OnPing(const std::string& payload) { + // Include message deserialization in latency. + DCHECK_EQ(payload_.size(), payload.size()); + + CHECK(count_down_ > 0); + count_down_--; + if (count_down_ == 0) { + perf_logger_.reset(); // Stop the perf timer now. + base::MessageLoop::current()->QuitWhenIdle(); + return; + } + + SendPong(); + } + + void SendPong() { sender_->Send(new TestMsg_Ping(payload_)); } + + private: + std::string label_; + Sender* sender_; + int msg_count_; + size_t msg_size_; + bool sync_; + + int count_down_; + std::string payload_; + std::unique_ptr<base::PerfTimeLogger> perf_logger_; +}; + +// This channel listener just replies to all messages with the exact same +// message. It assumes each message has one string parameter. When the string +// "quit" is sent, it will exit. +class ChannelReflectorListener : public Listener { + public: + ChannelReflectorListener() : channel_(NULL) { + VLOG(1) << "Client listener up"; + } + + ~ChannelReflectorListener() override { VLOG(1) << "Client listener down"; } + + void Init(Sender* channel) { + DCHECK(!channel_); + channel_ = channel; + } + + bool OnMessageReceived(const Message& message) override { + CHECK(channel_); + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message) + IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello) + IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing) + IPC_MESSAGE_HANDLER(TestMsg_SyncPing, OnSyncPing) + IPC_MESSAGE_HANDLER(TestMsg_Quit, OnQuit) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; + } + + void OnHello() { channel_->Send(new TestMsg_Hello); } + + void OnPing(const std::string& payload) { + channel_->Send(new TestMsg_Ping(payload)); + } + + void OnSyncPing(const std::string& payload, std::string* response) { + *response = payload; + } + + void OnQuit() { base::MessageLoop::current()->QuitWhenIdle(); } + + void Send(IPC::Message* message) { channel_->Send(message); } + + private: + Sender* channel_; +}; + +// This class locks the current thread to a particular CPU core. This is +// important because otherwise the different threads and processes of these +// tests end up on different CPU cores which means that all of the cores are +// lightly loaded so the OS (Windows and Linux) fails to ramp up the CPU +// frequency, leading to unpredictable and often poor performance. +class LockThreadAffinity { + public: + explicit LockThreadAffinity(int cpu_number) : affinity_set_ok_(false) { +#if defined(OS_WIN) + const DWORD_PTR thread_mask = static_cast<DWORD_PTR>(1) << cpu_number; + old_affinity_ = SetThreadAffinityMask(GetCurrentThread(), thread_mask); + affinity_set_ok_ = old_affinity_ != 0; +#elif defined(OS_LINUX) + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(cpu_number, &cpuset); + auto get_result = sched_getaffinity(0, sizeof(old_cpuset_), &old_cpuset_); + DCHECK_EQ(0, get_result); + auto set_result = sched_setaffinity(0, sizeof(cpuset), &cpuset); + // Check for get_result failure, even though it should always succeed. + affinity_set_ok_ = (set_result == 0) && (get_result == 0); +#endif + if (!affinity_set_ok_) + LOG(WARNING) << "Failed to set thread affinity to CPU " << cpu_number; + } + + ~LockThreadAffinity() { + if (!affinity_set_ok_) + return; +#if defined(OS_WIN) + auto set_result = SetThreadAffinityMask(GetCurrentThread(), old_affinity_); + DCHECK_NE(0u, set_result); +#elif defined(OS_LINUX) + auto set_result = sched_setaffinity(0, sizeof(old_cpuset_), &old_cpuset_); + DCHECK_EQ(0, set_result); +#endif + } + + private: + bool affinity_set_ok_; +#if defined(OS_WIN) + DWORD_PTR old_affinity_; +#elif defined(OS_LINUX) + cpu_set_t old_cpuset_; +#endif + + DISALLOW_COPY_AND_ASSIGN(LockThreadAffinity); +}; + +class PingPongTestParams { + public: + PingPongTestParams(size_t size, int count) + : message_size_(size), message_count_(count) {} + + size_t message_size() const { return message_size_; } + int message_count() const { return message_count_; } + + private: + size_t message_size_; + int message_count_; +}; + +std::vector<PingPongTestParams> GetDefaultTestParams() { +// Test several sizes. We use 12^N for message size, and limit the message +// count to keep the test duration reasonable. +#ifdef NDEBUG + const int kMultiplier = 100; +#else + // Debug builds on Windows run these tests orders of magnitude more slowly. + const int kMultiplier = 1; +#endif + std::vector<PingPongTestParams> list; + list.push_back(PingPongTestParams(12, 500 * kMultiplier)); + list.push_back(PingPongTestParams(144, 500 * kMultiplier)); + list.push_back(PingPongTestParams(1728, 500 * kMultiplier)); + list.push_back(PingPongTestParams(20736, 120 * kMultiplier)); + list.push_back(PingPongTestParams(248832, 10 * kMultiplier)); + return list; +} + +// Avoid core 0 due to conflicts with Intel's Power Gadget. +// Setting thread affinity will fail harmlessly on single/dual core machines. +const int kSharedCore = 2; + +class MojoChannelPerfTest : public IPCChannelMojoTestBase { + public: + MojoChannelPerfTest() = default; + ~MojoChannelPerfTest() override = default; + + void RunTestChannelProxyPingPong() { + io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart)); + + Init("MojoPerfTestClient"); + + // Set up IPC channel and start client. + PerformanceChannelListener listener("ChannelProxy"); + auto channel_proxy = IPC::ChannelProxy::Create( + TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener, + io_thread_->task_runner()); + listener.Init(channel_proxy.get()); + + LockThreadAffinity thread_locker(kSharedCore); + std::vector<PingPongTestParams> params = GetDefaultTestParams(); + for (size_t i = 0; i < params.size(); i++) { + listener.SetTestParams(params[i].message_count(), + params[i].message_size(), false); + + // This initial message will kick-start the ping-pong of messages. + channel_proxy->Send(new TestMsg_Hello); + + // Run message loop. + base::RunLoop().Run(); + } + + // Send quit message. + channel_proxy->Send(new TestMsg_Quit); + + EXPECT_TRUE(WaitForClientShutdown()); + channel_proxy.reset(); + + io_thread_.reset(); + } + + void RunTestChannelProxySyncPing() { + io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart)); + + Init("MojoPerfTestClient"); + + // Set up IPC channel and start client. + PerformanceChannelListener listener("ChannelProxy"); + auto channel_proxy = IPC::ChannelProxy::Create( + TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener, + io_thread_->task_runner()); + listener.Init(channel_proxy.get()); + + LockThreadAffinity thread_locker(kSharedCore); + std::vector<PingPongTestParams> params = GetDefaultTestParams(); + for (size_t i = 0; i < params.size(); i++) { + listener.SetTestParams(params[i].message_count(), + params[i].message_size(), true); + + // This initial message will kick-start the ping-pong of messages. + channel_proxy->Send(new TestMsg_Hello); + + // Run message loop. + base::RunLoop().Run(); + } + + // Send quit message. + channel_proxy->Send(new TestMsg_Quit); + + EXPECT_TRUE(WaitForClientShutdown()); + channel_proxy.reset(); + + io_thread_.reset(); + } + + scoped_refptr<base::TaskRunner> io_task_runner() { + if (io_thread_) + return io_thread_->task_runner(); + return base::ThreadTaskRunnerHandle::Get(); + } + + private: + std::unique_ptr<base::TestIOThread> io_thread_; +}; + +TEST_F(MojoChannelPerfTest, ChannelProxyPingPong) { + RunTestChannelProxyPingPong(); + + base::RunLoop run_loop; + run_loop.RunUntilIdle(); +} + +TEST_F(MojoChannelPerfTest, ChannelProxySyncPing) { + RunTestChannelProxySyncPing(); + + base::RunLoop run_loop; + run_loop.RunUntilIdle(); +} + +class MojoPerfTestClient { + public: + MojoPerfTestClient() : listener_(new ChannelReflectorListener()) { + mojo::edk::test::MultiprocessTestHelper::ChildSetup(); + } + + ~MojoPerfTestClient() = default; + + int Run(MojoHandle handle) { + handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle)); + LockThreadAffinity thread_locker(kSharedCore); + base::TestIOThread io_thread(base::TestIOThread::kAutoStart); + + std::unique_ptr<ChannelProxy> channel = + IPC::ChannelProxy::Create(handle_.release(), Channel::MODE_CLIENT, + listener_.get(), io_thread.task_runner()); + listener_->Init(channel.get()); + + base::RunLoop().Run(); + return 0; + } + + private: + base::MessageLoop main_message_loop_; + std::unique_ptr<ChannelReflectorListener> listener_; + std::unique_ptr<Channel> channel_; + mojo::ScopedMessagePipeHandle handle_; +}; + +MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) { + MojoPerfTestClient client; + int rv = mojo::edk::test::MultiprocessTestHelper::RunClientMain( + base::Bind(&MojoPerfTestClient::Run, base::Unretained(&client)), + true /* pass_pipe_ownership_to_main */); + + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + + return rv; +} + +class ReflectorImpl : public IPC::mojom::Reflector { + public: + explicit ReflectorImpl(mojo::ScopedMessagePipeHandle handle) + : binding_(this, IPC::mojom::ReflectorRequest(std::move(handle))) {} + ~ReflectorImpl() override { + ignore_result(binding_.Unbind().PassMessagePipe().release()); + } + + private: + // IPC::mojom::Reflector: + void Ping(const std::string& value, PingCallback callback) override { + std::move(callback).Run(value); + } + + void SyncPing(const std::string& value, PingCallback callback) override { + std::move(callback).Run(value); + } + + void Quit() override { base::MessageLoop::current()->QuitWhenIdle(); } + + mojo::Binding<IPC::mojom::Reflector> binding_; +}; + +class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase { + public: + MojoInterfacePerfTest() : message_count_(0), count_down_(0) {} + + protected: + void RunPingPongServer(MojoHandle mp, const std::string& label) { + label_ = label; + + mojo::MessagePipeHandle mp_handle(mp); + mojo::ScopedMessagePipeHandle scoped_mp(mp_handle); + ping_receiver_.Bind(IPC::mojom::ReflectorPtrInfo(std::move(scoped_mp), 0u)); + + LockThreadAffinity thread_locker(kSharedCore); + std::vector<PingPongTestParams> params = GetDefaultTestParams(); + for (size_t i = 0; i < params.size(); i++) { + ping_receiver_->Ping("hello", base::Bind(&MojoInterfacePerfTest::OnPong, + base::Unretained(this))); + message_count_ = count_down_ = params[i].message_count(); + payload_ = std::string(params[i].message_size(), 'a'); + + base::RunLoop().Run(); + } + + ping_receiver_->Quit(); + + ignore_result(ping_receiver_.PassInterface().PassHandle().release()); + } + + void OnPong(const std::string& value) { + if (value == "hello") { + DCHECK(!perf_logger_.get()); + std::string test_name = + base::StringPrintf("IPC_%s_Perf_%dx_%zu", label_.c_str(), + message_count_, payload_.size()); + perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); + } else { + DCHECK_EQ(payload_.size(), value.size()); + + CHECK(count_down_ > 0); + count_down_--; + if (count_down_ == 0) { + perf_logger_.reset(); + base::MessageLoop::current()->QuitWhenIdle(); + return; + } + } + + if (sync_) { + for (int i = 0; i < count_down_; ++i) { + std::string response; + ping_receiver_->SyncPing(payload_, &response); + } + base::MessageLoop::current()->QuitWhenIdle(); + } else { + ping_receiver_->Ping(payload_, base::Bind(&MojoInterfacePerfTest::OnPong, + base::Unretained(this))); + } + } + + static int RunPingPongClient(MojoHandle mp) { + mojo::MessagePipeHandle mp_handle(mp); + mojo::ScopedMessagePipeHandle scoped_mp(mp_handle); + + // In single process mode, this is running in a task and by default other + // tasks (in particular, the binding) won't run. To keep the single process + // and multi-process code paths the same, enable nestable tasks. + base::MessageLoop::ScopedNestableTaskAllower nest_loop( + base::MessageLoop::current()); + + LockThreadAffinity thread_locker(kSharedCore); + ReflectorImpl impl(std::move(scoped_mp)); + base::RunLoop().Run(); + return 0; + } + + bool sync_ = false; + + private: + int message_count_; + int count_down_; + std::string label_; + std::string payload_; + IPC::mojom::ReflectorPtr ping_receiver_; + std::unique_ptr<base::PerfTimeLogger> perf_logger_; + + DISALLOW_COPY_AND_ASSIGN(MojoInterfacePerfTest); +}; + +enum class InProcessMessageMode { + kSerialized, + kUnserialized, +}; + +class MojoInProcessInterfacePerfTest + : public MojoInterfacePerfTest, + public testing::WithParamInterface<InProcessMessageMode> { + public: + MojoInProcessInterfacePerfTest() { + switch (GetParam()) { + case InProcessMessageMode::kSerialized: + mojo::Connector::OverrideDefaultSerializationBehaviorForTesting( + mojo::Connector::OutgoingSerializationMode::kEager, + mojo::Connector::IncomingSerializationMode::kDispatchAsIs); + break; + case InProcessMessageMode::kUnserialized: + mojo::Connector::OverrideDefaultSerializationBehaviorForTesting( + mojo::Connector::OutgoingSerializationMode::kLazy, + mojo::Connector::IncomingSerializationMode::kDispatchAsIs); + break; + } + } +}; + +DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoInterfacePerfTest, h) { + base::MessageLoop main_message_loop; + return RunPingPongClient(h); +} + +// Similar to MojoChannelPerfTest above, but uses a Mojo interface instead of +// raw IPC::Messages. +TEST_F(MojoInterfacePerfTest, MultiprocessPingPong) { + RunTestClient("PingPongClient", [&](MojoHandle h) { + base::MessageLoop main_message_loop; + RunPingPongServer(h, "Multiprocess"); + }); +} + +TEST_F(MojoInterfacePerfTest, MultiprocessSyncPing) { + sync_ = true; + RunTestClient("PingPongClient", [&](MojoHandle h) { + base::MessageLoop main_message_loop; + RunPingPongServer(h, "MultiprocessSync"); + }); +} + +// A single process version of the above test. +TEST_P(MojoInProcessInterfacePerfTest, MultiThreadPingPong) { + MojoHandle server_handle, client_handle; + CreateMessagePipe(&server_handle, &client_handle); + + base::Thread client_thread("PingPongClient"); + client_thread.Start(); + client_thread.task_runner()->PostTask( + FROM_HERE, + base::Bind(base::IgnoreResult(&RunPingPongClient), client_handle)); + + base::MessageLoop main_message_loop; + RunPingPongServer(server_handle, "SingleProcess"); +} + +TEST_P(MojoInProcessInterfacePerfTest, SingleThreadPingPong) { + MojoHandle server_handle, client_handle; + CreateMessagePipe(&server_handle, &client_handle); + + base::MessageLoop main_message_loop; + mojo::MessagePipeHandle mp_handle(client_handle); + mojo::ScopedMessagePipeHandle scoped_mp(mp_handle); + LockThreadAffinity thread_locker(kSharedCore); + ReflectorImpl impl(std::move(scoped_mp)); + + RunPingPongServer(server_handle, "SingleProcess"); +} + +INSTANTIATE_TEST_CASE_P(, + MojoInProcessInterfacePerfTest, + testing::Values(InProcessMessageMode::kSerialized, + InProcessMessageMode::kUnserialized)); + +class CallbackPerfTest : public testing::Test { + public: + CallbackPerfTest() + : client_thread_("PingPongClient"), message_count_(0), count_down_(0) {} + + protected: + void RunMultiThreadPingPongServer() { + client_thread_.Start(); + + LockThreadAffinity thread_locker(kSharedCore); + std::vector<PingPongTestParams> params = GetDefaultTestParams(); + for (size_t i = 0; i < params.size(); i++) { + std::string hello("hello"); + client_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&CallbackPerfTest::Ping, base::Unretained(this), hello)); + message_count_ = count_down_ = params[i].message_count(); + payload_ = std::string(params[i].message_size(), 'a'); + + base::RunLoop().Run(); + } + } + + void Ping(const std::string& value) { + main_message_loop_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&CallbackPerfTest::OnPong, base::Unretained(this), value)); + } + + void OnPong(const std::string& value) { + if (value == "hello") { + DCHECK(!perf_logger_.get()); + std::string test_name = + base::StringPrintf("Callback_MultiProcess_Perf_%dx_%zu", + message_count_, payload_.size()); + perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); + } else { + DCHECK_EQ(payload_.size(), value.size()); + + CHECK(count_down_ > 0); + count_down_--; + if (count_down_ == 0) { + perf_logger_.reset(); + base::MessageLoop::current()->QuitWhenIdle(); + return; + } + } + + client_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&CallbackPerfTest::Ping, base::Unretained(this), payload_)); + } + + void RunSingleThreadNoPostTaskPingPongServer() { + LockThreadAffinity thread_locker(kSharedCore); + std::vector<PingPongTestParams> params = GetDefaultTestParams(); + base::Callback<void(const std::string&, + const base::Callback<void(const std::string&)>&)> + ping = base::Bind(&CallbackPerfTest::SingleThreadPingNoPostTask, + base::Unretained(this)); + for (size_t i = 0; i < params.size(); i++) { + payload_ = std::string(params[i].message_size(), 'a'); + std::string test_name = + base::StringPrintf("Callback_SingleThreadPostTask_Perf_%dx_%zu", + params[i].message_count(), payload_.size()); + perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); + for (int j = 0; j < params[i].message_count(); ++j) { + ping.Run(payload_, + base::Bind(&CallbackPerfTest::SingleThreadPongNoPostTask, + base::Unretained(this))); + } + perf_logger_.reset(); + } + } + + void SingleThreadPingNoPostTask( + const std::string& value, + const base::Callback<void(const std::string&)>& pong) { + pong.Run(value); + } + + void SingleThreadPongNoPostTask(const std::string& value) {} + + void RunSingleThreadPostTaskPingPongServer() { + LockThreadAffinity thread_locker(kSharedCore); + std::vector<PingPongTestParams> params = GetDefaultTestParams(); + for (size_t i = 0; i < params.size(); i++) { + std::string hello("hello"); + base::MessageLoop::current()->task_runner()->PostTask( + FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask, + base::Unretained(this), hello)); + message_count_ = count_down_ = params[i].message_count(); + payload_ = std::string(params[i].message_size(), 'a'); + + base::RunLoop().Run(); + } + } + + void SingleThreadPingPostTask(const std::string& value) { + base::MessageLoop::current()->task_runner()->PostTask( + FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPongPostTask, + base::Unretained(this), value)); + } + + void SingleThreadPongPostTask(const std::string& value) { + if (value == "hello") { + DCHECK(!perf_logger_.get()); + std::string test_name = + base::StringPrintf("Callback_SingleThreadNoPostTask_Perf_%dx_%zu", + message_count_, payload_.size()); + perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); + } else { + DCHECK_EQ(payload_.size(), value.size()); + + CHECK(count_down_ > 0); + count_down_--; + if (count_down_ == 0) { + perf_logger_.reset(); + base::MessageLoop::current()->QuitWhenIdle(); + return; + } + } + + base::MessageLoop::current()->task_runner()->PostTask( + FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask, + base::Unretained(this), payload_)); + } + + private: + base::Thread client_thread_; + base::MessageLoop main_message_loop_; + int message_count_; + int count_down_; + std::string payload_; + std::unique_ptr<base::PerfTimeLogger> perf_logger_; + + DISALLOW_COPY_AND_ASSIGN(CallbackPerfTest); +}; + +// Sends the same data as above using PostTask to a different thread instead of +// IPCs for comparison. +TEST_F(CallbackPerfTest, MultiThreadPingPong) { + RunMultiThreadPingPongServer(); +} + +// Sends the same data as above using PostTask to the same thread. +TEST_F(CallbackPerfTest, SingleThreadPostTaskPingPong) { + RunSingleThreadPostTaskPingPongServer(); +} + +// Sends the same data as above without using PostTask to the same thread. +TEST_F(CallbackPerfTest, SingleThreadNoPostTaskPingPong) { + RunSingleThreadNoPostTaskPingPongServer(); +} + +} // namespace +} // namespace IPC
diff --git a/ipc/ipc_test.mojom b/ipc/ipc_test.mojom index 8af397a..33181b8 100644 --- a/ipc/ipc_test.mojom +++ b/ipc/ipc_test.mojom
@@ -31,6 +31,8 @@ interface Reflector { Ping(string value) => (string value); + [Sync] + SyncPing(string value) => (string response); Quit(); };
diff --git a/mash/test/mash_test_suite.cc b/mash/test/mash_test_suite.cc index a7783011..9b0d6684 100644 --- a/mash/test/mash_test_suite.cc +++ b/mash/test/mash_test_suite.cc
@@ -10,8 +10,8 @@ #include "base/files/file_path.h" #include "base/memory/ptr_util.h" #include "base/path_service.h" -#include "cc/output/context_provider.h" #include "cc/surfaces/surface_manager.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "ui/aura/env.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc index 7ef340b6..b4cd8b5a 100644 --- a/media/filters/ffmpeg_demuxer_unittest.cc +++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -1660,4 +1660,32 @@ CheckStreamStatusNotifications(demuxer_.get(), video_stream); } +TEST_F(FFmpegDemuxerTest, MultitrackMemoryUsage) { + CreateDemuxer("multitrack-3video-2audio.webm"); + InitializeDemuxer(); + + DemuxerStream* audio = GetStream(DemuxerStream::AUDIO); + + // Read from the audio stream to make sure FFmpegDemuxer buffers data for all + // streams with available capacity, i.e all enabled streams. By default only + // the first audio and the first video stream are enabled, so the memory usage + // shouldn't be too high. + audio->Read(NewReadCB(FROM_HERE, 304, 0, true)); + base::RunLoop().Run(); + EXPECT_EQ(22134, demuxer_->GetMemoryUsage()); + + // Now enable all demuxer streams in the file and perform another read, this + // will buffer the data for additional streams and memory usage will increase. + std::vector<DemuxerStream*> streams = demuxer_->GetAllStreams(); + for (auto* stream : streams) + static_cast<FFmpegDemuxerStream*>(stream)->SetEnabled(true, + base::TimeDelta()); + + audio->Read(NewReadCB(FROM_HERE, 166, 21000, true)); + base::RunLoop().Run(); + // With newly enabled demuxer streams the amount of memory used by the demuxer + // is much higher. + EXPECT_EQ(156011, demuxer_->GetMemoryUsage()); +} + } // namespace media
diff --git a/mojo/edk/embedder/entrypoints.cc b/mojo/edk/embedder/entrypoints.cc index 9412b79a..d1a6b1a0 100644 --- a/mojo/edk/embedder/entrypoints.cc +++ b/mojo/edk/embedder/entrypoints.cc
@@ -59,10 +59,8 @@ return g_core->CancelWatch(watcher_handle, context); } -MojoResult MojoCreateMessageImpl(uintptr_t context, - const MojoMessageOperationThunks* thunks, - MojoMessageHandle* message) { - return g_core->CreateMessage(context, thunks, message); +MojoResult MojoCreateMessageImpl(MojoMessageHandle* message) { + return g_core->CreateMessage(message); } MojoResult MojoDestroyMessageImpl(MojoMessageHandle message) { @@ -73,6 +71,24 @@ return g_core->SerializeMessage(message); } +MojoResult MojoAttachSerializedMessageBufferImpl(MojoMessageHandle message, + uint32_t payload_size, + const MojoHandle* handles, + uint32_t num_handles, + void** buffer, + uint32_t* buffer_size) { + return g_core->AttachSerializedMessageBuffer( + message, payload_size, handles, num_handles, buffer, buffer_size); +} + +MojoResult MojoExtendSerializedMessagePayloadImpl(MojoMessageHandle message, + uint32_t new_payload_size, + void** new_buffer, + uint32_t* new_buffer_size) { + return g_core->ExtendSerializedMessagePayload(message, new_payload_size, + new_buffer, new_buffer_size); +} + MojoResult MojoGetSerializedMessageContentsImpl( MojoMessageHandle message, void** buffer, @@ -84,6 +100,14 @@ handles, num_handles, flags); } +MojoResult MojoAttachMessageContextImpl( + MojoMessageHandle message, + uintptr_t context, + MojoMessageContextSerializer serializer, + MojoMessageContextDestructor destructor) { + return g_core->AttachMessageContext(message, context, serializer, destructor); +} + MojoResult MojoGetMessageContextImpl(MojoMessageHandle message, uintptr_t* context, MojoGetMessageContextFlags flags) { @@ -262,7 +286,10 @@ MojoCreateMessageImpl, MojoDestroyMessageImpl, MojoSerializeMessageImpl, + MojoAttachSerializedMessageBufferImpl, + MojoExtendSerializedMessagePayloadImpl, MojoGetSerializedMessageContentsImpl, + MojoAttachMessageContextImpl, MojoGetMessageContextImpl, MojoWrapPlatformHandleImpl, MojoUnwrapPlatformHandleImpl,
diff --git a/mojo/edk/system/channel.cc b/mojo/edk/system/channel.cc index bfec79f..09be3b6 100644 --- a/mojo/edk/system/channel.cc +++ b/mojo/edk/system/channel.cc
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/memory/aligned_memory.h" +#include "base/numerics/safe_math.h" #include "base/process/process_handle.h" #include "mojo/edk/embedder/embedder_internal.h" #include "mojo/edk/embedder/platform_handle.h" @@ -55,18 +56,30 @@ const size_t kMaxAttachedHandles = 128; Channel::Message::Message(size_t payload_size, size_t max_handles) -#if defined(MOJO_EDK_LEGACY_PROTOCOL) - : Message(payload_size, max_handles, MessageType::NORMAL_LEGACY) { -} -#else - : Message(payload_size, max_handles, MessageType::NORMAL) { -} -#endif + : Message(payload_size, payload_size, max_handles) {} Channel::Message::Message(size_t payload_size, size_t max_handles, MessageType message_type) + : Message(payload_size, payload_size, max_handles, message_type) {} + +Channel::Message::Message(size_t capacity, + size_t payload_size, + size_t max_handles) +#if defined(MOJO_EDK_LEGACY_PROTOCOL) + : Message(capacity, payload_size, max_handles, MessageType::NORMAL_LEGACY) { +} +#else + : Message(capacity, payload_size, max_handles, MessageType::NORMAL) { +} +#endif + +Channel::Message::Message(size_t capacity, + size_t payload_size, + size_t max_handles, + MessageType message_type) : max_handles_(max_handles) { + DCHECK_GE(capacity, payload_size); DCHECK_LE(max_handles_, kMaxAttachedHandles); const bool is_legacy_message = (message_type == MessageType::NORMAL_LEGACY); @@ -94,9 +107,10 @@ is_legacy_message ? sizeof(LegacyHeader) : sizeof(Header); DCHECK(extra_header_size == 0 || !is_legacy_message); + capacity_ = header_size + extra_header_size + capacity; size_ = header_size + extra_header_size + payload_size; - data_ = static_cast<char*>(base::AlignedAlloc(size_, - kChannelMessageAlignment)); + data_ = static_cast<char*>( + base::AlignedAlloc(capacity_, kChannelMessageAlignment)); // Only zero out the header and not the payload. Since the payload is going to // be memcpy'd, zeroing the payload is unnecessary work and a significant // performance issue when dealing with large messages. Any sanitizer errors @@ -104,11 +118,11 @@ // treated as an error and fixed. memset(data_, 0, header_size + extra_header_size); - DCHECK_LE(size_, std::numeric_limits<uint32_t>::max()); + DCHECK(base::IsValueInRangeForNumericType<uint32_t>(size_)); legacy_header()->num_bytes = static_cast<uint32_t>(size_); - DCHECK_LE(header_size + extra_header_size, - std::numeric_limits<uint16_t>::max()); + DCHECK(base::IsValueInRangeForNumericType<uint16_t>(header_size + + extra_header_size)); legacy_header()->message_type = message_type; if (is_legacy_message) { @@ -238,6 +252,29 @@ return message; } +size_t Channel::Message::capacity() const { + if (is_legacy_message()) + return capacity_ - sizeof(LegacyHeader); + return capacity_ - header()->num_header_bytes; +} + +void Channel::Message::ExtendPayload(size_t new_payload_size) { + size_t capacity_without_header = capacity(); + size_t header_size = capacity_ - capacity_without_header; + if (new_payload_size > capacity_without_header) { + size_t new_capacity = + std::max(capacity_without_header * 2, new_payload_size) + header_size; + void* new_data = base::AlignedAlloc(new_capacity, kChannelMessageAlignment); + memcpy(new_data, data_, size_); + base::AlignedFree(data_); + data_ = static_cast<char*>(new_data); + capacity_ = new_capacity; + } + size_ = header_size + new_payload_size; + DCHECK(base::IsValueInRangeForNumericType<uint32_t>(size_)); + legacy_header()->num_bytes = static_cast<uint32_t>(size_); +} + const void* Channel::Message::extra_header() const { DCHECK(!is_legacy_message()); return data_ + sizeof(Header);
diff --git a/mojo/edk/system/channel.h b/mojo/edk/system/channel.h index cc3fa96..667a00c6 100644 --- a/mojo/edk/system/channel.h +++ b/mojo/edk/system/channel.h
@@ -124,6 +124,11 @@ // |payload_size| bytes plus a header, plus |max_handles| platform handles. Message(size_t payload_size, size_t max_handles); Message(size_t payload_size, size_t max_handles, MessageType message_type); + Message(size_t capacity, size_t payload_size, size_t max_handles); + Message(size_t capacity, + size_t max_handles, + size_t payload_size, + MessageType message_type); ~Message(); // Constructs a Message from serialized message data. @@ -132,6 +137,18 @@ const void* data() const { return data_; } size_t data_num_bytes() const { return size_; } + // The current capacity of the message buffer, not counting internal header + // data. + size_t capacity() const; + + // Extends the portion of the total message capacity which contains + // meaningful payload data. Storage capacity which falls outside of this + // range is not transmitted when the message is sent. + // + // If the message's current capacity is not large enough to accommodate the + // new payload size, it will be reallocated accordingly. + void ExtendPayload(size_t new_payload_size); + const void* extra_header() const; void* mutable_extra_header(); size_t extra_header_size() const; @@ -174,10 +191,20 @@ void SetVersionForTest(uint16_t version_number); private: - size_t size_ = 0; - size_t max_handles_ = 0; + // The message data buffer. char* data_ = nullptr; + // The capacity of the buffer at |data_|. + size_t capacity_ = 0; + + // The size of the message. This is the portion of |data_| that should + // be transmitted if the message is written to a channel. Includes all + // headers and user payload. + size_t size_ = 0; + + // Maximum number of handles which may be attached to this message. + size_t max_handles_ = 0; + ScopedPlatformHandleVectorPtr handle_vector_; #if defined(OS_WIN)
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc index 168bbf4..8b9f4c4b 100644 --- a/mojo/edk/system/core.cc +++ b/mojo/edk/system/core.cc
@@ -462,24 +462,11 @@ ready_signals_states); } -MojoResult Core::CreateMessage(uintptr_t context, - const MojoMessageOperationThunks* thunks, - MojoMessageHandle* message_handle) { - if (!message_handle || !context) +MojoResult Core::CreateMessage(MojoMessageHandle* message_handle) { + if (!message_handle) return MOJO_RESULT_INVALID_ARGUMENT; - - if (thunks) { - if (thunks->struct_size != sizeof(MojoMessageOperationThunks)) - return MOJO_RESULT_INVALID_ARGUMENT; - - if (!thunks->get_serialized_size || !thunks->serialize_handles || - !thunks->serialize_payload || !thunks->destroy) - return MOJO_RESULT_INVALID_ARGUMENT; - } - *message_handle = reinterpret_cast<MojoMessageHandle>( - UserMessageImpl::CreateEventForNewMessageWithContext(context, thunks) - .release()); + UserMessageImpl::CreateEventForNewMessage().release()); return MOJO_RESULT_OK; } @@ -501,6 +488,46 @@ ->SerializeIfNecessary(); } +MojoResult Core::AttachSerializedMessageBuffer(MojoMessageHandle message_handle, + uint32_t payload_size, + const MojoHandle* handles, + uint32_t num_handles, + void** buffer, + uint32_t* buffer_size) { + if (!message_handle || (num_handles && !handles) || !buffer || !buffer_size) + return MOJO_RESULT_INVALID_ARGUMENT; + auto* message = reinterpret_cast<ports::UserMessageEvent*>(message_handle) + ->GetMessage<UserMessageImpl>(); + MojoResult rv = message->AttachSerializedMessageBuffer(payload_size, handles, + num_handles); + if (rv != MOJO_RESULT_OK) + return rv; + + *buffer = message->user_payload(); + *buffer_size = + base::checked_cast<uint32_t>(message->user_payload_buffer_size()); + return MOJO_RESULT_OK; +} + +MojoResult Core::ExtendSerializedMessagePayload( + MojoMessageHandle message_handle, + uint32_t new_payload_size, + void** new_buffer, + uint32_t* new_buffer_size) { + if (!message_handle || !new_buffer || !new_buffer_size) + return MOJO_RESULT_INVALID_ARGUMENT; + auto* message = reinterpret_cast<ports::UserMessageEvent*>(message_handle) + ->GetMessage<UserMessageImpl>(); + MojoResult rv = message->ExtendSerializedMessagePayload(new_payload_size); + if (rv != MOJO_RESULT_OK) + return rv; + + *new_buffer = message->user_payload(); + *new_buffer_size = + base::checked_cast<uint32_t>(message->user_payload_buffer_size()); + return MOJO_RESULT_OK; +} + MojoResult Core::GetSerializedMessageContents( MojoMessageHandle message_handle, void** buffer, @@ -546,6 +573,17 @@ UserMessageImpl::ExtractBadHandlePolicy::kAbort, handles); } +MojoResult Core::AttachMessageContext(MojoMessageHandle message_handle, + uintptr_t context, + MojoMessageContextSerializer serializer, + MojoMessageContextDestructor destructor) { + if (!message_handle || !context) + return MOJO_RESULT_INVALID_ARGUMENT; + auto* message = reinterpret_cast<ports::UserMessageEvent*>(message_handle) + ->GetMessage<UserMessageImpl>(); + return message->AttachContext(context, serializer, destructor); +} + MojoResult Core::GetMessageContext(MojoMessageHandle message_handle, uintptr_t* context, MojoGetMessageContextFlags flags) {
diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h index ba98af5c..4b936a5 100644 --- a/mojo/edk/system/core.h +++ b/mojo/edk/system/core.h
@@ -191,11 +191,19 @@ uintptr_t* ready_contexts, MojoResult* ready_results, MojoHandleSignalsState* ready_signals_states); - MojoResult CreateMessage(uintptr_t context, - const MojoMessageOperationThunks* thunks, - MojoMessageHandle* message_handle); + MojoResult CreateMessage(MojoMessageHandle* message_handle); MojoResult DestroyMessage(MojoMessageHandle message_handle); MojoResult SerializeMessage(MojoMessageHandle message_handle); + MojoResult AttachSerializedMessageBuffer(MojoMessageHandle message_handle, + uint32_t payload_size, + const MojoHandle* handles, + uint32_t num_handles, + void** buffer, + uint32_t* buffer_size); + MojoResult ExtendSerializedMessagePayload(MojoMessageHandle message_handle, + uint32_t new_payload_size, + void** new_buffer, + uint32_t* new_buffer_size); MojoResult GetSerializedMessageContents( MojoMessageHandle message_handle, void** buffer, @@ -203,6 +211,10 @@ MojoHandle* handles, uint32_t* num_handles, MojoGetSerializedMessageContentsFlags flags); + MojoResult AttachMessageContext(MojoMessageHandle message_handle, + uintptr_t context, + MojoMessageContextSerializer serializer, + MojoMessageContextDestructor destructor); MojoResult GetMessageContext(MojoMessageHandle message_handle, uintptr_t* context, MojoGetMessageContextFlags flags);
diff --git a/mojo/edk/system/core_unittest.cc b/mojo/edk/system/core_unittest.cc index 159a47cc..f4747b05 100644 --- a/mojo/edk/system/core_unittest.cc +++ b/mojo/edk/system/core_unittest.cc
@@ -30,28 +30,6 @@ using CoreTest = test::CoreTestBase; -void UnusedGetSerializedSize(uintptr_t context, - size_t* num_bytes, - size_t* num_handles) {} -void UnusedSerializeHandles(uintptr_t context, MojoHandle* handles) {} -void UnusedSerializePayload(uintptr_t context, void* buffer) {} -void IgnoreDestroyMessage(uintptr_t context) {} - -const MojoMessageOperationThunks kUnusedMessageThunks = { - sizeof(MojoMessageOperationThunks), - &UnusedGetSerializedSize, - &UnusedSerializeHandles, - &UnusedSerializePayload, - &IgnoreDestroyMessage, -}; - -MojoMessageHandle CreateTestMessageHandle(Core* core, uintptr_t context) { - MojoMessageHandle handle; - CHECK_EQ(MOJO_RESULT_OK, - core->CreateMessage(context, &kUnusedMessageThunks, &handle)); - return handle; -} - TEST_F(CoreTest, GetTimeTicksNow) { const MojoTimeTicks start = core()->GetTimeTicksNow(); ASSERT_NE(static_cast<MojoTimeTicks>(0), start) @@ -73,10 +51,9 @@ ASSERT_EQ(0u, info.GetWriteMessageCallCount()); MojoMessageHandle message; - ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(42, nullptr, &message)); + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(&message)); ASSERT_EQ(MOJO_RESULT_OK, - core()->WriteMessage(h, CreateTestMessageHandle(core(), 42), - MOJO_WRITE_MESSAGE_FLAG_NONE)); + core()->WriteMessage(h, message, MOJO_WRITE_MESSAGE_FLAG_NONE)); ASSERT_EQ(1u, info.GetWriteMessageCallCount()); ASSERT_EQ(0u, info.GetReadMessageCallCount()); @@ -196,8 +173,10 @@ // Write to |h[1]|. const uintptr_t kTestMessageContext = 123; + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(&message)); ASSERT_EQ(MOJO_RESULT_OK, - core()->CreateMessage(kTestMessageContext, nullptr, &message)); + core()->AttachMessageContext(message, kTestMessageContext, nullptr, + nullptr)); ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h[1], message, MOJO_WRITE_MESSAGE_FLAG_NONE)); @@ -222,8 +201,10 @@ ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals); // Write to |h[0]|. + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(&message)); ASSERT_EQ(MOJO_RESULT_OK, - core()->CreateMessage(kTestMessageContext, nullptr, &message)); + core()->AttachMessageContext(message, kTestMessageContext, nullptr, + nullptr)); ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h[0], message, MOJO_WRITE_MESSAGE_FLAG_NONE)); @@ -259,8 +240,10 @@ EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[1].satisfiable_signals); // Try writing to |h[1]|. + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(&message)); ASSERT_EQ(MOJO_RESULT_OK, - core()->CreateMessage(kTestMessageContext, nullptr, &message)); + core()->AttachMessageContext(message, kTestMessageContext, nullptr, + nullptr)); ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->WriteMessage(h[1], message, MOJO_WRITE_MESSAGE_FLAG_NONE)); @@ -277,8 +260,10 @@ // Make sure that |h_passing[]| work properly. const uintptr_t kTestMessageContext = 42; MojoMessageHandle message; + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(&message)); ASSERT_EQ(MOJO_RESULT_OK, - core()->CreateMessage(kTestMessageContext, nullptr, &message)); + core()->AttachMessageContext(message, kTestMessageContext, nullptr, + nullptr)); ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passing[0], message, MOJO_WRITE_MESSAGE_FLAG_NONE)); hss = kEmptyMojoHandleSignalsState;
diff --git a/mojo/edk/system/message_unittest.cc b/mojo/edk/system/message_unittest.cc index c02c1ff..8e2b109 100644 --- a/mojo/edk/system/message_unittest.cc +++ b/mojo/edk/system/message_unittest.cc
@@ -8,6 +8,8 @@ #include <vector> #include "base/memory/ptr_util.h" +#include "base/numerics/safe_math.h" +#include "base/rand_util.h" #include "mojo/edk/test/mojo_test_base.h" #include "mojo/public/cpp/system/message_pipe.h" @@ -26,16 +28,16 @@ static MojoMessageHandle MakeMessageHandle( std::unique_ptr<TestMessageBase> message) { - MojoMessageOperationThunks thunks; - thunks.struct_size = sizeof(MojoMessageOperationThunks); - thunks.get_serialized_size = &CallGetSerializedSize; - thunks.serialize_handles = &CallSerializeHandles; - thunks.serialize_payload = &CallSerializePayload; - thunks.destroy = &Destroy; MojoMessageHandle handle; - MojoResult rv = MojoCreateMessage( - reinterpret_cast<uintptr_t>(message.release()), &thunks, &handle); + MojoResult rv = MojoCreateMessage(&handle); DCHECK_EQ(MOJO_RESULT_OK, rv); + + rv = MojoAttachMessageContext( + handle, reinterpret_cast<uintptr_t>(message.release()), + &TestMessageBase::SerializeMessageContext, + &TestMessageBase::DestroyMessageContext); + DCHECK_EQ(MOJO_RESULT_OK, rv); + return handle; } @@ -58,22 +60,28 @@ virtual void SerializePayload(void* buffer) = 0; private: - static void CallGetSerializedSize(uintptr_t context, - size_t* num_bytes, - size_t* num_handles) { - reinterpret_cast<TestMessageBase*>(context)->GetSerializedSize(num_bytes, - num_handles); + static void SerializeMessageContext(MojoMessageHandle message_handle, + uintptr_t context) { + auto* message = reinterpret_cast<TestMessageBase*>(context); + size_t num_bytes = 0; + size_t num_handles = 0; + message->GetSerializedSize(&num_bytes, &num_handles); + std::vector<MojoHandle> handles(num_handles); + if (num_handles) + message->SerializeHandles(handles.data()); + + void* buffer; + uint32_t buffer_size; + MojoResult rv = MojoAttachSerializedMessageBuffer( + message_handle, base::checked_cast<uint32_t>(num_bytes), handles.data(), + base::checked_cast<uint32_t>(num_handles), &buffer, &buffer_size); + DCHECK_EQ(MOJO_RESULT_OK, rv); + DCHECK_GE(buffer_size, base::checked_cast<uint32_t>(num_bytes)); + if (num_bytes) + message->SerializePayload(buffer); } - static void CallSerializeHandles(uintptr_t context, MojoHandle* handles) { - reinterpret_cast<TestMessageBase*>(context)->SerializeHandles(handles); - } - - static void CallSerializePayload(uintptr_t context, void* buffer) { - reinterpret_cast<TestMessageBase*>(context)->SerializePayload(buffer); - } - - static void Destroy(uintptr_t context) { + static void DestroyMessageContext(uintptr_t context) { delete reinterpret_cast<TestMessageBase*>(context); } }; @@ -156,10 +164,24 @@ MojoSerializeMessage(MOJO_MESSAGE_HANDLE_INVALID)); MojoMessageHandle message_handle; + void* buffer; + uint32_t buffer_size; + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoCreateMessage(nullptr)); + ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessage(&message_handle)); ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - MojoCreateMessage(0, nullptr, &message_handle)); + MojoAttachMessageContext(message_handle, 0, nullptr, nullptr)); ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - MojoCreateMessage(1234, nullptr, nullptr)); + MojoAttachSerializedMessageBuffer(message_handle, 0, nullptr, 0, + &buffer, nullptr)); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + MojoAttachSerializedMessageBuffer(message_handle, 0, nullptr, 0, + nullptr, &buffer_size)); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + MojoAttachSerializedMessageBuffer(message_handle, 0, nullptr, 0, + nullptr, nullptr)); + ASSERT_EQ(MOJO_RESULT_OK, + MojoAttachSerializedMessageBuffer(message_handle, 0, nullptr, 0, + &buffer, &buffer_size)); } TEST_F(MessageTest, SendLocalMessageWithContext) { @@ -221,6 +243,25 @@ }); } +TEST_F(MessageTest, SerializeDynamicallySizedMessage) { + RunTestClient("ReceiveMessageNoHandles", [&](MojoHandle h) { + MojoMessageHandle message; + EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessage(&message)); + + void* buffer; + uint32_t buffer_size; + EXPECT_EQ(MOJO_RESULT_OK, + MojoAttachSerializedMessageBuffer(message, 0, nullptr, 0, &buffer, + &buffer_size)); + EXPECT_EQ(MOJO_RESULT_OK, MojoExtendSerializedMessagePayload( + message, sizeof(kTestMessageWithContext1) - 1, + &buffer, &buffer_size)); + memcpy(buffer, kTestMessageWithContext1, + sizeof(kTestMessageWithContext1) - 1); + MojoWriteMessage(h, message, MOJO_WRITE_MESSAGE_FLAG_NONE); + }); +} + DEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReceiveMessageOneHandle, MessageTest, h) { MojoTestBase::WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE); MojoHandle h1; @@ -491,6 +532,178 @@ EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle)); } +TEST_F(MessageTest, ExtendMessagePayload) { + MojoMessageHandle message; + EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessage(&message)); + + const std::string kTestMessagePart1("hello i am message."); + void* buffer; + uint32_t buffer_size; + EXPECT_EQ(MOJO_RESULT_OK, + MojoAttachSerializedMessageBuffer( + message, static_cast<uint32_t>(kTestMessagePart1.size()), + nullptr, 0, &buffer, &buffer_size)); + ASSERT_GE(buffer_size, static_cast<uint32_t>(kTestMessagePart1.size())); + memcpy(buffer, kTestMessagePart1.data(), kTestMessagePart1.size()); + + void* payload; + uint32_t payload_size; + EXPECT_EQ(MOJO_RESULT_OK, + MojoGetSerializedMessageContents( + message, &payload, &payload_size, nullptr, nullptr, + MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE)); + EXPECT_EQ(kTestMessagePart1.size(), payload_size); + EXPECT_EQ( + 0, memcmp(payload, kTestMessagePart1.data(), kTestMessagePart1.size())); + + const std::string kTestMessagePart2 = " in ur computer."; + const std::string kTestMessageCombined1 = + kTestMessagePart1 + kTestMessagePart2; + EXPECT_EQ(MOJO_RESULT_OK, + MojoExtendSerializedMessagePayload( + message, static_cast<uint32_t>(kTestMessageCombined1.size()), + &buffer, &buffer_size)); + memcpy(static_cast<uint8_t*>(buffer) + kTestMessagePart1.size(), + kTestMessagePart2.data(), kTestMessagePart2.size()); + EXPECT_EQ(MOJO_RESULT_OK, + MojoGetSerializedMessageContents( + message, &payload, &payload_size, nullptr, nullptr, + MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE)); + EXPECT_EQ(kTestMessageCombined1.size(), payload_size); + EXPECT_EQ(0, memcmp(payload, kTestMessageCombined1.data(), + kTestMessageCombined1.size())); + + const std::string kTestMessagePart3 = kTestMessagePart2 + " carry ur bits."; + const std::string kTestMessageCombined2 = + kTestMessageCombined1 + kTestMessagePart3; + EXPECT_EQ(MOJO_RESULT_OK, + MojoExtendSerializedMessagePayload( + message, static_cast<uint32_t>(kTestMessageCombined2.size()), + &buffer, &buffer_size)); + memcpy(static_cast<uint8_t*>(buffer) + kTestMessageCombined1.size(), + kTestMessagePart3.data(), kTestMessagePart3.size()); + EXPECT_EQ(MOJO_RESULT_OK, + MojoGetSerializedMessageContents( + message, &payload, &payload_size, nullptr, nullptr, + MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE)); + EXPECT_EQ(kTestMessageCombined2.size(), payload_size); + EXPECT_EQ(0, memcmp(payload, kTestMessageCombined2.data(), + kTestMessageCombined2.size())); +} + +TEST_F(MessageTest, ExtendMessageWithHandlesPayload) { + MojoMessageHandle message; + EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessage(&message)); + + MojoHandle handles[2]; + CreateMessagePipe(&handles[0], &handles[1]); + + const std::string kTestMessagePart1("hello i am message."); + void* buffer; + uint32_t buffer_size; + EXPECT_EQ(MOJO_RESULT_OK, + MojoAttachSerializedMessageBuffer( + message, static_cast<uint32_t>(kTestMessagePart1.size()), + handles, 2, &buffer, &buffer_size)); + ASSERT_GE(buffer_size, static_cast<uint32_t>(kTestMessagePart1.size())); + memcpy(buffer, kTestMessagePart1.data(), kTestMessagePart1.size()); + + const std::string kTestMessagePart2 = " in ur computer."; + const std::string kTestMessageCombined1 = + kTestMessagePart1 + kTestMessagePart2; + EXPECT_EQ(MOJO_RESULT_OK, + MojoExtendSerializedMessagePayload( + message, static_cast<uint32_t>(kTestMessageCombined1.size()), + &buffer, &buffer_size)); + memcpy(static_cast<uint8_t*>(buffer) + kTestMessagePart1.size(), + kTestMessagePart2.data(), kTestMessagePart2.size()); + + void* payload; + uint32_t payload_size; + uint32_t num_handles = 2; + EXPECT_EQ(MOJO_RESULT_OK, + MojoGetSerializedMessageContents( + message, &payload, &payload_size, handles, &num_handles, + MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE)); + EXPECT_EQ(2u, num_handles); + EXPECT_EQ(kTestMessageCombined1.size(), payload_size); + EXPECT_EQ(0, memcmp(payload, kTestMessageCombined1.data(), + kTestMessageCombined1.size())); + + EXPECT_EQ(MOJO_RESULT_OK, MojoClose(handles[0])); + EXPECT_EQ(MOJO_RESULT_OK, MojoClose(handles[1])); +} + +TEST_F(MessageTest, ExtendMessagePayloadLarge) { + // We progressively extend a message payload from small to large using various + // chunk sizes to test potentially interesting boundary conditions. + constexpr size_t kTestChunkSizes[] = {1, 2, 3, 64, 509, 4096, 16384, 65535}; + for (const size_t kChunkSize : kTestChunkSizes) { + MojoMessageHandle message; + EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessage(&message)); + + MojoHandle handles[2]; + CreateMessagePipe(&handles[0], &handles[1]); + + const std::string kTestMessageHeader("hey pretend i'm a header"); + void* buffer; + uint32_t buffer_size; + EXPECT_EQ(MOJO_RESULT_OK, + MojoAttachSerializedMessageBuffer( + message, static_cast<uint32_t>(kTestMessageHeader.size()), + handles, 2, &buffer, &buffer_size)); + ASSERT_GE(buffer_size, static_cast<uint32_t>(kTestMessageHeader.size())); + memcpy(buffer, kTestMessageHeader.data(), kTestMessageHeader.size()); + + // 5 MB should be well beyond any reasonable default buffer size for the + // system implementation to choose, meaning that this test should guarantee + // several reallocations of the serialized message buffer as we + // progressively extend the payload to this size. + constexpr size_t kTestMessagePayloadSize = 5 * 1024 * 1024; + std::vector<uint8_t> test_payload(kTestMessagePayloadSize); + base::RandBytes(test_payload.data(), kTestMessagePayloadSize); + + size_t current_payload_size = 0; + while (current_payload_size < kTestMessagePayloadSize) { + const size_t previous_payload_size = current_payload_size; + current_payload_size = + std::min(current_payload_size + kChunkSize, kTestMessagePayloadSize); + const size_t current_chunk_size = + current_payload_size - previous_payload_size; + const size_t previous_total_size = + kTestMessageHeader.size() + previous_payload_size; + const size_t current_total_size = + kTestMessageHeader.size() + current_payload_size; + EXPECT_EQ(MOJO_RESULT_OK, + MojoExtendSerializedMessagePayload( + message, static_cast<uint32_t>(current_total_size), &buffer, + &buffer_size)); + EXPECT_GE(buffer_size, static_cast<uint32_t>(current_total_size)); + memcpy(static_cast<uint8_t*>(buffer) + previous_total_size, + &test_payload[previous_payload_size], current_chunk_size); + } + + void* payload; + uint32_t payload_size; + uint32_t num_handles = 2; + EXPECT_EQ(MOJO_RESULT_OK, + MojoGetSerializedMessageContents( + message, &payload, &payload_size, handles, &num_handles, + MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE)); + EXPECT_EQ(static_cast<uint32_t>(kTestMessageHeader.size() + + kTestMessagePayloadSize), + payload_size); + EXPECT_EQ(0, memcmp(payload, kTestMessageHeader.data(), + kTestMessageHeader.size())); + EXPECT_EQ(0, + memcmp(static_cast<uint8_t*>(payload) + kTestMessageHeader.size(), + test_payload.data(), kTestMessagePayloadSize)); + + EXPECT_EQ(MOJO_RESULT_OK, MojoClose(handles[0])); + EXPECT_EQ(MOJO_RESULT_OK, MojoClose(handles[1])); + } +} + } // namespace } // namespace edk } // namespace mojo
diff --git a/mojo/edk/system/node_channel.cc b/mojo/edk/system/node_channel.cc index 7e7bdc2..1c4f327 100644 --- a/mojo/edk/system/node_channel.cc +++ b/mojo/edk/system/node_channel.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "mojo/edk/system/channel.h" #include "mojo/edk/system/request_context.h" @@ -127,9 +128,15 @@ Channel::MessagePtr CreateMessage(MessageType type, size_t payload_size, size_t num_handles, - DataType** out_data) { - Channel::MessagePtr message( - new Channel::Message(sizeof(Header) + payload_size, num_handles)); + DataType** out_data, + size_t capacity = 0) { + const size_t total_size = payload_size + sizeof(Header); + if (capacity == 0) + capacity = total_size; + else + capacity = std::max(total_size, capacity); + auto message = + base::MakeUnique<Channel::Message>(capacity, total_size, num_handles); Header* header = reinterpret_cast<Header*>(message->mutable_payload()); header->type = type; header->padding = 0; @@ -167,11 +174,12 @@ } // static -Channel::MessagePtr NodeChannel::CreateEventMessage(size_t payload_size, +Channel::MessagePtr NodeChannel::CreateEventMessage(size_t capacity, + size_t payload_size, void** payload, size_t num_handles) { return CreateMessage(MessageType::EVENT_MESSAGE, payload_size, num_handles, - payload); + payload, capacity); } // static
diff --git a/mojo/edk/system/node_channel.h b/mojo/edk/system/node_channel.h index c962c6b..b3eac19 100644 --- a/mojo/edk/system/node_channel.h +++ b/mojo/edk/system/node_channel.h
@@ -95,7 +95,8 @@ scoped_refptr<base::TaskRunner> io_task_runner, const ProcessErrorCallback& process_error_callback); - static Channel::MessagePtr CreateEventMessage(size_t payload_size, + static Channel::MessagePtr CreateEventMessage(size_t capacity, + size_t payload_size, void** payload, size_t num_handles);
diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc index 865ebb6..f0ca64b 100644 --- a/mojo/edk/system/node_controller.cc +++ b/mojo/edk/system/node_controller.cc
@@ -85,8 +85,8 @@ } void* data; - auto message = - NodeChannel::CreateEventMessage(event->GetSerializedSize(), &data, 0); + size_t size = event->GetSerializedSize(); + auto message = NodeChannel::CreateEventMessage(size, size, &data, 0); event->Serialize(data); return message; }
diff --git a/mojo/edk/system/user_message_impl.cc b/mojo/edk/system/user_message_impl.cc index 727a4d2..842019d 100644 --- a/mojo/edk/system/user_message_impl.cc +++ b/mojo/edk/system/user_message_impl.cc
@@ -4,7 +4,10 @@ #include "mojo/edk/system/user_message_impl.h" +#include <algorithm> + #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros_local.h" #include "base/numerics/safe_conversions.h" #include "base/numerics/safe_math.h" #include "mojo/edk/embedder/embedder_internal.h" @@ -21,6 +24,11 @@ namespace { +// The minimum amount of memory to allocate for a new serialized message buffer. +// This should be sufficiently large such that most seiralized messages do not +// incur any reallocations as they're expanded to full size. +const uint32_t kMinimumPayloadBufferSize = 4096; + #pragma pack(push, 1) // Header attached to every message. struct MessageHeader { @@ -57,10 +65,12 @@ MojoResult SerializeEventMessage( ports::UserMessageEvent* event, size_t payload_size, + size_t payload_buffer_size, const Dispatcher::DispatcherInTransit* dispatchers, size_t num_dispatchers, Channel::MessagePtr* out_message, void** out_header, + size_t* out_header_size, void** out_user_payload) { // A structure for tracking information about every Dispatcher that will be // serialized into the message. This is NOT part of the message itself. @@ -94,9 +104,11 @@ event->ReservePorts(num_ports); const size_t event_size = event->GetSerializedSize(); const size_t total_size = event_size + header_size + payload_size; + const size_t total_buffer_size = + event_size + header_size + payload_buffer_size; void* data; - Channel::MessagePtr message = - NodeChannel::CreateEventMessage(total_size, &data, num_handles); + Channel::MessagePtr message = NodeChannel::CreateEventMessage( + total_buffer_size, total_size, &data, num_handles); auto* header = reinterpret_cast<MessageHeader*>(static_cast<uint8_t*>(data) + event_size); @@ -166,6 +178,7 @@ *out_message = std::move(message); *out_header = header; + *out_header_size = header_size; *out_user_payload = reinterpret_cast<uint8_t*>(header) + header_size; return MOJO_RESULT_OK; } @@ -176,11 +189,10 @@ const ports::UserMessage::TypeInfo UserMessageImpl::kUserMessageTypeInfo = {}; UserMessageImpl::~UserMessageImpl() { - if (HasContext()) { - if (context_thunks_.has_value()) - context_thunks_->destroy(context_); + if (HasContext() && context_destructor_) { DCHECK(!channel_message_); DCHECK(!has_serialized_handles_); + context_destructor_(context_); } else if (IsSerialized() && has_serialized_handles_) { // Ensure that any handles still serialized within this message are // extracted and closed so they don't leak. @@ -198,12 +210,10 @@ // static std::unique_ptr<ports::UserMessageEvent> -UserMessageImpl::CreateEventForNewMessageWithContext( - uintptr_t context, - const MojoMessageOperationThunks* thunks) { +UserMessageImpl::CreateEventForNewMessage() { auto message_event = base::MakeUnique<ports::UserMessageEvent>(0); - message_event->AttachMessage(base::WrapUnique( - new UserMessageImpl(message_event.get(), context, thunks))); + message_event->AttachMessage( + base::WrapUnique(new UserMessageImpl(message_event.get()))); return message_event; } @@ -217,14 +227,15 @@ void* header = nullptr; void* user_payload = nullptr; auto event = base::MakeUnique<ports::UserMessageEvent>(0); - MojoResult rv = SerializeEventMessage(event.get(), num_bytes, dispatchers, - num_dispatchers, &channel_message, - &header, &user_payload); + size_t header_size = 0; + MojoResult rv = SerializeEventMessage( + event.get(), num_bytes, num_bytes, dispatchers, num_dispatchers, + &channel_message, &header, &header_size, &user_payload); if (rv != MOJO_RESULT_OK) return rv; event->AttachMessage(base::WrapUnique( new UserMessageImpl(event.get(), std::move(channel_message), header, - user_payload, num_bytes))); + header_size, user_payload, num_bytes))); *out_event = std::move(event); return MOJO_RESULT_OK; } @@ -248,7 +259,7 @@ const size_t user_payload_size = payload_size - header_size; return base::WrapUnique( new UserMessageImpl(message_event, std::move(channel_message), header, - user_payload, user_payload_size)); + header_size, user_payload, user_payload_size)); } // static @@ -277,58 +288,97 @@ return context; } +size_t UserMessageImpl::user_payload_buffer_size() const { + DCHECK(IsSerialized()); + return channel_message_->capacity(); +} + size_t UserMessageImpl::num_handles() const { DCHECK(IsSerialized()); DCHECK(header_); return static_cast<const MessageHeader*>(header_)->num_dispatchers; } -MojoResult UserMessageImpl::SerializeIfNecessary() { +MojoResult UserMessageImpl::AttachContext( + uintptr_t context, + MojoMessageContextSerializer serializer, + MojoMessageContextDestructor destructor) { + if (HasContext()) + return MOJO_RESULT_ALREADY_EXISTS; if (IsSerialized()) return MOJO_RESULT_FAILED_PRECONDITION; - if (!context_thunks_.has_value()) - return MOJO_RESULT_NOT_FOUND; + context_ = context; + context_serializer_ = serializer; + context_destructor_ = destructor; + return MOJO_RESULT_OK; +} - DCHECK(HasContext()); - DCHECK(!has_serialized_handles_); - size_t num_bytes = 0; - size_t num_handles = 0; - context_thunks_->get_serialized_size(context_, &num_bytes, &num_handles); - - std::vector<ScopedHandle> handles(num_handles); +MojoResult UserMessageImpl::AttachSerializedMessageBuffer( + uint32_t payload_size, + const MojoHandle* handles, + uint32_t num_handles) { std::vector<Dispatcher::DispatcherInTransit> dispatchers; if (num_handles > 0) { - auto* raw_handles = reinterpret_cast<MojoHandle*>(handles.data()); - context_thunks_->serialize_handles(context_, raw_handles); MojoResult acquire_result = internal::g_core->AcquireDispatchersForTransit( - raw_handles, num_handles, &dispatchers); + handles, num_handles, &dispatchers); if (acquire_result != MOJO_RESULT_OK) return acquire_result; } - Channel::MessagePtr channel_message; MojoResult rv = SerializeEventMessage( - message_event_, num_bytes, dispatchers.data(), num_handles, - &channel_message, &header_, &user_payload_); + message_event_, payload_size, + std::max(payload_size, kMinimumPayloadBufferSize), dispatchers.data(), + num_handles, &channel_message, &header_, &header_size_, &user_payload_); if (num_handles > 0) { internal::g_core->ReleaseDispatchersForTransit(dispatchers, rv == MOJO_RESULT_OK); } - if (rv != MOJO_RESULT_OK) return MOJO_RESULT_ABORTED; - - // The handles are now owned by the message event. Release them here. - for (auto& handle : handles) - ignore_result(handle.release()); - - if (num_bytes) - context_thunks_->serialize_payload(context_, user_payload_); - user_payload_size_ = num_bytes; + user_payload_size_ = payload_size; channel_message_ = std::move(channel_message); + has_serialized_handles_ = true; + return MOJO_RESULT_OK; +} - context_thunks_->destroy(context_); - context_ = 0; +MojoResult UserMessageImpl::ExtendSerializedMessagePayload( + uint32_t new_payload_size) { + if (!IsSerialized()) + return MOJO_RESULT_FAILED_PRECONDITION; + if (new_payload_size < user_payload_size_) + return MOJO_RESULT_OUT_OF_RANGE; + + size_t header_offset = + static_cast<uint8_t*>(header_) - + static_cast<const uint8_t*>(channel_message_->payload()); + size_t user_payload_offset = + static_cast<uint8_t*>(user_payload_) - + static_cast<const uint8_t*>(channel_message_->payload()); + channel_message_->ExtendPayload(user_payload_offset + new_payload_size); + header_ = static_cast<uint8_t*>(channel_message_->mutable_payload()) + + header_offset; + user_payload_ = static_cast<uint8_t*>(channel_message_->mutable_payload()) + + user_payload_offset; + user_payload_size_ = new_payload_size; + return MOJO_RESULT_OK; +} + +MojoResult UserMessageImpl::SerializeIfNecessary() { + if (IsSerialized()) + return MOJO_RESULT_FAILED_PRECONDITION; + + DCHECK(HasContext()); + DCHECK(!has_serialized_handles_); + if (!context_serializer_) + return MOJO_RESULT_NOT_FOUND; + + uintptr_t context = ReleaseContext(); + context_serializer_(reinterpret_cast<MojoMessageHandle>(message_event_), + context); + + if (context_destructor_) + context_destructor_(context); + has_serialized_handles_ = true; return MOJO_RESULT_OK; } @@ -417,19 +467,14 @@ return MOJO_RESULT_OK; } -UserMessageImpl::UserMessageImpl(ports::UserMessageEvent* message_event, - uintptr_t context, - const MojoMessageOperationThunks* thunks) +UserMessageImpl::UserMessageImpl(ports::UserMessageEvent* message_event) : ports::UserMessage(&kUserMessageTypeInfo), - message_event_(message_event), - context_(context) { - if (thunks) - context_thunks_ = *thunks; -} + message_event_(message_event) {} UserMessageImpl::UserMessageImpl(ports::UserMessageEvent* message_event, Channel::MessagePtr channel_message, void* header, + size_t header_size, void* user_payload, size_t user_payload_size) : ports::UserMessage(&kUserMessageTypeInfo), @@ -437,6 +482,7 @@ channel_message_(std::move(channel_message)), has_serialized_handles_(true), header_(header), + header_size_(header_size), user_payload_(user_payload), user_payload_size_(user_payload_size) {}
diff --git a/mojo/edk/system/user_message_impl.h b/mojo/edk/system/user_message_impl.h index 461e4e2..0d6475f 100644 --- a/mojo/edk/system/user_message_impl.h +++ b/mojo/edk/system/user_message_impl.h
@@ -50,11 +50,8 @@ ~UserMessageImpl() override; - // Creates a new ports::UserMessageEvent with an attached unserialized - // UserMessageImpl associated with |context| and |thunks|. - static std::unique_ptr<ports::UserMessageEvent> - CreateEventForNewMessageWithContext(uintptr_t context, - const MojoMessageOperationThunks* thunks); + // Creates a new ports::UserMessageEvent with an attached UserMessageImpl. + static std::unique_ptr<ports::UserMessageEvent> CreateEventForNewMessage(); // Creates a new ports::UserMessageEvent with an attached serialized // UserMessageImpl. May fail iff one or more |dispatchers| fails to serialize @@ -114,11 +111,21 @@ return user_payload_size_; } + size_t user_payload_buffer_size() const; + size_t num_handles() const; void set_source_node(const ports::NodeName& name) { source_node_ = name; } const ports::NodeName& source_node() const { return source_node_; } + MojoResult AttachContext(uintptr_t context, + MojoMessageContextSerializer serializer, + MojoMessageContextDestructor destructor); + MojoResult AttachSerializedMessageBuffer(uint32_t payload_size, + const MojoHandle* handles, + uint32_t num_handles); + MojoResult ExtendSerializedMessagePayload(uint32_t new_payload_size); + // If this message is not already serialized, this serializes it. MojoResult SerializeIfNecessary(); @@ -140,9 +147,7 @@ // |thunks|. If the message is ever going to be routed to another node (see // |WillBeRoutedExternally()| below), it will be serialized at that time using // operations provided by |thunks|. - UserMessageImpl(ports::UserMessageEvent* message_event, - uintptr_t context, - const MojoMessageOperationThunks* thunks); + UserMessageImpl(ports::UserMessageEvent* message_event); // Creates a serialized UserMessageImpl backed by an existing Channel::Message // object. |header| and |user_payload| must be pointers into @@ -151,6 +156,7 @@ UserMessageImpl(ports::UserMessageEvent* message_event, Channel::MessagePtr channel_message, void* header, + size_t header_size, void* user_payload, size_t user_payload_size); @@ -162,7 +168,8 @@ // Unserialized message state. uintptr_t context_ = 0; - base::Optional<MojoMessageOperationThunks> context_thunks_; + MojoMessageContextSerializer context_serializer_ = nullptr; + MojoMessageContextDestructor context_destructor_ = nullptr; // Serialized message contents. May be null if this is not a serialized // message. @@ -178,6 +185,7 @@ // after any serialized dispatchers, with the payload comprising the remaining // |user_payload_size_| bytes of the message. void* header_ = nullptr; + size_t header_size_ = 0; void* user_payload_ = nullptr; size_t user_payload_size_ = 0;
diff --git a/mojo/public/c/system/README.md b/mojo/public/c/system/README.md index a668fc1..847eb2dc 100644 --- a/mojo/public/c/system/README.md +++ b/mojo/public/c/system/README.md
@@ -126,46 +126,75 @@ The state of these conditions can be queried and watched asynchronously as described in the [Signals & Watchers](#Signals-Watchers) section below. -### Allocating Messages +### Creating Messages -In order to avoid redundant internal buffer copies, Mojo would like to allocate -your message storage buffers for you. This is easy: +Message pipes carry message objects which may or may not be serialized. You can +create a new message object as follows: ``` c MojoMessageHandle message; -MojoResult result = MojoAllocMessage(6, NULL, 0, MOJO_ALLOC_MESSAGE_FLAG_NONE, - &message); +MojoResult result = MojoCreateMessage(&message); ``` Note that we have a special `MojoMessageHandle` type for message objects. -The code above allocates a buffer for a message payload of 6 bytes with no -handles attached. +Messages may be serialized or unserialized. Unserialized messages may support +lazy serialization, meaning they can be serialized if and only if necessary +(e.g. if the message needs to cross a process boundary.) -If we change our mind and decide not to send this message, we can delete it: +To make a serialized message, you might write something like: ``` c -MojoResult result = MojoFreeMessage(message); +void* buffer; +uint32_t buffer_size; +MojoResult result = MojoAttachSerializedMessageBuffer( + message, 6, nullptr, 0, &buffer, &buffer_size); ``` -If we instead decide to send our newly allocated message, we first need to fill -in the payload data with something interesting. How about a pleasant greeting: +This attaches a serialized message buffer to `message` with at least `6` bytes +of storage capacity. The results stored in `buffer` and `buffer_size` give more +information about the payload's storage. + +If you want to increase the size of the payload layer, you can use +`MojoExtendSerializedMessagePayload`. + +Creating lazily-serialized messages is also straightforward: ``` c -void* buffer = NULL; -MojoResult result = MojoGetMessageBuffer(message, &buffer); -memcpy(buffer, "hello", 6); +struct MyMessage { + // some interesting data... +}; + +void SerializeMessage(MojoMessageHandle message, uintptr_t context) { + struct MyMessage* my_message = (struct MyMessage*)context; + + MojoResult result = MojoAttachSerializedMessageBuffer(message, ...); + // Serialize however you like. + + free(my_message); +} + +MyMessage* data = malloc(sizeof(MyMessage)); +// initialize *data... + +MojoResult result = MojoAttachMessageContext(message, (uintptr_t)data, + &SerializeMessage); ``` -Now we can write the message to a pipe. Note that attempting to write a message -transfers ownership of the message object (and any attached handles) into the -target pipe and there is therefore no need to subsequently call -`MojoFreeMessage` on that message. +If we change our mind and decide not to send a message, we can destroy it: + +``` c +MojoResult result = MojoDestroyMessage(message); +``` + +Note that attempting to write a message transfers ownership of the message +object (and any attached handles) into the message pipe, and there is therefore +no need to subsequently call `MojoDestroyMessage` on that message. ### Writing Messages ``` c -result = MojoWriteMessageNew(a, message, MOJO_WRITE_MESSAGE_FLAG_NONE); +result = MojoWriteMessage(a, message, MOJO_WRITE_MESSAGE_FLAG_NONE); ``` `MojoWriteMessage` is a *non-blocking* call: it always returns @@ -180,10 +209,11 @@ [Signals & Watchers](#Signals-Watchers) below for more information. *** aside -**NOTE**: Although this is an implementation detail and not strictly guaranteed by the -System API, it is true in the current implementation that the message will -arrive at `b` before the above `MojoWriteMessage` call even returns, because `b` -is in the same process as `a` and has never been transferred over another pipe. +**NOTE**: Although this is an implementation detail and not strictly guaranteed +by the System API, it is true in the current implementation that the message +will arrive at `b` before the above `MojoWriteMessage` call even returns, +because `b` is in the same process as `a` and has never been transferred over +another pipe. *** ### Reading Messages @@ -192,16 +222,17 @@ ``` c MojoMessageHandle message; -uint32_t num_bytes; -MojoResult result = MojoReadMessageNew(b, &message, &num_bytes, NULL, NULL, - MOJO_READ_MESSAGE_FLAG_NONE); +MojoResult result = MojoReadMessage(b, &message, MOJO_READ_MESSAGE_FLAG_NONE); ``` -and map its buffer to retrieve the contents: +and extract its serialized contents: ``` c void* buffer = NULL; -MojoResult result = MojoGetMessageBuffer(message, &buffer); +uint32_t num_bytes; +MojoResult result = MojoGetSerializedMessageContents( + message, &buffer, &num_bytes, nullptr, nullptr, + MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE); printf("Pipe says: %s", (const char*)buffer); ``` @@ -212,13 +243,21 @@ ``` c MojoMessageHandle message; -MojoResult result = MojoReadMessageNew(b, &message, NULL, NULL, NULL, - MOJO_READ_MESSAGE_FLAG_NONE); +MojoResult result = MojoReadMessage(b, &message, MOJO_READ_MESSAGE_FLAG_NONE); ``` We'll get a `result` of `MOJO_RESULT_SHOULD_WAIT`, indicating that the pipe is not yet readable. +Note that message also may not have been serialized if they came from within the +same process. In that case, `MojoGetSerializedMessageContents` will return +`MOJO_RESULT_FAILED_PRECONDITION`. The message's unserialized context can +instead be retrieved using `MojoGetMessageContext`. + +Messages read from a message pipe are owned by the caller and must be +subsequently destroyed using `MojoDestroyMessage` (or, in theory, written to +another pipe using `MojoWriteMessage`.) + ### Messages With Handles Probably the most useful feature of Mojo IPC is that message pipes can carry @@ -233,52 +272,53 @@ ``` c MojoHandle a, b; MojoHandle c, d; -MojoMessage message; +MojoCreateMessagePipe(NULL, &a, &b); +MojoCreateMessagePipe(NULL, &c, &d); // Allocate a message with an empty payload and handle |c| attached. Note that // this takes ownership of |c|, effectively invalidating its handle value. -MojoResult result = MojoAllocMessage(0, &c, 1, MOJO_ALLOC_MESSAGE_FLAG_NONE, - message); - -result = MojoWriteMessageNew(a, message, MOJO_WRITE_MESSAGE_FLAG_NONE); +MojoMessageHandle message; +void* buffer; +uint32_t buffer_size; +MojoCreateMessage(&message); +MojoAttachSerializedMessageBuffer(message, "hi", 2, &c, 1, &buffer, + &buffer_size); +MojoWriteMessage(a, message, MOJO_WRITE_MESSAGE_FLAG_NONE); // Some time later... -uint32_t num_bytes; MojoHandle e; uint32_t num_handles = 1; -MojoResult result = MojoReadMessageNew(b, &message, &num_bytes, &e, - &num_handles, - MOJO_READ_MESSAGE_FLAG_NONE); +MojoReadMessage(b, &message, MOJO_READ_MESSAGE_FLAG_NONE); +MojoGetSerializedMessageContents( + message, &buffer, &buffer_size, &e, &num_handles, + MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE); ``` At this point the handle in `e` is now referencing the same message pipe endpoint which was originally referenced by `c`. Note that `num_handles` above is initialized to 1 before we pass its address to -`MojoReadMessageNew`. This is to indicate how much `MojoHandle` storage is -available at the output buffer we gave it (`&e` above). +`MojoGetSerializedMessageContents`. This is to indicate how much `MojoHandle` +storage is available at the output buffer we gave it (`&e` above). If we didn't know how many handles to expect in an incoming message -- which is -often the case -- we can use `MojoReadMessageNew` to query for this information -first: +often the case -- we can use `MojoGetSerializedMessageContents` to query for +this information first: ``` c MojoMessageHandle message; +void* buffer; uint32_t num_bytes = 0; uint32_t num_handles = 0; -MojoResult result = MojoReadMessageNew(b, &message, &num_bytes, NULL, - &num_handles, - MOJO_READ_MESSAGE_FLAG_NONE); +MojoResult result = MojoGetSerializedMessageContents( + message, &buffer, &num_bytes, NULL, &num_handles, + MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE); ``` -If in this case there were a received message on `b` with some nonzero number -of handles, `result` would be `MOJO_RESULT_RESOURCE_EXHAUSTED`, and both -`num_bytes` and `num_handles` would be updated to reflect the payload size and -number of attached handles on the next available message. - -It's also worth noting that if there did happen to be a message available with -no payload and no handles (*i.e.* an empty message), this would actually return -`MOJO_RESULT_OK`. +If `message` has some non-zero number of handles, `result` will be +`MOJO_RESULT_RESOURCE_EXHAUSTED`, and both `num_bytes` and `num_handles` would +be updated to reflect the payload size and number of attached handles in the +message. ## Data Pipes
diff --git a/mojo/public/c/system/message_pipe.h b/mojo/public/c/system/message_pipe.h index d83155a..90d55253 100644 --- a/mojo/public/c/system/message_pipe.h +++ b/mojo/public/c/system/message_pipe.h
@@ -110,55 +110,23 @@ extern "C" { #endif -// A structure used with MojoCreateMessage to inform the system about how to -// operate on an opaque message object given by |context|. +// A callback which can serialize a message given some context. Passed to +// MojoAttachMessageContext along with a context it knows how to serialize. +// See |MojoAttachMessageContext()| for more details. // -// See |MojoCreateMessage()| for more details. -#pragma pack(push, 8) -struct MojoMessageOperationThunks { - // Must be set to sizeof(MojoMessageOperationThunks). - size_t struct_size; +// |message| is a message object which had |context| attached. +// |context| the context which was attached to |message|. +// +// Note that the context is always detached from the message immediately before +// this callback is invoked, and that the associated destructor (if any) is also +// invoked on |context| immediately after the serializer returns. +typedef void (*MojoMessageContextSerializer)(MojoMessageHandle message, + uintptr_t context); - // Computes the number of bytes of payload and the number of handles required - // to serialize the message associated with |context|. If the message needs - // to be serialized, this is the first function invoked by the system, - // followed immediately by |serialize_handles()| or |serialize_payload()| for - // the same |context|. - // - // The implementation must populate |*num_bytes| and |*num_handles|. - void (*get_serialized_size)(uintptr_t context, - size_t* num_bytes, - size_t* num_handles); - - // Passes ownership of any MojoHandles carried by the message associated with - // |context|. Called immediately after |get_serialized_size()| for the same - // |context|, if and only if the returned |*num_handles| was non-zero. - // - // The implementation must populate |handles| with a contiguous MojoHandle - // array of exactly |*num_handles| (from above) elements. - void (*serialize_handles)(uintptr_t context, MojoHandle* handles); - - // Serializes the message payload bytes into a message buffer. This always - // follows a call to |get_serialized_size()| (and possibly - // |serialize_handles()|) for the same |context|, if and only if |*num_bytes| - // (from above) is non-zero. - // - // The implementation must populate |buffer| with exactly |*num_bytes| bytes - // of message content. The storage in |buffer| is NOT initialized otherwise, - // so it is the caller's responsibility to ensure that ALL |*num_bytes| bytes - // are written to. - void (*serialize_payload)(uintptr_t context, void* buffer); - - // Destroys the message object associated with |context|. This is called when - // the message associated with |context| is either explicitly freed by - // |MojoDestroyMessage()| or serialized for transmission across a process - // boundary (after serialization is complete.) - // - // The implementation must use this to release any resources associated with - // |context|. - void (*destroy)(uintptr_t context); -}; -#pragma pack(pop) +// A callback which can be used to destroy a message context after serialization +// or in the event that the message to which it's attached is destroyed without +// ever being serialized. +typedef void (*MojoMessageContextDestructor)(uintptr_t context); // Note: See the comment in functions.h about the meaning of the "optional" // label for pointer parameters. @@ -185,8 +153,8 @@ // Writes a message to the message pipe endpoint given by |message_pipe_handle|. // -// Note that regardless of success or failure, |message| is freed by this call -// and therefore invalidated. +// Note that regardless of success or failure, |message| is destroyed by this +// call and therefore invalidated. // // Returns: // |MOJO_RESULT_OK| on success (i.e., the message was enqueued). @@ -196,6 +164,8 @@ // Note that closing an endpoint is not necessarily synchronous (e.g., // across processes), so this function may succeed even if the other // endpoint has been closed (in which case the message would be dropped). +// |MOJO_RESULT_NOT_FOUND| if |message| has neither a context nor serialized +// buffer attached and therefore has nothing to be written. MOJO_SYSTEM_EXPORT MojoResult MojoWriteMessage(MojoHandle message_pipe_handle, MojoMessageHandle message, MojoWriteMessageFlags flags); @@ -247,37 +217,16 @@ // |MojoWriteMessage()|. Returns a handle to the new message object in // |*message|. // -// |context| is an arbitrary context value to associate with this message, and -// |thunks| is a set of functions which may be called on |context| to perform -// various operations. See |MojoMessageOperationThunks| for details. -// -// Typically a caller will use |context| as an opaque pointer to some heap -// object which is effectively owned by the newly created message once this -// returns. In this way, messages can be sent over a message pipe to a peer -// endpoint in the same process as the sender without ever performing a -// serialization step. -// -// If the message does need to cross a process boundary or is otherwise -// forced to serialize (see |MojoSerializeMessage()| below), it will be -// serialized by invoking the serialization helper functions from |thunks| on -// |context| to obtain a serialized representation of the message. Note that -// because the need to serialize may occur at any time and on any thread, -// functions in |thunks| must be safe to invoke accordingly. -// -// If |thunks| is null, the created message cannot be serialized. Subsequent -// calls to |MojoSerializeMessage()| on the created message, or any attempt to -// transmit the message across a process boundary, will fail. +// In its initial state the message object cannot be successfully written to a +// message pipe, but must first have either a context or serialized buffer +// attached (see |MojoAttachContext()| and |MojoAttachSerializedMessageBuffer()| +// below.) // // Returns: // |MOJO_RESULT_OK| if a new message was created. |*message| contains a handle -// to the new message object on return. -// |MOJO_RESULT_INVALID_ARGUMENT| if |context| is 0, or |thunks| is non-null -// and any element of |thunks| is invalid. In this case, the value of -// |message| is ignored. -MOJO_SYSTEM_EXPORT MojoResult -MojoCreateMessage(uintptr_t context, - const struct MojoMessageOperationThunks* thunks, - MojoMessageHandle* message); +// to the new message object upon return. +// |MOJO_RESULT_INVALID_ARGUMENT| if |message| is null. +MOJO_SYSTEM_EXPORT MojoResult MojoCreateMessage(MojoMessageHandle* message); // Destroys a message object created by |MojoCreateMessage()| or // |MojoReadMessage()|. @@ -300,7 +249,7 @@ // written to a pipe or decomposed by MojoGetSerializedMessageContents(). // |MOJO_RESULT_FAILED_PRECONDITION| if |message| was already serialized. // |MOJO_RESULT_NOT_FOUND| if |message| cannot be serialized (i.e. it was -// created with null |MojoMessageOperationThunks|.) +// created with null |MojoMessageContextSerializer|.) // |MOJO_RESULT_BUSY| if one or more handles provided by the user context // reported itself as busy during the serialization attempt. In this case // all serialized handles are closed automatically. @@ -314,6 +263,77 @@ // allows callers to coerce eager serialization. MOJO_SYSTEM_EXPORT MojoResult MojoSerializeMessage(MojoMessageHandle message); +// Attaches a serialized message buffer to a message object. +// +// |message|: The message to which a buffer is to be attached. +// |payload_size|: The initial expected payload size of the message. If this +// call succeeds, the attached buffer will be at least this large. +// |handles|: The handles to attach to the serialized message. The set of +// attached handles may not be augmented once the buffer is attached, and so +// all handle attachments must be known up front. May be null if +// |num_handles| is 0. +// |num_handles|: The number of handles provided by |handles|. +// +// Note that while a serialized message buffer's size may exceed the size of the +// payload, when a serialized message is transmitted (or its contents retrieved +// with |MojoGetSerializedMessageContents()|), only the extent of the payload +// is transmitted and/or exposed. Use |MojoExtendSerializedMessagePayload()| to +// extend the portion of the buffer which is designated as valid payload and +// (if necessary) expand the available capacity. +// +// Ownership of all handles in |handles| is tranferred to the message object if +// and ONLY if this operation succeeds and returns |MOJO_RESULT_OK|. Otherwise +// the caller retains ownership. +// +// Returns: +// |MOJO_RESULT_OK| upon success. A new serialized message buffer has been +// attached to |message|. The address of the buffer's storage is output in +// |*buffer| and its size is in |*buffer_size|. +// |MOJO_RESULT_INVALID_ARGUMENT| if |message| is not a valid message object; +// if |num_handles| is non-zero but |handles| is null; if either +// |buffer| or |buffer_size| is null; or if any handle in |handles| is +// invalid. +// |MOJO_RESULT_RESOURCE_EXHAUSTED| if |payload_size| or |num_handles| exceeds +// some implementation- or embedder-defined maximum. +// |MOJO_RESULT_FAILED_PRECONDITION| if |message| has a context attached. +// |MOJO_RESULT_ALREADY_EXISTS| if |message| already has a serialized buffer +// attached. +// |MOJO_RESULT_BUSY| if one or more handles in |handles| is currently busy +// and unable to be serialized. +MOJO_SYSTEM_EXPORT MojoResult +MojoAttachSerializedMessageBuffer(MojoMessageHandle message, + uint32_t payload_size, + const MojoHandle* handles, + uint32_t num_handles, + void** buffer, + uint32_t* buffer_size); + +// Extends the designated payload size within a serialized message buffer. If +// the buffer is not large enough to accomodate the additional payload size, +// this will attempt to expand the buffer before returning. +// +// |message|: The message getting additional payload. +// |new_payload_size|: The new total of the payload. Must be at least as large +// as the message's current payload size. +// +// Returns: +// |MOJO_RESULT_OK| if the new payload size has been committed to the message. +// If necessary, the message's buffer may have been reallocated to +// accommodate additional capacity. |*buffer| and |*buffer_size| contain +// the (possibly changed) address and size of the serialized message +// buffer's storage. +// |MOJO_RESULT_INVALID_ARGUMENT| if |message| is not a valid message object, +// or either |buffer| or |buffer_size| is null. +// |MOJO_RESULT_OUT_OF_RANGE| if |payload_size| is not at least as large as +// the message's current payload size. +// |MOJO_RESULT_FAILED_PRECONDITION| if |message| does not have a serialized +// message buffer attached. +MOJO_SYSTEM_EXPORT MojoResult +MojoExtendSerializedMessagePayload(MojoMessageHandle message, + uint32_t new_payload_size, + void** new_buffer, + uint32_t* new_buffer_size); + // Retrieves the contents of a serialized message. // // |message|: The message whose contents are to be retrieved. @@ -365,20 +385,60 @@ uint32_t* num_handles, MojoGetSerializedMessageContentsFlags flags); +// Attachs an unserialized message context to a message. +// +// |context| is the context value to associate with this message, and +// |serializer| is a function which may be called at some later time to convert +// |message| to a serialized message object using |context| as input. See +// |MojoMessageContextSerializer| for more details. |destructor| is a function +// which may be called to allow the user to cleanup state associated with +// |context| after serialization or in the event that the message is destroyed +// without ever being serialized. +// +// Typically a caller will use |context| as an opaque pointer to some heap +// object which is effectively owned by the newly created message once this +// returns. In this way, messages can be sent over a message pipe to a peer +// endpoint in the same process as the sender without ever performing a +// serialization step. +// +// If the message does need to cross a process boundary or is otherwise +// forced to serialize (see |MojoSerializeMessage()| below), it will be +// serialized by invoking |serializer|. +// +// If |serializer| is null, the created message cannot be serialized. Subsequent +// calls to |MojoSerializeMessage()| on the created message, or any attempt to +// transmit the message across a process boundary, will fail. +// +// If |destructor| is null, it is assumed that no cleanup is required after +// serializing or destroying a message with |context| attached. +// +// Returns: +// |MOJO_RESULT_OK| if the context was successfully attached. +// |MOJO_RESULT_INVALID_ARGUMENT| if |context| is 0 or |message| is not a +// valid message object. +// |MOJO_RESULT_ALREADY_EXISTS| if |message| already has a context attached. +// |MOJO_RESULT_FAILED_PRECONDITION| if |message| already has a serialized +// buffer attached. +MOJO_SYSTEM_EXPORT MojoResult +MojoAttachMessageContext(MojoMessageHandle message, + uintptr_t context, + MojoMessageContextSerializer serializer, + MojoMessageContextDestructor destructor); + // Extracts the user-provided context from a message and returns it to the -// caller. This can only succeed if the message is not in a serialized form. +// caller. // // |flags|: Flags to alter the behavior of this call. See // |MojoGetMessageContextFlags| for details. // // Returns: -// |MOJO_RESULT_OK| if |message| was a valid message object which has not yet -// been serialized. Upon return, |*context| contains the context value -// originally provided to the |MojoCreateMessage()| call which created +// |MOJO_RESULT_OK| if |message| is a valid message object which has a +// |context| attached. Upon return, |*context| contains the value of the +// attached context. If |flags| contains +// |MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE|, the |context| is detached from // |message|. // |MOJO_RESULT_NOT_FOUND| if |message| is a valid message object which has no -// associated context value. In this case it must be a serialized message, -// and |MojoGetSerializedMessageContents()| should be called instead. +// attached context. // |MOJO_RESULT_INVALID_ARGUMENT| if |message| is not a valid message object. MOJO_SYSTEM_EXPORT MojoResult MojoGetMessageContext(MojoMessageHandle message,
diff --git a/mojo/public/c/system/tests/core_unittest.cc b/mojo/public/c/system/tests/core_unittest.cc index 7e02a1a..7fa87ed 100644 --- a/mojo/public/c/system/tests/core_unittest.cc +++ b/mojo/public/c/system/tests/core_unittest.cc
@@ -98,8 +98,10 @@ // Write to |h1|. const uintptr_t kTestMessageContext = 1234; - EXPECT_EQ(MOJO_RESULT_OK, - MojoCreateMessage(kTestMessageContext, nullptr, &message)); + EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessage(&message)); + EXPECT_EQ( + MOJO_RESULT_OK, + MojoAttachMessageContext(message, kTestMessageContext, nullptr, nullptr)); EXPECT_EQ(MOJO_RESULT_OK, MojoWriteMessage(h1, message, MOJO_WRITE_MESSAGE_FLAG_NONE));
diff --git a/mojo/public/c/system/tests/core_unittest_pure_c.c b/mojo/public/c/system/tests/core_unittest_pure_c.c index fc6d6a3d..4d7e934 100644 --- a/mojo/public/c/system/tests/core_unittest_pure_c.c +++ b/mojo/public/c/system/tests/core_unittest_pure_c.c
@@ -56,7 +56,8 @@ EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(NULL, &handle0, &handle1)); MojoMessageHandle message; - EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessage(42, NULL, &message)); + EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessage(&message)); + EXPECT_EQ(MOJO_RESULT_OK, MojoAttachMessageContext(message, 42, NULL, NULL)); EXPECT_EQ(MOJO_RESULT_OK, MojoWriteMessage(handle0, message, MOJO_WRITE_DATA_FLAG_NONE));
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc index 2ce9edb..5a08dbf7 100644 --- a/mojo/public/c/system/thunks.cc +++ b/mojo/public/c/system/thunks.cc
@@ -173,11 +173,9 @@ return g_thunks.FuseMessagePipes(handle0, handle1); } -MojoResult MojoCreateMessage(uintptr_t context, - const MojoMessageOperationThunks* thunks, - MojoMessageHandle* message) { +MojoResult MojoCreateMessage(MojoMessageHandle* message) { assert(g_thunks.CreateMessage); - return g_thunks.CreateMessage(context, thunks, message); + return g_thunks.CreateMessage(message); } MojoResult MojoDestroyMessage(MojoMessageHandle message) { @@ -190,6 +188,26 @@ return g_thunks.SerializeMessage(message); } +MojoResult MojoAttachSerializedMessageBuffer(MojoMessageHandle message, + uint32_t payload_size, + const MojoHandle* handles, + uint32_t num_handles, + void** buffer, + uint32_t* buffer_size) { + assert(g_thunks.AttachSerializedMessageBuffer); + return g_thunks.AttachSerializedMessageBuffer( + message, payload_size, handles, num_handles, buffer, buffer_size); +} + +MojoResult MojoExtendSerializedMessagePayload(MojoMessageHandle message, + uint32_t new_payload_size, + void** buffer, + uint32_t* buffer_size) { + assert(g_thunks.ExtendSerializedMessagePayload); + return g_thunks.ExtendSerializedMessagePayload(message, new_payload_size, + buffer, buffer_size); +} + MojoResult MojoGetSerializedMessageContents( MojoMessageHandle message, void** buffer, @@ -202,6 +220,15 @@ handles, num_handles, flags); } +MojoResult MojoAttachMessageContext(MojoMessageHandle message, + uintptr_t context, + MojoMessageContextSerializer serializer, + MojoMessageContextDestructor destructor) { + assert(g_thunks.AttachMessageContext); + return g_thunks.AttachMessageContext(message, context, serializer, + destructor); +} + MojoResult MojoGetMessageContext(MojoMessageHandle message, uintptr_t* context, MojoGetMessageContextFlags flags) {
diff --git a/mojo/public/c/system/thunks.h b/mojo/public/c/system/thunks.h index c6d8abe82..9f40696 100644 --- a/mojo/public/c/system/thunks.h +++ b/mojo/public/c/system/thunks.h
@@ -86,11 +86,19 @@ MojoResult* ready_results, MojoHandleSignalsState* ready_signals_states); MojoResult (*FuseMessagePipes)(MojoHandle handle0, MojoHandle handle1); - MojoResult (*CreateMessage)(uintptr_t context, - const struct MojoMessageOperationThunks* thunks, - MojoMessageHandle* message); + MojoResult (*CreateMessage)(MojoMessageHandle* message); MojoResult (*DestroyMessage)(MojoMessageHandle message); MojoResult (*SerializeMessage)(MojoMessageHandle message); + MojoResult (*AttachSerializedMessageBuffer)(MojoMessageHandle message, + uint32_t payload_size, + const MojoHandle* handles, + uint32_t num_handles, + void** buffer, + uint32_t* buffer_size); + MojoResult (*ExtendSerializedMessagePayload)(MojoMessageHandle message, + uint32_t new_payload_size, + void** buffer, + uint32_t* buffer_size); MojoResult (*GetSerializedMessageContents)( MojoMessageHandle message, void** buffer, @@ -98,6 +106,10 @@ MojoHandle* handles, uint32_t* num_handles, MojoGetSerializedMessageContentsFlags flags); + MojoResult (*AttachMessageContext)(MojoMessageHandle message, + uintptr_t context, + MojoMessageContextSerializer serializer, + MojoMessageContextDestructor destructor); MojoResult (*GetMessageContext)(MojoMessageHandle message, uintptr_t* context, MojoGetMessageContextFlags flags);
diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc index a6d927c7..11b02d9fb 100644 --- a/mojo/public/cpp/bindings/lib/message.cc +++ b/mojo/public/cpp/bindings/lib/message.cc
@@ -14,6 +14,7 @@ #include "base/bind.h" #include "base/lazy_instance.h" #include "base/logging.h" +#include "base/numerics/safe_math.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_local.h" #include "mojo/public/cpp/bindings/associated_group_controller.h" @@ -34,47 +35,6 @@ message.NotifyBadMessage(error); } -// An internal serialization context used to initialize new serialized messages. -struct MessageInfo { - MessageInfo(size_t total_size, std::vector<ScopedHandle>* handles) - : total_size(total_size), handles(handles) {} - const size_t total_size; - std::vector<ScopedHandle>* handles; - internal::Buffer payload_buffer; -}; - -void GetSerializedSizeFromMessageInfo(uintptr_t context, - size_t* num_bytes, - size_t* num_handles) { - auto* info = reinterpret_cast<MessageInfo*>(context); - *num_bytes = info->total_size; - *num_handles = info->handles ? info->handles->size() : 0; -} - -void SerializeHandlesFromMessageInfo(uintptr_t context, MojoHandle* handles) { - auto* info = reinterpret_cast<MessageInfo*>(context); - DCHECK(info->handles); - for (size_t i = 0; i < info->handles->size(); ++i) - handles[i] = info->handles->at(i).release().value(); -} - -void SerializePayloadFromMessageInfo(uintptr_t context, void* storage) { - auto* info = reinterpret_cast<MessageInfo*>(context); - info->payload_buffer = internal::Buffer(storage, info->total_size); -} - -void DestroyMessageInfo(uintptr_t context) { - // MessageInfo is always stack-allocated, so there's nothing to do here. -} - -const MojoMessageOperationThunks kMessageInfoThunks{ - sizeof(MojoMessageOperationThunks), - &GetSerializedSizeFromMessageInfo, - &SerializeHandlesFromMessageInfo, - &SerializePayloadFromMessageInfo, - &DestroyMessageInfo, -}; - template <typename HeaderType> void AllocateHeaderFromBuffer(internal::Buffer* buffer, HeaderType** header) { *header = static_cast<HeaderType*>(buffer->Allocate(sizeof(HeaderType))); @@ -118,65 +78,80 @@ std::vector<ScopedHandle>* handles, ScopedMessageHandle* out_handle, internal::Buffer* out_buffer) { - internal::Buffer buffer; - MessageInfo info(internal::ComputeSerializedMessageSize( - flags, payload_size, payload_interface_id_count), - handles); ScopedMessageHandle handle; - MojoResult rv = mojo::CreateMessage(reinterpret_cast<uintptr_t>(&info), - &kMessageInfoThunks, &handle); + MojoResult rv = mojo::CreateMessage(&handle); DCHECK_EQ(MOJO_RESULT_OK, rv); DCHECK(handle.is_valid()); - // Force the message object to be serialized immediately. MessageInfo thunks - // are invoked here to serialize the handles and allocate enough space for - // header and user payload. |info.payload_buffer| is initialized with a Buffer - // that can be used to write the header and payload data. - rv = MojoSerializeMessage(handle->value()); + void* buffer; + uint32_t buffer_size; + size_t total_size = internal::ComputeSerializedMessageSize( + flags, payload_size, payload_interface_id_count); + DCHECK(base::IsValueInRangeForNumericType<uint32_t>(total_size)); + DCHECK(!handles || + base::IsValueInRangeForNumericType<uint32_t>(handles->size())); + rv = MojoAttachSerializedMessageBuffer( + handle->value(), static_cast<uint32_t>(total_size), + handles ? reinterpret_cast<MojoHandle*>(handles->data()) : nullptr, + handles ? static_cast<uint32_t>(handles->size()) : 0, &buffer, + &buffer_size); DCHECK_EQ(MOJO_RESULT_OK, rv); - DCHECK(info.payload_buffer.is_valid()); + if (handles) { + // Handle ownership has been taken by MojoAttachSerializedMessageBuffer. + for (size_t i = 0; i < handles->size(); ++i) + ignore_result(handles->at(i).release()); + } + + internal::Buffer payload_buffer(buffer, buffer_size); // Make sure we zero the memory first! - memset(info.payload_buffer.data(), 0, info.total_size); - WriteMessageHeader(name, flags, payload_interface_id_count, - &info.payload_buffer); + memset(payload_buffer.data(), 0, total_size); + WriteMessageHeader(name, flags, payload_interface_id_count, &payload_buffer); *out_handle = std::move(handle); - *out_buffer = std::move(info.payload_buffer); + *out_buffer = std::move(payload_buffer); } -void GetSerializedSizeFromUnserializedContext(uintptr_t context, - size_t* num_bytes, - size_t* num_handles) { - reinterpret_cast<internal::UnserializedMessageContext*>(context) - ->GetSerializedSize(num_bytes, num_handles); -} - -void SerializeHandlesFromUnserializedContext(uintptr_t context, - MojoHandle* handles) { - reinterpret_cast<internal::UnserializedMessageContext*>(context) - ->SerializeHandles(handles); -} - -void SerializePayloadFromUnserializedContext(uintptr_t context_value, - void* storage) { +void SerializeUnserializedContext(MojoMessageHandle message, + uintptr_t context_value) { auto* context = reinterpret_cast<internal::UnserializedMessageContext*>(context_value); - internal::Buffer payload_buffer(storage, context->total_serialized_size()); + size_t num_bytes; + size_t num_handles; + context->GetSerializedSize(&num_bytes, &num_handles); + if (!base::IsValueInRangeForNumericType<uint32_t>(num_bytes)) + return; + if (!base::IsValueInRangeForNumericType<uint32_t>(num_handles)) + return; + + std::vector<MojoHandle> handles(num_handles); + if (num_handles) + context->SerializeHandles(handles.data()); + + void* buffer; + uint32_t buffer_size; + MojoResult rv = MojoAttachSerializedMessageBuffer( + message, static_cast<uint32_t>(num_bytes), handles.data(), + static_cast<uint32_t>(num_handles), &buffer, &buffer_size); + if (rv != MOJO_RESULT_OK) + return; + + internal::Buffer payload_buffer(buffer, num_bytes); WriteMessageHeader(context->message_name(), context->message_flags(), 0 /* payload_interface_id_count */, &payload_buffer); // We need to copy additional header data which may have been set after // message construction, as this codepath may be reached at some arbitrary // time between message send and message dispatch. - static_cast<internal::MessageHeader*>(storage)->interface_id = + static_cast<internal::MessageHeader*>(buffer)->interface_id = context->header()->interface_id; if (context->header()->flags & (Message::kFlagExpectsResponse | Message::kFlagIsResponse)) { DCHECK_GE(context->header()->version, 1u); - static_cast<internal::MessageHeaderV1*>(storage)->request_id = + static_cast<internal::MessageHeaderV1*>(buffer)->request_id = context->header()->request_id; } + context->SerializePayload(&payload_buffer); } @@ -184,22 +159,17 @@ delete reinterpret_cast<internal::UnserializedMessageContext*>(context); } -const MojoMessageOperationThunks kUnserializedMessageContextThunks{ - sizeof(MojoMessageOperationThunks), - &GetSerializedSizeFromUnserializedContext, - &SerializeHandlesFromUnserializedContext, - &SerializePayloadFromUnserializedContext, - &DestroyUnserializedContext, -}; - ScopedMessageHandle CreateUnserializedMessageObject( std::unique_ptr<internal::UnserializedMessageContext> context) { ScopedMessageHandle handle; - MojoResult rv = - mojo::CreateMessage(reinterpret_cast<uintptr_t>(context.release()), - &kUnserializedMessageContextThunks, &handle); + MojoResult rv = mojo::CreateMessage(&handle); DCHECK_EQ(MOJO_RESULT_OK, rv); DCHECK(handle.is_valid()); + + rv = MojoAttachMessageContext( + handle->value(), reinterpret_cast<uintptr_t>(context.release()), + &SerializeUnserializedContext, &DestroyUnserializedContext); + DCHECK_EQ(MOJO_RESULT_OK, rv); return handle; }
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc index d498f049..ed00e6a2 100644 --- a/mojo/public/cpp/bindings/tests/validation_unittest.cc +++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" +#include "base/numerics/safe_math.h" #include "base/run_loop.h" #include "base/threading/thread_task_runner_handle.h" #include "mojo/public/c/system/macros.h" @@ -34,33 +35,20 @@ namespace test { namespace { -void GetSerializedRawMessageSize(uintptr_t context, - size_t* num_bytes, - size_t* num_handles) { - *num_bytes = *reinterpret_cast<size_t*>(context); - *num_handles = 0; -} -static void IgnoreSerializeHandles(uintptr_t, MojoHandle*) {} -static void IgnoreSerializePayload(uintptr_t, void*) {} -static void IgnoreDestroy(uintptr_t) {} - -const MojoMessageOperationThunks kRawMessageThunks{ - sizeof(MojoMessageOperationThunks), - &GetSerializedRawMessageSize, - &IgnoreSerializeHandles, - &IgnoreSerializePayload, - &IgnoreDestroy, -}; - Message CreateRawMessage(size_t size) { ScopedMessageHandle handle; - MojoResult rv = CreateMessage(reinterpret_cast<uintptr_t>(&size), - &kRawMessageThunks, &handle); + MojoResult rv = CreateMessage(&handle); DCHECK_EQ(MOJO_RESULT_OK, rv); DCHECK(handle.is_valid()); - rv = MojoSerializeMessage(handle->value()); + DCHECK(base::IsValueInRangeForNumericType<uint32_t>(size)); + void* buffer; + uint32_t buffer_size; + rv = MojoAttachSerializedMessageBuffer(handle->value(), + static_cast<uint32_t>(size), nullptr, + 0, &buffer, &buffer_size); DCHECK_EQ(MOJO_RESULT_OK, rv); + return Message(std::move(handle)); }
diff --git a/mojo/public/cpp/system/message.h b/mojo/public/cpp/system/message.h index 13d7f85..58aed263 100644 --- a/mojo/public/cpp/system/message.h +++ b/mojo/public/cpp/system/message.h
@@ -50,11 +50,9 @@ using ScopedMessageHandle = ScopedHandleBase<MessageHandle>; -inline MojoResult CreateMessage(uintptr_t context, - const MojoMessageOperationThunks* thunks, - ScopedMessageHandle* handle) { +inline MojoResult CreateMessage(ScopedMessageHandle* handle) { MojoMessageHandle raw_handle; - MojoResult rv = MojoCreateMessage(context, thunks, &raw_handle); + MojoResult rv = MojoCreateMessage(&raw_handle); if (rv != MOJO_RESULT_OK) return rv;
diff --git a/mojo/public/cpp/system/message_pipe.cc b/mojo/public/cpp/system/message_pipe.cc index 3f66b92..f5b1c0a 100644 --- a/mojo/public/cpp/system/message_pipe.cc +++ b/mojo/public/cpp/system/message_pipe.cc
@@ -4,82 +4,31 @@ #include "mojo/public/cpp/system/message_pipe.h" +#include "base/numerics/safe_math.h" + namespace mojo { -namespace { - -struct RawMessage { - RawMessage(const void* bytes, - size_t num_bytes, - const MojoHandle* handles, - size_t num_handles) - : bytes(static_cast<const uint8_t*>(bytes)), - num_bytes(num_bytes), - handles(handles), - num_handles(num_handles) {} - - const uint8_t* const bytes; - const size_t num_bytes; - const MojoHandle* const handles; - const size_t num_handles; -}; - -void GetRawMessageSize(uintptr_t context, - size_t* num_bytes, - size_t* num_handles) { - auto* message = reinterpret_cast<RawMessage*>(context); - *num_bytes = message->num_bytes; - *num_handles = message->num_handles; -} - -void SerializeRawMessageHandles(uintptr_t context, MojoHandle* handles) { - auto* message = reinterpret_cast<RawMessage*>(context); - DCHECK(message->handles); - DCHECK(message->num_handles); - std::copy(message->handles, message->handles + message->num_handles, handles); -} - -void SerializeRawMessagePayload(uintptr_t context, void* buffer) { - auto* message = reinterpret_cast<RawMessage*>(context); - DCHECK(message->bytes); - DCHECK(message->num_bytes); - std::copy(message->bytes, message->bytes + message->num_bytes, - static_cast<uint8_t*>(buffer)); -} - -void DoNothing(uintptr_t context) {} - -const MojoMessageOperationThunks kRawMessageThunks = { - sizeof(kRawMessageThunks), - &GetRawMessageSize, - &SerializeRawMessageHandles, - &SerializeRawMessagePayload, - &DoNothing, -}; - -} // namespace - MojoResult WriteMessageRaw(MessagePipeHandle message_pipe, const void* bytes, size_t num_bytes, const MojoHandle* handles, size_t num_handles, MojoWriteMessageFlags flags) { - RawMessage message(bytes, num_bytes, handles, num_handles); ScopedMessageHandle message_handle; - MojoResult rv = CreateMessage(reinterpret_cast<uintptr_t>(&message), - &kRawMessageThunks, &message_handle); + MojoResult rv = CreateMessage(&message_handle); DCHECK_EQ(MOJO_RESULT_OK, rv); - // Force the message object to be serialized immediately so we can copy the - // local data in. - if (MojoSerializeMessage(message_handle->value()) != MOJO_RESULT_OK) { - // If serialization fails for some reason (e.g. invalid handles) we must - // be careful to not propagate the message object further. It is unsafe for - // the message's unserialized context to persist beyond the scope of this - // function. + void* buffer; + uint32_t buffer_size; + rv = MojoAttachSerializedMessageBuffer( + message_handle->value(), base::checked_cast<uint32_t>(num_bytes), handles, + base::checked_cast<uint32_t>(num_handles), &buffer, &buffer_size); + if (rv != MOJO_RESULT_OK) return MOJO_RESULT_ABORTED; - } + + DCHECK(buffer); + DCHECK_GE(buffer_size, base::checked_cast<uint32_t>(num_bytes)); + memcpy(buffer, bytes, num_bytes); return MojoWriteMessage(message_pipe.value(), message_handle.release().value(), flags);
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index 42b107d..cd8f0f8 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -43,6 +43,7 @@ "//ui/events/mojo/typemaps.gni", "//ui/gfx/typemaps.gni", "//ui/latency/mojo/typemaps.gni", + "//ui/ozone/public/interfaces/typemaps.gni", "//ui/message_center/mojo/typemaps.gni", "//url/mojo/typemaps.gni", ]
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index c196e68..a61f168d 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc
@@ -612,8 +612,7 @@ entry_ptr->disk_entry->Doom(); entry_ptr->doomed = true; - DCHECK(entry_ptr->writer || !entry_ptr->readers.empty() || - entry_ptr->headers_transaction || + DCHECK(!entry_ptr->HasNoTransactions() || entry_ptr->will_process_queued_transactions); return OK; } @@ -915,6 +914,10 @@ // Restart already validated transactions so that they are able to read // the truncated status of the entry. RestartHeadersPhaseTransactions(entry, transaction); + if (entry->HasNoTransactions() && + !entry->will_process_queued_transactions) { + DestroyEntry(entry); + } return; } DoneWritingToEntry(entry, success && !did_truncate, transaction);
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc index e37c7b0..e9248ba 100644 --- a/net/socket/ssl_client_socket_impl.cc +++ b/net/socket/ssl_client_socket_impl.cc
@@ -928,6 +928,9 @@ case kTLS13VariantExperiment: SSL_set_tls13_variant(ssl_.get(), tls13_experiment); break; + case kTLS13VariantRecordTypeExperiment: + SSL_set_tls13_variant(ssl_.get(), tls13_record_type_experiment); + break; } // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h index 4a2a13b..c0b2357 100644 --- a/net/ssl/ssl_config.h +++ b/net/ssl/ssl_config.h
@@ -38,6 +38,7 @@ enum TLS13Variant { kTLS13VariantDraft = 0, kTLS13VariantExperiment = 1, + kTLS13VariantRecordTypeExperiment = 2, }; // Default minimum protocol version.
diff --git a/remoting/ios/BUILD.gn b/remoting/ios/BUILD.gn index 67589d8..d3108ae 100644 --- a/remoting/ios/BUILD.gn +++ b/remoting/ios/BUILD.gn
@@ -27,28 +27,16 @@ "client_gestures.mm", "client_keyboard.h", "client_keyboard.mm", - "host_preferences.h", - "host_preferences.mm", - "host_preferences_persistence.h", "keychain_wrapper.h", "keychain_wrapper.mm", ] - if (!is_chrome_branded) { - sources += [ "host_preferences_persistence_chromium.mm" ] - } else { - # TODO(nicholss): Until we have a private implementation of this, stub it - # with the chromium version. We still want the logic of is_chrome_branded - # but to get the release builds building we will just reuse the file. - sources += [ "host_preferences_persistence_chromium.mm" ] - } - public_deps = [ "//remoting/ios/domain", "//remoting/ios/facade", "//remoting/ios/session", - "//third_party/webrtc/rtc_base:rtc_base", "//third_party/webrtc/modules/desktop_capture:primitives", + "//third_party/webrtc/rtc_base:rtc_base", ] deps = [
diff --git a/remoting/ios/app/BUILD.gn b/remoting/ios/app/BUILD.gn index 7fc1ce8..2bee702c 100644 --- a/remoting/ios/app/BUILD.gn +++ b/remoting/ios/app/BUILD.gn
@@ -70,7 +70,9 @@ "//remoting/ios/app/resources:assets", "//remoting/ios/app/settings", "//remoting/ios/display", + "//remoting/ios/domain", "//remoting/ios/mdc", + "//remoting/ios/persistence", "//remoting/protocol", "//ui/base", "//ui/gfx",
diff --git a/remoting/ios/app/host_view_controller.mm b/remoting/ios/app/host_view_controller.mm index ea36e730..4af3cd89 100644 --- a/remoting/ios/app/host_view_controller.mm +++ b/remoting/ios/app/host_view_controller.mm
@@ -16,7 +16,10 @@ #import "remoting/ios/client_gestures.h" #import "remoting/ios/client_keyboard.h" #import "remoting/ios/display/eagl_view.h" +#import "remoting/ios/domain/host_info.h" +#import "remoting/ios/domain/host_settings.h" #import "remoting/ios/mdc/MDCActionImageView.h" +#import "remoting/ios/persistence/remoting_preferences.h" #import "remoting/ios/session/remoting_client.h" #include "base/strings/sys_string_conversions.h" @@ -37,6 +40,7 @@ ClientKeyboard* _clientKeyboard; CGSize _keyboardSize; BOOL _surfaceCreated; + HostSettings* _settings; } @end @@ -48,6 +52,8 @@ _client = client; _keyboardSize = CGSizeZero; _surfaceCreated = NO; + _settings = + [[RemotingPreferences instance] settingsForHost:client.hostInfo.hostId]; } return self; } @@ -81,9 +87,7 @@ [_floatingButton addSubview:_actionImageView]; [self.view addSubview:_floatingButton]; - // TODO(yuweih): This should be loaded from and stored into user defaults. - _client.gestureInterpreter->SetInputMode( - remoting::GestureInterpreter::DIRECT_INPUT_MODE); + [self applyInputMode]; } - (void)viewDidUnload { @@ -135,6 +139,9 @@ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; + [[RemotingPreferences instance] setSettings:_settings + forHost:_client.hostInfo.hostId]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } @@ -242,15 +249,13 @@ } - (void)useDirectInputMode { - // TODO(nicholss): Store this as a preference. - _client.gestureInterpreter->SetInputMode( - remoting::GestureInterpreter::DIRECT_INPUT_MODE); + _settings.inputMode = ClientInputModeDirect; + [self applyInputMode]; } - (void)useTrackpadInputMode { - // TODO(nicholss): Store this as a preference. - _client.gestureInterpreter->SetInputMode( - remoting::GestureInterpreter::TRACKPAD_INPUT_MODE); + _settings.inputMode = ClientInputModeTrackpad; + [self applyInputMode]; } - (void)sendCtrAltDel { @@ -263,6 +268,19 @@ #pragma mark - Private +- (void)applyInputMode { + switch (_settings.inputMode) { + case ClientInputModeTrackpad: + _client.gestureInterpreter->SetInputMode( + remoting::GestureInterpreter::TRACKPAD_INPUT_MODE); + break; + case ClientInputModeDirect: // Fall-through. + default: + _client.gestureInterpreter->SetInputMode( + remoting::GestureInterpreter::DIRECT_INPUT_MODE); + } +} + - (void)didTap:(id)sender { // TODO(nicholss): The FAB is being used to launch an alert window with // more options. This is not ideal but it gets us an easy way to make a @@ -298,10 +316,15 @@ ? @"Trackpad Mode" : @"Touch Mode"; void (^switchInputModeHandler)(UIAlertAction*) = ^(UIAlertAction*) { - _client.gestureInterpreter->SetInputMode( - currentInputMode == remoting::GestureInterpreter::DIRECT_INPUT_MODE - ? remoting::GestureInterpreter::TRACKPAD_INPUT_MODE - : remoting::GestureInterpreter::DIRECT_INPUT_MODE); + switch (currentInputMode) { + case remoting::GestureInterpreter::DIRECT_INPUT_MODE: + [self useTrackpadInputMode]; + break; + case remoting::GestureInterpreter::TRACKPAD_INPUT_MODE: // Fall-through. + default: + [self useDirectInputMode]; + break; + } [_actionImageView setActive:NO animated:YES]; }; [alert addAction:[UIAlertAction actionWithTitle:switchInputModeTitle
diff --git a/remoting/ios/domain/BUILD.gn b/remoting/ios/domain/BUILD.gn index 4f708511..238f6fc 100644 --- a/remoting/ios/domain/BUILD.gn +++ b/remoting/ios/domain/BUILD.gn
@@ -12,6 +12,8 @@ "client_session_details.mm", "host_info.h", "host_info.mm", + "host_settings.h", + "host_settings.mm", "user_info.h", "user_info.mm", ]
diff --git a/remoting/ios/domain/host_settings.h b/remoting/ios/domain/host_settings.h new file mode 100644 index 0000000..25e95b6 --- /dev/null +++ b/remoting/ios/domain/host_settings.h
@@ -0,0 +1,25 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_IOS_DOMAIN_HOST_SETTINGS_H_ +#define REMOTING_IOS_DOMAIN_HOST_SETTINGS_H_ + +#import <Foundation/Foundation.h> + +typedef NS_ENUM(NSInteger, ClientInputMode) { + ClientInputModeUndefined, + ClientInputModeDirect, + ClientInputModeTrackpad, +}; + +// A detail record for a Remoting Settings. +@interface HostSettings : NSObject<NSCoding> + +// Various properties of the Remoting Settings. +@property(nonatomic, copy) NSString* hostId; +@property(nonatomic) ClientInputMode inputMode; + +@end + +#endif // REMOTING_IOS_DOMAIN_HOST_SETTINGS_H_
diff --git a/remoting/ios/domain/host_settings.mm b/remoting/ios/domain/host_settings.mm new file mode 100644 index 0000000..4c8e9503 --- /dev/null +++ b/remoting/ios/domain/host_settings.mm
@@ -0,0 +1,37 @@ +// 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. + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#import "remoting/ios/domain/host_settings.h" + +@implementation HostSettings + +@synthesize hostId = _hostId; +@synthesize inputMode = _inputMode; + +- (id)initWithCoder:(NSCoder*)coder { + self = [super init]; + if (self) { + self.hostId = [coder decodeObjectForKey:@"hostId"]; + NSNumber* mode = [coder decodeObjectForKey:@"inputMode"]; + self.inputMode = (ClientInputMode)[mode intValue]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder*)coder { + [coder encodeObject:self.hostId forKey:@"hostId"]; + NSNumber* mode = [NSNumber numberWithInt:self.inputMode]; + [coder encodeObject:mode forKey:@"inputMode"]; +} + +- (NSString*)description { + return [NSString stringWithFormat:@"HostSettings: hostId=%@ inputMode=%d", + _hostId, (int)_inputMode]; +} + +@end
diff --git a/remoting/ios/facade/BUILD.gn b/remoting/ios/facade/BUILD.gn index 681ce32..c2f6623 100644 --- a/remoting/ios/facade/BUILD.gn +++ b/remoting/ios/facade/BUILD.gn
@@ -25,6 +25,7 @@ "//base", "//remoting/base:authorization", "//remoting/ios/domain", + "//remoting/ios/persistence", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/remoting/ios/facade/remoting_oauth_authentication.mm b/remoting/ios/facade/remoting_oauth_authentication.mm index 5bbbbf04..39cbc52 100644 --- a/remoting/ios/facade/remoting_oauth_authentication.mm +++ b/remoting/ios/facade/remoting_oauth_authentication.mm
@@ -18,6 +18,7 @@ #import "remoting/ios/facade/ios_client_runtime_delegate.h" #import "remoting/ios/facade/remoting_service.h" #import "remoting/ios/keychain_wrapper.h" +#import "remoting/ios/persistence/remoting_preferences.h" #include "base/logging.h" #include "base/strings/sys_string_conversions.h" @@ -25,9 +26,6 @@ #include "remoting/base/oauth_token_getter.h" #include "remoting/base/oauth_token_getter_impl.h" -static NSString* const kCRDAuthenticatedUserEmailKey = - @"kCRDAuthenticatedUserEmailKey"; - const char kOauthRedirectUrl[] = "https://chromoting-oauth.talkgadget." "google.com/talkgadget/oauth/chrome-remote-desktop/dev"; @@ -184,22 +182,19 @@ #pragma mark - Persistence - (void)storeUserInfo:(UserInfo*)user { - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; if (user) { - [defaults setObject:user.userEmail forKey:kCRDAuthenticatedUserEmailKey]; + [RemotingPreferences instance].activeUserKey = user.userEmail; // TODO(nicholss): Need to match the token with the email. [_keychainWrapper setRefreshToken:user.refreshToken]; } else { - [defaults removeObjectForKey:kCRDAuthenticatedUserEmailKey]; + [RemotingPreferences instance].activeUserKey = nil; [_keychainWrapper resetKeychainItem]; } - [defaults synchronize]; } - (UserInfo*)loadUserInfo { UserInfo* user = [[UserInfo alloc] init]; - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - user.userEmail = [defaults objectForKey:kCRDAuthenticatedUserEmailKey]; + user.userEmail = [RemotingPreferences instance].activeUserKey; // TODO(nicholss): Need to match the token with the email. user.refreshToken = [_keychainWrapper refreshToken];
diff --git a/remoting/ios/facade/remoting_service.h b/remoting/ios/facade/remoting_service.h index af15a60..0d315d2 100644 --- a/remoting/ios/facade/remoting_service.h +++ b/remoting/ios/facade/remoting_service.h
@@ -38,13 +38,13 @@ // singleton and should only be accessed via the |SharedInstance| method. @interface RemotingService : NSObject -// Access to the singleton shared instance from this method. -+ (RemotingService*)instance; - // Start a request to fetch the host list. This will produce an notification on // |kHostsDidUpdate| when a new host is ready. - (void)requestHostListFetch; +// Access to the singleton shared instance from this property. +@property(nonatomic, readonly, class) RemotingService* instance; + // Returns the current host list. @property(nonatomic, readonly) NSArray<HostInfo*>* hosts;
diff --git a/remoting/ios/host_preferences.h b/remoting/ios/host_preferences.h deleted file mode 100644 index d8dba18..0000000 --- a/remoting/ios/host_preferences.h +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef REMOTING_IOS_HOST_PREFERENCES_H_ -#define REMOTING_IOS_HOST_PREFERENCES_H_ - -#import <CoreData/CoreData.h> - -// A HostPreferences contains details to negotiate and maintain a connection -// to a remote Chromoting host. This is an entity in a backing store. -@interface HostPreferences : NSObject<NSCoding> - -// Properties supplied by the host server. -@property(nonatomic, copy) NSString* hostId; -@property(nonatomic, copy) NSString* pairId; -@property(nonatomic, copy) NSString* pairSecret; - -// Commit this record using the Keychain for current identity. -- (void)saveToKeychain; - -// Load a record from the Keychain for current identity. -// If a record does not exist, return a new record with a blank secret. -+ (HostPreferences*)hostForId:(NSString*)hostId; - -@end - -#endif // REMOTING_IOS_HOST_PREFERENCES_H_
diff --git a/remoting/ios/host_preferences.mm b/remoting/ios/host_preferences.mm deleted file mode 100644 index d0c0efc..0000000 --- a/remoting/ios/host_preferences.mm +++ /dev/null
@@ -1,92 +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. - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import "remoting/ios/host_preferences.h" - -#import "base/logging.h" -#import "remoting/ios/host_preferences_persistence.h" - -namespace { -static NSString* const kHostPreferencesDataKeyHostDictionary = - @"kHostPreferencesDataKeyHostDictionary"; -static NSString* const kHostPreferencesHostIdKey = @"HostId"; -static NSString* const kHostPreferencesPairIdKey = @"PairId"; -static NSString* const kHostPreferencesPairSecretKey = @"PairSecret"; -} // namespace - -@interface HostPreferences () - -// Load the known hosts from the Keychain. -// If no data exists, return an empty dictionary -+ (NSMutableDictionary*)loadHosts; - -@end - -@implementation HostPreferences - -@synthesize hostId = _hostId; -@synthesize pairId = _pairId; -@synthesize pairSecret = _pairSecret; - -#pragma mark - Public - -- (void)saveToKeychain { - NSMutableDictionary* hosts = [HostPreferences loadHosts]; - [hosts setObject:self forKey:_hostId]; - - NSData* writeData = [NSKeyedArchiver archivedDataWithRootObject:hosts]; - - NSError* keychainError = - remoting::ios::WriteHostPreferencesToKeychain(writeData); - - LOG_IF(ERROR, !keychainError) << "Could not write to keychain."; -} - -+ (HostPreferences*)hostForId:(NSString*)hostId { - NSMutableDictionary* hosts = [HostPreferences loadHosts]; - HostPreferences* host = hosts[hostId]; - if (!host) { - host = [[HostPreferences alloc] init]; - host.hostId = hostId; - host.pairId = @""; - host.pairSecret = @""; - } - return host; -} - -#pragma mark - Private - -+ (NSMutableDictionary*)loadHosts { - NSData* readData = remoting::ios::ReadHostPreferencesFromKeychain(); - if (readData) { - return [NSKeyedUnarchiver unarchiveObjectWithData:readData]; - } else { - return [[NSMutableDictionary alloc] init]; - } -} - -#pragma mark - NSCoding - -- (instancetype)initWithCoder:(NSCoder*)coder { - self = [super init]; - if (self) { - [self setHostId:[coder decodeObjectForKey:kHostPreferencesHostIdKey]]; - [self setPairId:[coder decodeObjectForKey:kHostPreferencesPairIdKey]]; - [self - setPairSecret:[coder decodeObjectForKey:kHostPreferencesPairSecretKey]]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder*)coder { - [coder encodeObject:_hostId forKey:kHostPreferencesHostIdKey]; - [coder encodeObject:_pairId forKey:kHostPreferencesPairIdKey]; - [coder encodeObject:_pairSecret forKey:kHostPreferencesPairSecretKey]; -} - -@end
diff --git a/remoting/ios/host_preferences_persistence.h b/remoting/ios/host_preferences_persistence.h deleted file mode 100644 index 486b64f..0000000 --- a/remoting/ios/host_preferences_persistence.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef REMOTING_IOS_HOST_PREFERENCES_PERSISTENCE_H_ -#define REMOTING_IOS_HOST_PREFERENCES_PERSISTENCE_H_ - -#import <CoreData/CoreData.h> - -// Methods used to store and recall Host Prefrences on the keychain. -// Used to cache data for quicker connection to previously fetched host data. -namespace remoting { -namespace ios { - -NSError* WriteHostPreferencesToKeychain(NSData* data); -NSData* ReadHostPreferencesFromKeychain(); - -} // namespace ios -} // namespace remoting - -#endif // REMOTING_IOS_HOST_PREFERENCES_PERSISTENCE_H_
diff --git a/remoting/ios/host_preferences_persistence_chromium.mm b/remoting/ios/host_preferences_persistence_chromium.mm deleted file mode 100644 index a2258db4..0000000 --- a/remoting/ios/host_preferences_persistence_chromium.mm +++ /dev/null
@@ -1,28 +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. - -#import "remoting/ios/host_preferences_persistence.h" - -#import "base/logging.h" - -namespace remoting { -namespace ios { - -// TODO(nicholss): It might be useful to save |data| in a static variable, -// which is then returned from ReadHostPreferencesFromKeychain(). This would -// allow to test pairing, even though the pairing info is not persisted when -// the app is restarted. - -NSError* WriteHostPreferencesToKeychain(NSData* data) { - NOTIMPLEMENTED(); - return nil; -} - -NSData* ReadHostPreferencesFromKeychain() { - NOTIMPLEMENTED(); - return nil; -} - -} // namespace ios -} // namespace remoting
diff --git a/remoting/ios/persistence/BUILD.gn b/remoting/ios/persistence/BUILD.gn new file mode 100644 index 0000000..54afc44a --- /dev/null +++ b/remoting/ios/persistence/BUILD.gn
@@ -0,0 +1,21 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chrome_build.gni") +import("//build/config/ios/rules.gni") +import("//remoting/build/config/remoting_build.gni") + +source_set("persistence") { + sources = [ + "remoting_preferences.h", + "remoting_preferences.mm", + ] + + deps = [ + "//base", + "//remoting/ios/domain", + ] + + configs += [ "//build/config/compiler:enable_arc" ] +}
diff --git a/remoting/ios/persistence/remoting_preferences.h b/remoting/ios/persistence/remoting_preferences.h new file mode 100644 index 0000000..cd677196 --- /dev/null +++ b/remoting/ios/persistence/remoting_preferences.h
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_IOS_PERSISTENCE_REMOTING_PREFERENCES_H_ +#define REMOTING_IOS_PERSISTENCE_REMOTING_PREFERENCES_H_ + +#import <Foundation/Foundation.h> + +@class HostSettings; + +// |RemotingPreferences| is the centralized place to ask for information about +// defaults and prefrences. +@interface RemotingPreferences : NSObject + +- (HostSettings*)settingsForHost:(NSString*)hostId; +- (void)setSettings:(HostSettings*)settings forHost:(NSString*)hostId; + +// Access to the singleton shared instance from this property. +@property(nonatomic, readonly, class) RemotingPreferences* instance; + +@property(nonatomic) NSString* activeUserKey; + +@end + +#endif // REMOTING_IOS_PERSISTENCE_REMOTING_PREFERENCES_H_
diff --git a/remoting/ios/persistence/remoting_preferences.mm b/remoting/ios/persistence/remoting_preferences.mm new file mode 100644 index 0000000..a148c9b --- /dev/null +++ b/remoting/ios/persistence/remoting_preferences.mm
@@ -0,0 +1,89 @@ +// 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. + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#import "remoting/ios/persistence/remoting_preferences.h" + +#import "base/mac/bind_objc_block.h" +#import "remoting/ios/domain/host_info.h" +#import "remoting/ios/domain/host_settings.h" + +#include "base/logging.h" + +static NSString* const kActiveUserKey = @"kActiveUserKey"; +static NSString* const kHostSettingsKey = @"kHostSettingsKey"; + +@interface RemotingPreferences () { + NSUserDefaults* _defaults; +} +@end + +@implementation RemotingPreferences + +// RemotingService is a singleton. ++ (RemotingPreferences*)instance { + static RemotingPreferences* sharedInstance = nil; + static dispatch_once_t guard; + dispatch_once(&guard, ^{ + sharedInstance = [[RemotingPreferences alloc] init]; + }); + return sharedInstance; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _defaults = [NSUserDefaults standardUserDefaults]; + } + return self; +} + +#pragma mark - RemotingPreferences Implementation + +- (HostSettings*)settingsForHost:(NSString*)hostId { + NSString* key = + [NSString stringWithFormat:@"%@-%@", kHostSettingsKey, hostId]; + NSData* encodedSettings = [_defaults objectForKey:key]; + HostSettings* settings = + [NSKeyedUnarchiver unarchiveObjectWithData:encodedSettings]; + if (settings == nil) { + settings = [[HostSettings alloc] init]; + settings.hostId = hostId; + [self setSettings:settings forHost:hostId]; + } + return settings; +} + +- (void)setSettings:(HostSettings*)settings forHost:(NSString*)hostId { + NSString* key = + [NSString stringWithFormat:@"%@-%@", kHostSettingsKey, hostId]; + if (settings) { + NSData* encodedSettings = + [NSKeyedArchiver archivedDataWithRootObject:settings]; + [_defaults setObject:encodedSettings forKey:key]; + } else { + return [_defaults removeObjectForKey:key]; + } + [_defaults synchronize]; +} + +#pragma mark - Properties + +- (void)setActiveUserKey:(NSString*)activeUserKey { + if (activeUserKey) { + [_defaults setObject:activeUserKey forKey:kActiveUserKey]; + } else { + [_defaults removeObjectForKey:kActiveUserKey]; + } + [_defaults synchronize]; +} + +- (NSString*)activeUserKey { + return [_defaults objectForKey:kActiveUserKey]; +} + +@end
diff --git a/services/shape_detection/barcode_detection_impl_mac.h b/services/shape_detection/barcode_detection_impl_mac.h index 062a68b..51f32b3 100644 --- a/services/shape_detection/barcode_detection_impl_mac.h +++ b/services/shape_detection/barcode_detection_impl_mac.h
@@ -5,6 +5,7 @@ #ifndef SERVICES_SHAPE_DETECTION_BARCODE_DETECTION_IMPL_MAC_H_ #define SERVICES_SHAPE_DETECTION_BARCODE_DETECTION_IMPL_MAC_H_ +#include "base/mac/availability.h" #include "base/mac/scoped_nsobject.h" #include "services/shape_detection/public/interfaces/barcodedetection.mojom.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -13,7 +14,10 @@ namespace shape_detection { -class BarcodeDetectionImplMac +// The __attribute__ visibility annotation is necessary to work around a clang +// bug: https://bugs.llvm.org/show_bug.cgi?id=33796. +class API_AVAILABLE(macosx(10.10)) + __attribute__((visibility("hidden"))) BarcodeDetectionImplMac : public shape_detection::mojom::BarcodeDetection { public: BarcodeDetectionImplMac();
diff --git a/services/shape_detection/barcode_detection_impl_mac.mm b/services/shape_detection/barcode_detection_impl_mac.mm index 6aa128f..d449d8c 100644 --- a/services/shape_detection/barcode_detection_impl_mac.mm +++ b/services/shape_detection/barcode_detection_impl_mac.mm
@@ -29,19 +29,17 @@ const service_manager::BindSourceInfo& source_info, shape_detection::mojom::BarcodeDetectionRequest request) { // Barcode detection needs at least MAC OS X 10.10. - if (!base::mac::IsAtLeastOS10_10()) - return; - mojo::MakeStrongBinding(base::MakeUnique<BarcodeDetectionImplMac>(), - std::move(request)); + if (@available(macOS 10.10, *)) { + mojo::MakeStrongBinding(base::MakeUnique<BarcodeDetectionImplMac>(), + std::move(request)); + } } BarcodeDetectionImplMac::BarcodeDetectionImplMac() { NSDictionary* const options = @{CIDetectorAccuracy : CIDetectorAccuracyHigh}; - if (@available(macOS 10.10, *)) { - detector_.reset([[CIDetector detectorOfType:CIDetectorTypeQRCode - context:nil - options:options] retain]); - } + detector_.reset([[CIDetector detectorOfType:CIDetectorTypeQRCode + context:nil + options:options] retain]); } BarcodeDetectionImplMac::~BarcodeDetectionImplMac() {}
diff --git a/services/shape_detection/barcode_detection_impl_mac_unittest.mm b/services/shape_detection/barcode_detection_impl_mac_unittest.mm index b30879c..386dbe9 100644 --- a/services/shape_detection/barcode_detection_impl_mac_unittest.mm +++ b/services/shape_detection/barcode_detection_impl_mac_unittest.mm
@@ -31,7 +31,7 @@ } MOCK_METHOD2(Detection, void(size_t, const std::string&)); - BarcodeDetectionImplMac impl_; + API_AVAILABLE(macosx(10.10)) std::unique_ptr<BarcodeDetectionImplMac> impl_; const base::MessageLoop message_loop_; }; @@ -41,51 +41,54 @@ TEST_F(BarcodeDetectionImplMacTest, ScanOneBarcode) { // Barcode detection needs at least MAC OS X 10.10, and GPU infrastructure. if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUseGpuInTests) || - !base::mac::IsAtLeastOS10_10()) { + switches::kUseGpuInTests)) { return; } - const std::string kInfoString = "https://www.chromium.org"; - // Generate a QR code image as a CIImage by using |qr_code_generator|. - NSData* const qr_code_data = - [[NSString stringWithUTF8String:kInfoString.c_str()] - dataUsingEncoding:NSISOLatin1StringEncoding]; - // TODO(mcasas): Consider using other generator types (e.g. - // CI{AztecCode,Code128Barcode,PDF417Barcode}Generator) when the minimal OS X - // is upgraded to 10.10+ (https://crbug.com/624049). - CIFilter* qr_code_generator = - [CIFilter filterWithName:@"CIQRCodeGenerator"]; - [qr_code_generator setValue:qr_code_data forKey:@"inputMessage"]; + if (@available(macOS 10.10, *)) { + impl_.reset(new BarcodeDetectionImplMac); + const std::string kInfoString = "https://www.chromium.org"; + // Generate a QR code image as a CIImage by using |qr_code_generator|. + NSData* const qr_code_data = + [[NSString stringWithUTF8String:kInfoString.c_str()] + dataUsingEncoding:NSISOLatin1StringEncoding]; + // TODO(mcasas): Consider using other generator types (e.g. + // CI{AztecCode,Code128Barcode,PDF417Barcode}Generator) when the minimal OS + // X is upgraded to 10.10+ (https://crbug.com/624049). + CIFilter* qr_code_generator = + [CIFilter filterWithName:@"CIQRCodeGenerator"]; + [qr_code_generator setValue:qr_code_data forKey:@"inputMessage"]; - // [CIImage outputImage] is available in macOS 10.10+. Could be added to - // sdk_forward_declarations.h but seems hardly worth it. - EXPECT_TRUE([qr_code_generator respondsToSelector:@selector(outputImage)]); - CIImage* qr_code_image = - [qr_code_generator performSelector:@selector(outputImage)]; + // [CIImage outputImage] is available in macOS 10.10+. Could be added to + // sdk_forward_declarations.h but seems hardly worth it. + EXPECT_TRUE([qr_code_generator respondsToSelector:@selector(outputImage)]); + CIImage* qr_code_image = + [qr_code_generator performSelector:@selector(outputImage)]; - const gfx::Size size([qr_code_image extent].size.width, - [qr_code_image extent].size.height); + const gfx::Size size([qr_code_image extent].size.width, + [qr_code_image extent].size.height); - base::scoped_nsobject<CIContext> context([[CIContext alloc] init]); + base::scoped_nsobject<CIContext> context([[CIContext alloc] init]); - base::ScopedCFTypeRef<CGImageRef> cg_image( - [context createCGImage:qr_code_image fromRect:[qr_code_image extent]]); - EXPECT_EQ(static_cast<size_t>(size.width()), CGImageGetWidth(cg_image)); - EXPECT_EQ(static_cast<size_t>(size.height()), CGImageGetHeight(cg_image)); + base::ScopedCFTypeRef<CGImageRef> cg_image( + [context createCGImage:qr_code_image fromRect:[qr_code_image extent]]); + EXPECT_EQ(static_cast<size_t>(size.width()), CGImageGetWidth(cg_image)); + EXPECT_EQ(static_cast<size_t>(size.height()), CGImageGetHeight(cg_image)); - SkBitmap bitmap; - ASSERT_TRUE(SkCreateBitmapFromCGImage(&bitmap, cg_image)); + SkBitmap bitmap; + ASSERT_TRUE(SkCreateBitmapFromCGImage(&bitmap, cg_image)); - base::RunLoop run_loop; - base::Closure quit_closure = run_loop.QuitClosure(); - // Send the image Detect() and expect the response in callback. - EXPECT_CALL(*this, Detection(1, kInfoString)) - .WillOnce(RunClosure(quit_closure)); - impl_.Detect(bitmap, base::Bind(&BarcodeDetectionImplMacTest::DetectCallback, - base::Unretained(this))); + base::RunLoop run_loop; + base::Closure quit_closure = run_loop.QuitClosure(); + // Send the image Detect() and expect the response in callback. + EXPECT_CALL(*this, Detection(1, kInfoString)) + .WillOnce(RunClosure(quit_closure)); + impl_->Detect(bitmap, + base::Bind(&BarcodeDetectionImplMacTest::DetectCallback, + base::Unretained(this))); - run_loop.Run(); + run_loop.Run(); + } } } // shape_detection namespace
diff --git a/services/shape_detection/text_detection_impl_mac.h b/services/shape_detection/text_detection_impl_mac.h index 64563c67..83a5f177 100644 --- a/services/shape_detection/text_detection_impl_mac.h +++ b/services/shape_detection/text_detection_impl_mac.h
@@ -5,6 +5,7 @@ #ifndef SERVICES_SHAPE_DETECTION_TEXT_DETECTION_IMPL_MAC_H_ #define SERVICES_SHAPE_DETECTION_TEXT_DETECTION_IMPL_MAC_H_ +#include "base/mac/availability.h" #include "base/mac/scoped_nsobject.h" #include "services/shape_detection/public/interfaces/textdetection.mojom.h" @@ -12,7 +13,11 @@ namespace shape_detection { -class TextDetectionImplMac : public mojom::TextDetection { +// The __attribute__ visibility annotation is necessary to work around a clang +// bug: https://bugs.llvm.org/show_bug.cgi?id=33796. +class API_AVAILABLE(macosx(10.11)) + __attribute__((visibility("hidden"))) TextDetectionImplMac + : public mojom::TextDetection { public: TextDetectionImplMac(); ~TextDetectionImplMac() override;
diff --git a/services/shape_detection/text_detection_impl_mac.mm b/services/shape_detection/text_detection_impl_mac.mm index f645cce..a2fec7a 100644 --- a/services/shape_detection/text_detection_impl_mac.mm +++ b/services/shape_detection/text_detection_impl_mac.mm
@@ -28,17 +28,17 @@ const service_manager::BindSourceInfo& source_info, mojom::TextDetectionRequest request) { // Text detection needs at least MAC OS X 10.11. - if (!base::mac::IsAtLeastOS10_11()) - return; - mojo::MakeStrongBinding(base::MakeUnique<TextDetectionImplMac>(), - std::move(request)); + if (@available(macOS 10.11, *)) { + mojo::MakeStrongBinding(base::MakeUnique<TextDetectionImplMac>(), + std::move(request)); + } } TextDetectionImplMac::TextDetectionImplMac() { NSDictionary* const opts = @{CIDetectorAccuracy : CIDetectorAccuracyHigh}; - detector_.reset([[CIDetector detectorOfType:CIDetectorTypeText - context:nil - options:opts] retain]); + detector_.reset( + [[CIDetector detectorOfType:CIDetectorTypeText context:nil options:opts] + retain]); } TextDetectionImplMac::~TextDetectionImplMac() {}
diff --git a/services/shape_detection/text_detection_impl_mac_unittest.mm b/services/shape_detection/text_detection_impl_mac_unittest.mm index 71def0f..8981645 100644 --- a/services/shape_detection/text_detection_impl_mac_unittest.mm +++ b/services/shape_detection/text_detection_impl_mac_unittest.mm
@@ -32,7 +32,7 @@ } MOCK_METHOD1(Detection, void(size_t)); - TextDetectionImplMac impl_; + API_AVAILABLE(macosx(10.11)) std::unique_ptr<TextDetectionImplMac> impl_; const base::MessageLoop message_loop_; }; @@ -47,53 +47,56 @@ return; } - base::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace( - CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); + if (@available(macOS 10.11, *)) { + impl_.reset(new TextDetectionImplMac); + base::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace( + CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); - const int width = 200; - const int height = 50; - base::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate( - nullptr, width, height, 8 /* bitsPerComponent */, - width * 4 /* rowBytes */, rgb_colorspace, - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + const int width = 200; + const int height = 50; + base::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate( + nullptr, width, height, 8 /* bitsPerComponent */, + width * 4 /* rowBytes */, rgb_colorspace, + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - // Draw a white background. - CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); - CGContextFillRect(context, CGRectMake(0.0, 0.0, width, height)); + // Draw a white background. + CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); + CGContextFillRect(context, CGRectMake(0.0, 0.0, width, height)); - // Create a line of Helvetica 16 text, and draw it in the |context|. - base::scoped_nsobject<NSFont> helvetica( - [NSFont fontWithName:@"Helvetica" size:16]); - NSDictionary* attributes = [NSDictionary - dictionaryWithObjectsAndKeys:helvetica, kCTFontAttributeName, nil]; + // Create a line of Helvetica 16 text, and draw it in the |context|. + base::scoped_nsobject<NSFont> helvetica( + [NSFont fontWithName:@"Helvetica" size:16]); + NSDictionary* attributes = [NSDictionary + dictionaryWithObjectsAndKeys:helvetica, kCTFontAttributeName, nil]; - base::scoped_nsobject<NSAttributedString> info([[NSAttributedString alloc] - initWithString:@"https://www.chromium.org" - attributes:attributes]); + base::scoped_nsobject<NSAttributedString> info([[NSAttributedString alloc] + initWithString:@"https://www.chromium.org" + attributes:attributes]); - base::ScopedCFTypeRef<CTLineRef> line( - CTLineCreateWithAttributedString((CFAttributedStringRef)info.get())); + base::ScopedCFTypeRef<CTLineRef> line( + CTLineCreateWithAttributedString((CFAttributedStringRef)info.get())); - CGContextSetTextPosition(context, 10.0, height / 2.0); - CTLineDraw(line, context); + CGContextSetTextPosition(context, 10.0, height / 2.0); + CTLineDraw(line, context); - // Extract a CGImage and its raw pixels from |context|. - base::ScopedCFTypeRef<CGImageRef> cg_image( - CGBitmapContextCreateImage(context)); - EXPECT_EQ(static_cast<size_t>(width), CGImageGetWidth(cg_image)); - EXPECT_EQ(static_cast<size_t>(height), CGImageGetHeight(cg_image)); + // Extract a CGImage and its raw pixels from |context|. + base::ScopedCFTypeRef<CGImageRef> cg_image( + CGBitmapContextCreateImage(context)); + EXPECT_EQ(static_cast<size_t>(width), CGImageGetWidth(cg_image)); + EXPECT_EQ(static_cast<size_t>(height), CGImageGetHeight(cg_image)); - SkBitmap bitmap; - ASSERT_TRUE(SkCreateBitmapFromCGImage(&bitmap, cg_image)); + SkBitmap bitmap; + ASSERT_TRUE(SkCreateBitmapFromCGImage(&bitmap, cg_image)); - base::RunLoop run_loop; - base::Closure quit_closure = run_loop.QuitClosure(); - // Send the image to Detect() and expect the response in callback. - EXPECT_CALL(*this, Detection(1)).WillOnce(RunClosure(quit_closure)); - impl_.Detect(bitmap, base::Bind(&TextDetectionImplMacTest::DetectCallback, - base::Unretained(this))); + base::RunLoop run_loop; + base::Closure quit_closure = run_loop.QuitClosure(); + // Send the image to Detect() and expect the response in callback. + EXPECT_CALL(*this, Detection(1)).WillOnce(RunClosure(quit_closure)); + impl_->Detect(bitmap, base::Bind(&TextDetectionImplMacTest::DetectCallback, + base::Unretained(this))); - run_loop.Run(); + run_loop.Run(); + } } } // shape_detection namespace
diff --git a/services/ui/gpu/gpu_service.cc b/services/ui/gpu/gpu_service.cc index 777a29a..ef4877e 100644 --- a/services/ui/gpu/gpu_service.cc +++ b/services/ui/gpu/gpu_service.cc
@@ -11,7 +11,7 @@ #include "base/message_loop/message_loop.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "cc/output/in_process_context_provider.h" +#include "components/viz/common/gpu/in_process_context_provider.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/scheduler.h"
diff --git a/services/ui/public/cpp/DEPS b/services/ui/public/cpp/DEPS index 10ed84d5..90ba774 100644 --- a/services/ui/public/cpp/DEPS +++ b/services/ui/public/cpp/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/viz/common/gpu", "+gpu", "+mojo/gpu", "+skia/public/interfaces"
diff --git a/services/ui/public/cpp/gpu/context_provider_command_buffer.cc b/services/ui/public/cpp/gpu/context_provider_command_buffer.cc index da0f48d2..81f7c19 100644 --- a/services/ui/public/cpp/gpu/context_provider_command_buffer.cc +++ b/services/ui/public/cpp/gpu/context_provider_command_buffer.cc
@@ -17,8 +17,8 @@ #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" -#include "cc/output/context_cache_controller.h" #include "cc/output/managed_memory_policy.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/client/gles2_trace_implementation.h" @@ -317,7 +317,7 @@ shared_providers_->list.push_back(this); cache_controller_.reset( - new cc::ContextCacheController(gles2_impl_.get(), task_runner)); + new viz::ContextCacheController(gles2_impl_.get(), task_runner)); } set_bind_failed.Reset(); bind_succeeded_ = true; @@ -392,7 +392,7 @@ return gr_context_->get(); } -cc::ContextCacheController* ContextProviderCommandBuffer::CacheController() { +viz::ContextCacheController* ContextProviderCommandBuffer::CacheController() { DCHECK(context_thread_checker_.CalledOnValidThread()); return cache_controller_.get(); }
diff --git a/services/ui/public/cpp/gpu/context_provider_command_buffer.h b/services/ui/public/cpp/gpu/context_provider_command_buffer.h index a5afb59..c00c28f 100644 --- a/services/ui/public/cpp/gpu/context_provider_command_buffer.h +++ b/services/ui/public/cpp/gpu/context_provider_command_buffer.h
@@ -15,7 +15,7 @@ #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" #include "base/trace_event/memory_dump_provider.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/scheduling_priority.h" @@ -41,10 +41,10 @@ namespace ui { -// Implementation of cc::ContextProvider that provides a GL implementation over +// Implementation of viz::ContextProvider that provides a GL implementation over // command buffer to the GPU process. class ContextProviderCommandBuffer - : public cc::ContextProvider, + : public viz::ContextProvider, public base::trace_event::MemoryDumpProvider { public: ContextProviderCommandBuffer( @@ -65,13 +65,13 @@ // on the default framebuffer. uint32_t GetCopyTextureInternalFormat(); - // cc::ContextProvider implementation. + // viz::ContextProvider implementation. bool BindToCurrentThread() override; void DetachFromThread() override; gpu::gles2::GLES2Interface* ContextGL() override; gpu::ContextSupport* ContextSupport() override; class GrContext* GrContext() override; - cc::ContextCacheController* CacheController() override; + viz::ContextCacheController* CacheController() override; void InvalidateGrContext(uint32_t state) override; base::Lock* GetLock() override; gpu::Capabilities ContextCapabilities() override; @@ -132,7 +132,7 @@ std::unique_ptr<gpu::gles2::GLES2Implementation> gles2_impl_; std::unique_ptr<gpu::gles2::GLES2TraceImplementation> trace_impl_; std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_; - std::unique_ptr<cc::ContextCacheController> cache_controller_; + std::unique_ptr<viz::ContextCacheController> cache_controller_; LostContextCallback lost_context_callback_; };
diff --git a/services/ui/public/cpp/gpu/gpu.cc b/services/ui/public/cpp/gpu/gpu.cc index 191633e..936dc5d 100644 --- a/services/ui/public/cpp/gpu/gpu.cc +++ b/services/ui/public/cpp/gpu/gpu.cc
@@ -66,7 +66,7 @@ return base::WrapUnique(new Gpu(std::move(factory), std::move(task_runner))); } -scoped_refptr<cc::ContextProvider> Gpu::CreateContextProvider( +scoped_refptr<viz::ContextProvider> Gpu::CreateContextProvider( scoped_refptr<gpu::GpuChannelHost> gpu_channel) { int32_t stream_id = 0; gpu::SchedulingPriority stream_priority = gpu::SchedulingPriority::kNormal;
diff --git a/services/ui/public/cpp/gpu/gpu.h b/services/ui/public/cpp/gpu/gpu.h index 73459fc04..c64eeae 100644 --- a/services/ui/public/cpp/gpu/gpu.h +++ b/services/ui/public/cpp/gpu/gpu.h
@@ -13,7 +13,7 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/ipc/client/gpu_channel_host.h" #include "services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.h" #include "services/ui/public/interfaces/gpu.mojom.h" @@ -41,7 +41,7 @@ const std::string& service_name, scoped_refptr<base::SingleThreadTaskRunner> task_runner = nullptr); - scoped_refptr<cc::ContextProvider> CreateContextProvider( + scoped_refptr<viz::ContextProvider> CreateContextProvider( scoped_refptr<gpu::GpuChannelHost> gpu_channel); void CreateJpegDecodeAccelerator(
diff --git a/services/ui/ws/DEPS b/services/ui/ws/DEPS index d714e80d..9e9f18d 100644 --- a/services/ui/ws/DEPS +++ b/services/ui/ws/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/viz/common/gpu", "+components/viz/host", "+gpu/command_buffer/client", "+gpu/config",
diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc index 8932277..2e34c639 100644 --- a/services/ui/ws/event_dispatcher.cc +++ b/services/ui/ws/event_dispatcher.cc
@@ -80,7 +80,6 @@ void EventDispatcher::SetMousePointerDisplayLocation( const gfx::Point& display_location, int64_t display_id) { - DCHECK(pointer_targets_.empty()); SetMousePointerLocation(display_location, display_id); UpdateCursorProviderByLastKnownLocation(); // Write our initial location back to our shared screen coordinate. This
diff --git a/services/ui/ws/server_window_compositor_frame_sink_manager.h b/services/ui/ws/server_window_compositor_frame_sink_manager.h index d2d6887f5..2a200d29 100644 --- a/services/ui/ws/server_window_compositor_frame_sink_manager.h +++ b/services/ui/ws/server_window_compositor_frame_sink_manager.h
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "cc/ipc/compositor_frame.mojom.h" #include "cc/ipc/frame_sink_manager.mojom.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/surface_id.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/ui/public/interfaces/window_tree.mojom.h"
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn index a7aa3ca..f45832f 100644 --- a/storage/browser/BUILD.gn +++ b/storage/browser/BUILD.gn
@@ -32,6 +32,8 @@ "blob/blob_transport_host.h", "blob/blob_transport_request_builder.cc", "blob/blob_transport_request_builder.h", + "blob/blob_transport_strategy.cc", + "blob/blob_transport_strategy.h", "blob/blob_url_request_job.cc", "blob/blob_url_request_job.h", "blob/blob_url_request_job_factory.cc", @@ -243,6 +245,7 @@ "blob/blob_storage_context_unittest.cc", "blob/blob_storage_registry_unittest.cc", "blob/blob_transport_request_builder_unittest.cc", + "blob/blob_transport_strategy_unittest.cc", "database/database_quota_client_unittest.cc", "database/database_tracker_unittest.cc", "database/database_util_unittest.cc", @@ -309,6 +312,8 @@ "test/fileapi_test_file_set.h", "test/mock_blob_url_request_context.cc", "test/mock_blob_url_request_context.h", + "test/mock_bytes_provider.cc", + "test/mock_bytes_provider.h", "test/mock_file_change_observer.cc", "test/mock_file_change_observer.h", "test/mock_file_update_observer.cc", @@ -336,6 +341,7 @@ deps = [ ":browser", "//base/test:test_support", + "//mojo/common", "//net:test_support", "//testing/gtest", "//third_party/leveldatabase",
diff --git a/storage/browser/blob/blob_data_builder.cc b/storage/browser/blob/blob_data_builder.cc index 204a4e8..fc2e6eb 100644 --- a/storage/browser/blob/blob_data_builder.cc +++ b/storage/browser/blob/blob_data_builder.cc
@@ -111,8 +111,19 @@ const char* data, size_t offset, size_t length) { - DCHECK_LT(index, items_.size()); DCHECK(data); + + char* target = GetFutureDataPointerToPopulate(index, offset, length); + if (!target) + return false; + std::memcpy(target, data, length); + return true; +} + +char* BlobDataBuilder::GetFutureDataPointerToPopulate(size_t index, + size_t offset, + size_t length) { + DCHECK_LT(index, items_.size()); DataElement* element = items_[index]->data_element_ptr(); // We lazily allocate our data buffer by waiting until the first @@ -128,16 +139,15 @@ } if (element->type() != DataElement::TYPE_BYTES) { DVLOG(1) << "Invalid item type."; - return false; + return nullptr; } base::CheckedNumeric<size_t> checked_end = offset; checked_end += length; if (!checked_end.IsValid() || checked_end.ValueOrDie() > element->length()) { DVLOG(1) << "Invalid offset or length."; - return false; + return nullptr; } - std::memcpy(element->mutable_bytes() + offset, data, length); - return true; + return element->mutable_bytes() + offset; } size_t BlobDataBuilder::AppendFutureFile(uint64_t offset,
diff --git a/storage/browser/blob/blob_data_builder.h b/storage/browser/blob/blob_data_builder.h index 088ceb755..56aebb2 100644 --- a/storage/browser/blob/blob_data_builder.h +++ b/storage/browser/blob/blob_data_builder.h
@@ -81,6 +81,16 @@ size_t offset, size_t length); + // Same as PopulateFutureData, but rather than passing in the data to be + // copied, this method returns a pointer where the caller can copy |length| + // bytes of data to. + // Returns nullptr if: + // * The item was not created by using AppendFutureData, or + // * The offset and length are not valid. + char* GetFutureDataPointerToPopulate(size_t index, + size_t offset, + size_t length); + // Adds an item that is flagged for future data population. Use // 'PopulateFutureFile' to set the file path and expected modification time // of this file. Returns the index of the item (to be used in
diff --git a/storage/browser/blob/blob_registry_impl.cc b/storage/browser/blob/blob_registry_impl.cc index fb8b8bd..67715d3 100644 --- a/storage/browser/blob/blob_registry_impl.cc +++ b/storage/browser/blob/blob_registry_impl.cc
@@ -9,9 +9,44 @@ #include "storage/browser/blob/blob_data_builder.h" #include "storage/browser/blob/blob_impl.h" #include "storage/browser/blob/blob_storage_context.h" +#include "storage/browser/blob/blob_transport_strategy.h" namespace storage { +namespace { + +using MemoryStrategy = BlobMemoryController::Strategy; + +bool CalculateBlobMemorySize(const std::vector<mojom::DataElementPtr>& elements, + size_t* shortcut_bytes, + uint64_t* total_bytes) { + DCHECK(shortcut_bytes); + DCHECK(total_bytes); + + base::CheckedNumeric<uint64_t> total_size_checked = 0; + base::CheckedNumeric<size_t> shortcut_size_checked = 0; + for (const auto& e : elements) { + if (e->is_bytes()) { + const auto& bytes = e->get_bytes(); + total_size_checked += bytes->length; + if (bytes->embedded_data) { + if (bytes->embedded_data->size() != bytes->length) + return false; + shortcut_size_checked += bytes->length; + } + } else { + continue; + } + if (!total_size_checked.IsValid() || !shortcut_size_checked.IsValid()) + return false; + } + *shortcut_bytes = shortcut_size_checked.ValueOrDie(); + *total_bytes = total_size_checked.ValueOrDie(); + return true; +} + +} // namespace + class BlobRegistryImpl::BlobUnderConstruction { public: BlobUnderConstruction(BlobRegistryImpl* blob_registry, @@ -33,7 +68,7 @@ // referenced by this new blob. This (and any further methods) could end up // deleting |this| by removing it from the blobs_under_construction_ // collection in the blob service. - void StartFetchingBlobUUIDs(); + void StartTransportation(); ~BlobUnderConstruction() {} @@ -48,9 +83,18 @@ // Also deletes |this| by removing it from the blobs_under_construction_ list. void MarkAsBroken(BlobStatus reason, const std::string& bad_message_reason = "") { - context()->CancelBuildingBlob(uuid(), reason); + DCHECK(BlobStatusIsError(reason)); + DCHECK_EQ(bad_message_reason.empty(), !BlobStatusIsBadIPC(reason)); + // The blob might no longer have any references, in which case it may no + // longer exist. If that happens just skip calling cancel. + if (context()->registry().HasEntry(uuid())) + context()->CancelBuildingBlob(uuid(), reason); if (!bad_message_reason.empty()) std::move(bad_message_callback_).Run(bad_message_reason); + MarkAsFinishedAndDeleteSelf(); + } + + void MarkAsFinishedAndDeleteSelf() { blob_registry_->blobs_under_construction_.erase(uuid()); } @@ -75,6 +119,16 @@ // transporting. void ResolvedAllBlobDependencies(); + // Called when memory has been reserved for this blob and transport can begin. + // Could also be called if something caused the blob to become invalid before + // transportation began, in which case we just give up. + void OnReadyForTransport( + BlobStatus status, + std::vector<BlobMemoryController::FileCreationInfo> file_infos); + + // Called when all data has been transported, or transport has failed. + void TransportComplete(BlobStatus result); + #if DCHECK_IS_ON() // Returns true if the DAG made up by this blob and any other blobs that // are currently being built by BlobRegistryImpl contains any cycles. @@ -99,6 +153,9 @@ // called. mojo::ReportBadMessageCallback bad_message_callback_; + // Transport strategy to use when transporting data. + std::unique_ptr<BlobTransportStrategy> transport_strategy_; + // List of UUIDs for referenced blobs. Same size as |elements_|. All entries // for non-blob elements will remain empty strings. std::vector<std::string> referenced_blob_uuids_; @@ -113,17 +170,11 @@ DISALLOW_COPY_AND_ASSIGN(BlobUnderConstruction); }; -void BlobRegistryImpl::BlobUnderConstruction::StartFetchingBlobUUIDs() { +void BlobRegistryImpl::BlobUnderConstruction::StartTransportation() { size_t blob_count = 0; for (size_t i = 0; i < elements_.size(); ++i) { const auto& element = elements_[i]; if (element->is_blob()) { - if (element->get_blob()->blob.encountered_error()) { - // Will delete |this|. - MarkAsBroken(BlobStatus::ERR_REFERENCED_BLOB_BROKEN); - return; - } - // If connection to blob is broken, something bad happened, so mark this // new blob as broken, which will delete |this| and keep it from doing // unneeded extra work. @@ -134,6 +185,10 @@ element->get_blob()->blob->GetInternalUUID( base::BindOnce(&BlobUnderConstruction::ReceivedBlobUUID, weak_ptr_factory_.GetWeakPtr(), blob_count++)); + } else if (element->is_bytes()) { + element->get_bytes()->data.set_connection_error_handler(base::BindOnce( + &BlobUnderConstruction::MarkAsBroken, weak_ptr_factory_.GetWeakPtr(), + BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, "")); } } referenced_blob_uuids_.resize(blob_count); @@ -142,6 +197,32 @@ // Without it a blob could forever remaing pending if a renderer sends us // a BlobPtr connected to a (malicious) non-responding implementation. + // Do some basic validation of bytes to transport, and determine memory + // transport strategy to use later. + uint64_t transport_memory_size = 0; + size_t shortcut_size = 0; + if (!CalculateBlobMemorySize(elements_, &shortcut_size, + &transport_memory_size)) { + MarkAsBroken(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, + "Invalid byte element sizes in BlobRegistry::Register"); + return; + } + + const BlobMemoryController& memory_controller = + context()->memory_controller(); + MemoryStrategy memory_strategy = + memory_controller.DetermineStrategy(shortcut_size, transport_memory_size); + if (memory_strategy == MemoryStrategy::TOO_LARGE) { + MarkAsBroken(BlobStatus::ERR_OUT_OF_MEMORY); + return; + } + + transport_strategy_ = BlobTransportStrategy::Create( + memory_strategy, &builder_, + base::BindOnce(&BlobUnderConstruction::TransportComplete, + weak_ptr_factory_.GetWeakPtr()), + memory_controller.limits()); + // If there were no unresolved blobs, immediately proceed to the next step. // Currently this will only happen if there are no blobs referenced // whatsoever, but hopefully in the future blob UUIDs will be cached in the @@ -212,10 +293,11 @@ DCHECK_EQ(resolved_blob_uuid_count_, referenced_blob_uuids_.size()); DCHECK_EQ(ready_dependent_blob_count_, referenced_blob_uuids_.size()); - // TODO(mek): Fill BlobDataBuilder with elements_ other than blobs. auto blob_uuid_it = referenced_blob_uuids_.begin(); for (const auto& element : elements_) { - if (element->is_file()) { + if (element->is_bytes()) { + transport_strategy_->AddBytesElement(element->get_bytes().get()); + } else if (element->is_file()) { const auto& f = element->get_file(); builder_.AppendFile(f->path, f->offset, f->length, f->expected_modification_time.value_or(base::Time())); @@ -231,14 +313,49 @@ element->get_blob()->length); } } + // OnReadyForTransport can be called synchronously, which can call + // MarkAsFinishedAndDeleteSelf synchronously, so don't access any members + // after this call. std::unique_ptr<BlobDataHandle> new_handle = context()->BuildPreregisteredBlob( - builder_, BlobStorageContext::TransportAllowedCallback()); + builder_, base::Bind(&BlobUnderConstruction::OnReadyForTransport, + weak_ptr_factory_.GetWeakPtr())); // TODO(mek): Update BlobImpl with new BlobDataHandle. Although handles // only differ in their size() attribute, which is currently not used by // BlobImpl. - DCHECK(!BlobStatusIsPending(new_handle->GetBlobStatus())); +} + +void BlobRegistryImpl::BlobUnderConstruction::OnReadyForTransport( + BlobStatus status, + std::vector<BlobMemoryController::FileCreationInfo> file_infos) { + if (!BlobStatusIsPending(status)) { + // Done or error. + MarkAsFinishedAndDeleteSelf(); + return; + } + transport_strategy_->BeginTransport(std::move(file_infos)); +} + +void BlobRegistryImpl::BlobUnderConstruction::TransportComplete( + BlobStatus result) { + // The blob might no longer have any references, in which case it may no + // longer exist. If that happens just skip calling Complete. + // TODO(mek): Stop building sooner if a blob is no longer referenced. + if (context()->registry().HasEntry(uuid())) { + if (result == BlobStatus::DONE) + context()->NotifyTransportComplete(uuid()); + else + context()->CancelBuildingBlob(uuid(), result); + } + if (BlobStatusIsBadIPC(result)) { + // BlobTransportStrategy might have already reported a BadMessage on the + // BytesProvider binding, but just to be safe, also report one on the + // BlobRegistry binding itself. + std::move(bad_message_callback_) + .Run("Received invalid data while transporting blob"); + } + MarkAsFinishedAndDeleteSelf(); } #if DCHECK_IS_ON() @@ -331,7 +448,7 @@ context_->AddFutureBlob(uuid, content_type, content_disposition); BlobImpl::Create(std::move(handle), std::move(blob)); - blobs_under_construction_[uuid]->StartFetchingBlobUUIDs(); + blobs_under_construction_[uuid]->StartTransportation(); std::move(callback).Run(); }
diff --git a/storage/browser/blob/blob_registry_impl_unittest.cc b/storage/browser/blob/blob_registry_impl_unittest.cc index 0f2a60b2..e31518bd 100644 --- a/storage/browser/blob/blob_registry_impl_unittest.cc +++ b/storage/browser/blob/blob_registry_impl_unittest.cc
@@ -4,13 +4,18 @@ #include "storage/browser/blob/blob_registry_impl.h" +#include <limits> #include "base/files/scoped_temp_dir.h" +#include "base/rand_util.h" +#include "base/task_scheduler/post_task.h" #include "base/test/scoped_task_environment.h" +#include "base/threading/thread_restrictions.h" #include "mojo/edk/embedder/embedder.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "storage/browser/blob/blob_data_builder.h" #include "storage/browser/blob/blob_data_handle.h" #include "storage/browser/blob/blob_storage_context.h" +#include "storage/browser/test/mock_bytes_provider.h" #include "storage/browser/test/mock_special_storage_policy.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,6 +23,15 @@ namespace { +const size_t kTestBlobStorageIPCThresholdBytes = 5; +const size_t kTestBlobStorageMaxSharedMemoryBytes = 20; +const size_t kTestBlobStorageMaxBytesDataItemSize = 13; + +const size_t kTestBlobStorageMaxBlobMemorySize = 400; +const uint64_t kTestBlobStorageMaxDiskSpace = 4000; +const uint64_t kTestBlobStorageMinFileSizeBytes = 10; +const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; + class MockBlob : public mojom::Blob { public: explicit MockBlob(const std::string& uuid) : uuid_(uuid) {} @@ -51,13 +65,20 @@ bool can_read_file_system_file_result = true; }; +void BindBytesProvider(std::unique_ptr<MockBytesProvider> impl, + mojom::BytesProviderRequest request) { + mojo::MakeStrongBinding(std::move(impl), std::move(request)); +} + } // namespace class BlobRegistryImplTest : public testing::Test { public: void SetUp() override { ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); - context_ = base::MakeUnique<BlobStorageContext>(); + context_ = base::MakeUnique<BlobStorageContext>( + data_dir_.GetPath(), + base::CreateTaskRunnerWithTraits({base::MayBlock()})); auto storage_policy = base::MakeRefCounted<content::MockSpecialStoragePolicy>(); file_system_context_ = base::MakeRefCounted<storage::FileSystemContext>( @@ -74,11 +95,28 @@ auto delegate = base::MakeUnique<MockDelegate>(); delegate_ptr_ = delegate.get(); registry_impl_->Bind(MakeRequest(®istry_), std::move(delegate)); + mojo::edk::SetDefaultProcessErrorCallback(base::Bind( &BlobRegistryImplTest::OnBadMessage, base::Unretained(this))); + + storage::BlobStorageLimits limits; + limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes; + limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes; + limits.max_bytes_data_item_size = kTestBlobStorageMaxBytesDataItemSize; + limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize; + limits.desired_max_disk_space = kTestBlobStorageMaxDiskSpace; + limits.effective_max_disk_space = kTestBlobStorageMaxDiskSpace; + limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes; + limits.max_file_size = kTestBlobStorageMaxFileSizeBytes; + context_->mutable_memory_controller()->set_limits_for_testing(limits); + + // Disallow IO on the main loop. + base::ThreadRestrictions::SetIOAllowed(false); } void TearDown() override { + base::ThreadRestrictions::SetIOAllowed(true); + mojo::edk::SetDefaultProcessErrorCallback( mojo::edk::ProcessErrorCallback()); } @@ -118,6 +156,35 @@ loop.Run(); } + mojom::BytesProviderPtr CreateBytesProvider(const std::string& bytes) { + if (!bytes_provider_runner_) { + bytes_provider_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::WithBaseSyncPrimitives()}); + } + mojom::BytesProviderPtr result; + auto provider = base::MakeUnique<MockBytesProvider>( + std::vector<uint8_t>(bytes.begin(), bytes.end()), &reply_request_count_, + &stream_request_count_, &file_request_count_); + bytes_provider_runner_->PostTask( + FROM_HERE, base::BindOnce(&BindBytesProvider, std::move(provider), + MakeRequest(&result))); + return result; + } + + void CreateBytesProvider(const std::string& bytes, + mojom::BytesProviderRequest request) { + if (!bytes_provider_runner_) { + bytes_provider_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::WithBaseSyncPrimitives()}); + } + auto provider = base::MakeUnique<MockBytesProvider>( + std::vector<uint8_t>(bytes.begin(), bytes.end()), &reply_request_count_, + &stream_request_count_, &file_request_count_); + bytes_provider_runner_->PostTask( + FROM_HERE, base::BindOnce(&BindBytesProvider, std::move(provider), + std::move(request))); + } + protected: base::ScopedTempDir data_dir_; base::test::ScopedTaskEnvironment scoped_task_environment_; @@ -126,6 +193,11 @@ std::unique_ptr<BlobRegistryImpl> registry_impl_; mojom::BlobRegistryPtr registry_; MockDelegate* delegate_ptr_; + scoped_refptr<base::SequencedTaskRunner> bytes_provider_runner_; + + size_t reply_request_count_ = 0; + size_t stream_request_count_ = 0; + size_t file_request_count_ = 0; std::vector<std::string> bad_messages_; }; @@ -389,10 +461,10 @@ WaitForBlobCompletion(handle3.get()); EXPECT_FALSE(handle2->IsBroken()); - EXPECT_EQ(BlobStatus::DONE, handle2->GetBlobStatus()); + ASSERT_EQ(BlobStatus::DONE, handle2->GetBlobStatus()); EXPECT_FALSE(handle3->IsBroken()); - EXPECT_EQ(BlobStatus::DONE, handle3->GetBlobStatus()); + ASSERT_EQ(BlobStatus::DONE, handle3->GetBlobStatus()); BlobDataBuilder expected_blob_data(kId2); expected_blob_data.AppendData("hello wo"); @@ -441,7 +513,7 @@ WaitForBlobCompletion(handle.get()); EXPECT_FALSE(handle->IsBroken()); - EXPECT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); + ASSERT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); BlobDataBuilder expected_blob_data(kId); expected_blob_data.AppendFile(path, 0, 16, base::Time()); @@ -510,7 +582,7 @@ WaitForBlobCompletion(handle.get()); EXPECT_FALSE(handle->IsBroken()); - EXPECT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); + ASSERT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); BlobDataBuilder expected_blob_data(kId); expected_blob_data.AppendFileSystemFile(url, 0, 16, base::Time()); @@ -518,4 +590,305 @@ EXPECT_EQ(expected_blob_data, *handle->CreateSnapshot()); } +TEST_F(BlobRegistryImplTest, Register_BytesInvalidEmbeddedData) { + const std::string kId = "id"; + + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + 10, std::vector<uint8_t>(5), CreateBytesProvider("")))); + + mojom::BlobPtr blob; + EXPECT_FALSE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + EXPECT_EQ(1u, bad_messages_.size()); + + registry_.FlushForTesting(); + EXPECT_TRUE(registry_.encountered_error()); + + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); + WaitForBlobCompletion(handle.get()); + + EXPECT_TRUE(handle->IsBroken()); + EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, + handle->GetBlobStatus()); + + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(0u, stream_request_count_); + EXPECT_EQ(0u, file_request_count_); +} + +TEST_F(BlobRegistryImplTest, Register_BytesInvalidDataSize) { + const std::string kId = "id"; + + // Two elements that together are more than uint64_t::max bytes. + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes( + mojom::DataElementBytes::New(8, base::nullopt, CreateBytesProvider("")))); + elements.push_back(mojom::DataElement::NewBytes( + mojom::DataElementBytes::New(std::numeric_limits<uint64_t>::max() - 4, + base::nullopt, CreateBytesProvider("")))); + + mojom::BlobPtr blob; + EXPECT_FALSE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + EXPECT_EQ(1u, bad_messages_.size()); + + registry_.FlushForTesting(); + EXPECT_TRUE(registry_.encountered_error()); + + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); + WaitForBlobCompletion(handle.get()); + + EXPECT_TRUE(handle->IsBroken()); + EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, + handle->GetBlobStatus()); + + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(0u, stream_request_count_); + EXPECT_EQ(0u, file_request_count_); +} + +TEST_F(BlobRegistryImplTest, Register_BytesOutOfMemory) { + const std::string kId = "id"; + + // Two elements that together don't fit in the test quota. + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + kTestBlobStorageMaxDiskSpace, base::nullopt, CreateBytesProvider("")))); + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + kTestBlobStorageMaxDiskSpace, base::nullopt, CreateBytesProvider("")))); + + mojom::BlobPtr blob; + EXPECT_TRUE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); + WaitForBlobCompletion(handle.get()); + + EXPECT_TRUE(handle->IsBroken()); + EXPECT_EQ(BlobStatus::ERR_OUT_OF_MEMORY, handle->GetBlobStatus()); + + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(0u, stream_request_count_); + EXPECT_EQ(0u, file_request_count_); +} + +TEST_F(BlobRegistryImplTest, Register_ValidEmbeddedBytes) { + const std::string kId = "id"; + const std::string kData = "hello world"; + + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + kData.size(), std::vector<uint8_t>(kData.begin(), kData.end()), + CreateBytesProvider(kData)))); + + mojom::BlobPtr blob; + EXPECT_TRUE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); + WaitForBlobCompletion(handle.get()); + + EXPECT_FALSE(handle->IsBroken()); + ASSERT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); + + BlobDataBuilder expected_blob_data(kId); + expected_blob_data.AppendData(kData); + + EXPECT_EQ(expected_blob_data, *handle->CreateSnapshot()); + + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(0u, stream_request_count_); + EXPECT_EQ(0u, file_request_count_); +} + +TEST_F(BlobRegistryImplTest, Register_ValidBytesAsReply) { + const std::string kId = "id"; + const std::string kData = "hello"; + + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + kData.size(), base::nullopt, CreateBytesProvider(kData)))); + + mojom::BlobPtr blob; + EXPECT_TRUE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); + WaitForBlobCompletion(handle.get()); + + EXPECT_FALSE(handle->IsBroken()); + ASSERT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); + + BlobDataBuilder expected_blob_data(kId); + expected_blob_data.AppendData(kData); + + EXPECT_EQ(expected_blob_data, *handle->CreateSnapshot()); + + EXPECT_EQ(1u, reply_request_count_); + EXPECT_EQ(0u, stream_request_count_); + EXPECT_EQ(0u, file_request_count_); +} + +TEST_F(BlobRegistryImplTest, Register_ValidBytesAsStream) { + const std::string kId = "id"; + const std::string kData = + base::RandBytesAsString(kTestBlobStorageMaxSharedMemoryBytes * 3 + 13); + + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + kData.size(), base::nullopt, CreateBytesProvider(kData)))); + + mojom::BlobPtr blob; + EXPECT_TRUE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); + WaitForBlobCompletion(handle.get()); + + EXPECT_FALSE(handle->IsBroken()); + ASSERT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); + + size_t offset = 0; + BlobDataBuilder expected_blob_data(kId); + while (offset < kData.size()) { + expected_blob_data.AppendData( + kData.substr(offset, kTestBlobStorageMaxBytesDataItemSize)); + offset += kTestBlobStorageMaxBytesDataItemSize; + } + + EXPECT_EQ(expected_blob_data, *handle->CreateSnapshot()); + + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(1u, stream_request_count_); + EXPECT_EQ(0u, file_request_count_); +} + +TEST_F(BlobRegistryImplTest, Register_ValidBytesAsFile) { + const std::string kId = "id"; + const std::string kData = + base::RandBytesAsString(kTestBlobStorageMaxBlobMemorySize + 42); + + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + kData.size(), base::nullopt, CreateBytesProvider(kData)))); + + mojom::BlobPtr blob; + EXPECT_TRUE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); + WaitForBlobCompletion(handle.get()); + + EXPECT_FALSE(handle->IsBroken()); + ASSERT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); + + BlobDataBuilder expected_blob_data(kId); + expected_blob_data.AppendData(kData); + + size_t expected_file_count = + 1 + kData.size() / kTestBlobStorageMaxFileSizeBytes; + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(0u, stream_request_count_); + EXPECT_EQ(expected_file_count, file_request_count_); + + auto snapshot = handle->CreateSnapshot(); + EXPECT_EQ(expected_file_count, snapshot->items().size()); + size_t remaining_size = kData.size(); + for (const auto& item : snapshot->items()) { + EXPECT_EQ(DataElement::TYPE_FILE, item->type()); + EXPECT_EQ(0u, item->offset()); + if (remaining_size > kTestBlobStorageMaxFileSizeBytes) + EXPECT_EQ(kTestBlobStorageMaxFileSizeBytes, item->length()); + else + EXPECT_EQ(remaining_size, item->length()); + remaining_size -= item->length(); + } + EXPECT_EQ(0u, remaining_size); +} + +TEST_F(BlobRegistryImplTest, Register_BytesProviderClosedPipe) { + const std::string kId = "id"; + + mojom::BytesProviderPtr bytes_provider; + MakeRequest(&bytes_provider); + + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + 32, base::nullopt, std::move(bytes_provider)))); + + mojom::BlobPtr blob; + EXPECT_TRUE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + EXPECT_TRUE(bad_messages_.empty()); + + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); + WaitForBlobCompletion(handle.get()); + + EXPECT_TRUE(handle->IsBroken()); + EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus()); +} + +TEST_F(BlobRegistryImplTest, + Register_DefereferencedWhileBuildingBeforeBreaking) { + const std::string kId = "id"; + + mojom::BytesProviderPtr bytes_provider; + mojom::BytesProviderRequest request = MakeRequest(&bytes_provider); + + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + 32, base::nullopt, std::move(bytes_provider)))); + + mojom::BlobPtr blob; + EXPECT_TRUE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + EXPECT_TRUE(bad_messages_.empty()); + + EXPECT_TRUE(context_->registry().HasEntry(kId)); + EXPECT_TRUE(context_->GetBlobDataFromUUID(kId)->IsBeingBuilt()); + + // Now drop all references to the blob. + blob.reset(); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(context_->registry().HasEntry(kId)); + + // Now cause construction to fail, if it would still be going on. + request = nullptr; + base::RunLoop().RunUntilIdle(); +} + +TEST_F(BlobRegistryImplTest, + Register_DefereferencedWhileBuildingBeforeTransporting) { + const std::string kId = "id"; + const std::string kData = "hello world"; + + mojom::BytesProviderPtr bytes_provider; + mojom::BytesProviderRequest request = MakeRequest(&bytes_provider); + + std::vector<mojom::DataElementPtr> elements; + elements.push_back(mojom::DataElement::NewBytes(mojom::DataElementBytes::New( + kData.size(), base::nullopt, std::move(bytes_provider)))); + + mojom::BlobPtr blob; + EXPECT_TRUE(registry_->Register(MakeRequest(&blob), kId, "", "", + std::move(elements))); + EXPECT_TRUE(bad_messages_.empty()); + + EXPECT_TRUE(context_->registry().HasEntry(kId)); + EXPECT_TRUE(context_->GetBlobDataFromUUID(kId)->IsBeingBuilt()); + + // Now drop all references to the blob. + blob.reset(); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(context_->registry().HasEntry(kId)); + + // Now cause construction to complete, if it would still be going on. + CreateBytesProvider(kData, std::move(request)); + scoped_task_environment_.RunUntilIdle(); + base::RunLoop().RunUntilIdle(); +} + } // namespace storage
diff --git a/storage/browser/blob/blob_storage_context.h b/storage/browser/blob/blob_storage_context.h index a923cdb5..52e09b2 100644 --- a/storage/browser/blob/blob_storage_context.h +++ b/storage/browser/blob/blob_storage_context.h
@@ -149,6 +149,7 @@ friend class BlobDataHandle; friend class BlobDataHandle::BlobDataHandleShared; friend class BlobFlattenerTest; + friend class BlobRegistryImplTest; friend class BlobSliceTest; friend class BlobStorageContextTest;
diff --git a/storage/browser/blob/blob_transport_strategy.cc b/storage/browser/blob/blob_transport_strategy.cc new file mode 100644 index 0000000..4d2502cd --- /dev/null +++ b/storage/browser/blob/blob_transport_strategy.cc
@@ -0,0 +1,386 @@ +// 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 "storage/browser/blob/blob_transport_strategy.h" + +#include "mojo/public/cpp/system/data_pipe.h" +#include "storage/browser/blob/blob_data_builder.h" +#include "storage/public/interfaces/blobs.mojom.h" + +namespace storage { + +namespace { + +using MemoryStrategy = BlobMemoryController::Strategy; + +// Transport strategy when no transport is needed. All Bytes elements should +// have their data embedded already. +class NoneNeededTransportStrategy : public BlobTransportStrategy { + public: + NoneNeededTransportStrategy(BlobDataBuilder* builder, + ResultCallback result_callback) + : BlobTransportStrategy(builder, std::move(result_callback)) {} + + void AddBytesElement(mojom::DataElementBytes* bytes) override { + DCHECK(bytes->embedded_data); + DCHECK_EQ(bytes->length, bytes->embedded_data->size()); + builder_->AppendData( + reinterpret_cast<const char*>(bytes->embedded_data->data()), + bytes->length); + } + + void BeginTransport( + std::vector<BlobMemoryController::FileCreationInfo>) override { + std::move(result_callback_).Run(BlobStatus::DONE); + } +}; + +// Transport strategy that requests all data as replies. +class ReplyTransportStrategy : public BlobTransportStrategy { + public: + ReplyTransportStrategy(BlobDataBuilder* builder, + ResultCallback result_callback) + : BlobTransportStrategy(builder, std::move(result_callback)) {} + + void AddBytesElement(mojom::DataElementBytes* bytes) override { + size_t builder_element_index = builder_->AppendFutureData(bytes->length); + // base::Unretained is safe because |this| is guaranteed (by the contract + // that code using BlobTransportStrategy should adhere to) to outlive the + // BytesProvider. + requests_.push_back(base::BindOnce( + &mojom::BytesProvider::RequestAsReply, + base::Unretained(bytes->data.get()), + base::BindOnce(&ReplyTransportStrategy::OnReply, base::Unretained(this), + builder_element_index, bytes->length))); + } + + void BeginTransport( + std::vector<BlobMemoryController::FileCreationInfo>) override { + if (requests_.empty()) { + std::move(result_callback_).Run(BlobStatus::DONE); + return; + } + for (auto& request : requests_) + std::move(request).Run(); + } + + private: + void OnReply(size_t builder_element_index, + size_t expected_size, + const std::vector<uint8_t>& data) { + if (data.size() != expected_size) { + mojo::ReportBadMessage( + "Invalid data size in reply to BytesProvider::RequestAsReply"); + std::move(result_callback_) + .Run(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); + return; + } + bool populate_result = builder_->PopulateFutureData( + builder_element_index, reinterpret_cast<const char*>(data.data()), 0, + data.size()); + DCHECK(populate_result); + + if (++num_resolved_requests_ == requests_.size()) + std::move(result_callback_).Run(BlobStatus::DONE); + } + + std::vector<base::OnceClosure> requests_; + size_t num_resolved_requests_ = 0; +}; + +// Transport strategy that requests all data as data pipes, one pipe at a time. +class DataPipeTransportStrategy : public BlobTransportStrategy { + public: + DataPipeTransportStrategy(BlobDataBuilder* builder, + ResultCallback result_callback, + const BlobStorageLimits& limits) + : BlobTransportStrategy(builder, std::move(result_callback)), + limits_(limits), + watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {} + + void AddBytesElement(mojom::DataElementBytes* bytes) override { + // Split up the data in |max_bytes_data_item_size| sized chunks. + for (uint64_t source_offset = 0; source_offset < bytes->length; + source_offset += limits_.max_bytes_data_item_size) { + size_t builder_element_index = + builder_->AppendFutureData(std::min<uint64_t>( + bytes->length - source_offset, limits_.max_bytes_data_item_size)); + if (source_offset == 0) { + requests_.push_back(base::BindOnce( + &DataPipeTransportStrategy::RequestDataPipe, base::Unretained(this), + bytes->data.get(), bytes->length, builder_element_index)); + } + } + } + + void BeginTransport( + std::vector<BlobMemoryController::FileCreationInfo>) override { + NextRequestOrDone(); + } + + private: + void NextRequestOrDone() { + if (requests_.empty()) { + std::move(result_callback_).Run(BlobStatus::DONE); + return; + } + auto request = std::move(requests_.front()); + requests_.pop_front(); + std::move(request).Run(); + } + + void RequestDataPipe(mojom::BytesProvider* provider, + size_t expected_source_size, + size_t first_builder_element_index) { + // TODO(mek): Determine if the overhead of creating a new SharedMemory + // segment for each BytesProvider is too much. If it is possible solutions + // would include somehow teaching DataPipe to reuse the SharedMemory from a + // previous DataPipe, or simply using a single BytesProvider for all bytes + // elements. http://crbug.com/741159 + DCHECK(!consumer_handle_.is_valid()); + mojo::ScopedDataPipeProducerHandle producer_handle; + MojoCreateDataPipeOptions options; + options.struct_size = sizeof(MojoCreateDataPipeOptions); + options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; + options.element_num_bytes = 1; + options.capacity_num_bytes = + std::min(expected_source_size, limits_.max_shared_memory_size); + MojoResult result = + CreateDataPipe(&options, &producer_handle, &consumer_handle_); + if (result != MOJO_RESULT_OK) { + DVLOG(1) << "Unable to create data pipe for blob transfer."; + std::move(result_callback_).Run(BlobStatus::ERR_OUT_OF_MEMORY); + return; + } + + current_source_offset_ = 0; + provider->RequestAsStream(std::move(producer_handle)); + watcher_.Watch(consumer_handle_.get(), MOJO_HANDLE_SIGNAL_READABLE, + base::Bind(&DataPipeTransportStrategy::OnDataPipeReadable, + base::Unretained(this), expected_source_size, + first_builder_element_index)); + } + + void OnDataPipeReadable(size_t expected_full_source_size, + size_t first_builder_element_index, + MojoResult result) { + // The index of the element data should currently be written to, relative to + // the first element of this stream (first_builder_element_index). + size_t relative_element_index = + current_source_offset_ / limits_.max_bytes_data_item_size; + // The offset into the current element where data should be written next. + size_t offset_in_builder_element = + current_source_offset_ - + relative_element_index * limits_.max_bytes_data_item_size; + + while (true) { + uint32_t num_bytes = 0; + const void* source_buffer; + MojoResult read_result = + mojo::BeginReadDataRaw(consumer_handle_.get(), &source_buffer, + &num_bytes, MOJO_READ_DATA_FLAG_NONE); + if (read_result == MOJO_RESULT_SHOULD_WAIT) + return; + if (read_result != MOJO_RESULT_OK) { + // Data pipe broke before we received all the data. + std::move(result_callback_).Run(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT); + return; + } + + if (current_source_offset_ + num_bytes > expected_full_source_size) { + // Received more bytes then expected. + std::move(result_callback_) + .Run(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); + return; + } + + // Only read as many bytes as can fit in current data element. Any + // remaining bytes will be read on the next iteration of this loop. + num_bytes = + std::min<uint32_t>(num_bytes, limits_.max_bytes_data_item_size - + offset_in_builder_element); + char* output_buffer = builder_->GetFutureDataPointerToPopulate( + first_builder_element_index + relative_element_index, + offset_in_builder_element, num_bytes); + DCHECK(output_buffer); + + std::memcpy(output_buffer, source_buffer, num_bytes); + read_result = mojo::EndReadDataRaw(consumer_handle_.get(), num_bytes); + DCHECK_EQ(read_result, MOJO_RESULT_OK); + + current_source_offset_ += num_bytes; + if (current_source_offset_ >= expected_full_source_size) { + // Done with this stream, on to the next. + // TODO(mek): Should this wait to see if more data than expected gets + // written, instead of immediately closing the pipe? + watcher_.Cancel(); + consumer_handle_.reset(); + NextRequestOrDone(); + return; + } + + offset_in_builder_element += num_bytes; + if (offset_in_builder_element >= limits_.max_bytes_data_item_size) { + offset_in_builder_element = 0; + relative_element_index++; + } + } + } + + const BlobStorageLimits& limits_; + std::deque<base::OnceClosure> requests_; + + mojo::ScopedDataPipeConsumerHandle consumer_handle_; + mojo::SimpleWatcher watcher_; + // How many bytes have been read and processed so far from the current data + // pipe. + size_t current_source_offset_ = 0; +}; + +// Transport strategy that requests all data through files. +class FileTransportStrategy : public BlobTransportStrategy { + public: + FileTransportStrategy(BlobDataBuilder* builder, + ResultCallback result_callback, + const BlobStorageLimits& limits) + : BlobTransportStrategy(builder, std::move(result_callback)), + limits_(limits) {} + + void AddBytesElement(mojom::DataElementBytes* bytes) override { + uint64_t source_offset = 0; + while (source_offset < bytes->length) { + if (current_file_size_ >= limits_.max_file_size || + file_requests_.empty()) { + current_file_size_ = 0; + current_file_index_++; + file_requests_.push_back(std::vector<Request>()); + } + + // Make sure no single file gets too big, but do use up all the available + // space in all but the last file. + uint64_t element_size = + std::min(bytes->length - source_offset, + limits_.max_file_size - current_file_size_); + size_t builder_element_index = builder_->AppendFutureFile( + current_file_size_, element_size, file_requests_.size() - 1); + + num_unresolved_requests_++; + file_requests_.back().push_back(Request{bytes->data.get(), source_offset, + element_size, + builder_element_index}); + + source_offset += element_size; + current_file_size_ += element_size; + } + } + + void BeginTransport( + std::vector<BlobMemoryController::FileCreationInfo> file_infos) override { + if (file_requests_.empty()) { + std::move(result_callback_).Run(BlobStatus::DONE); + return; + } + DCHECK_EQ(file_infos.size(), file_requests_.size()); + for (size_t file_index = 0; file_index < file_requests_.size(); + ++file_index) { + const auto& requests = file_requests_[file_index]; + uint64_t file_offset = 0; + for (size_t i = 0; i < requests.size(); ++i) { + const auto& request = requests[i]; + base::File file = i == requests.size() - 1 + ? std::move(file_infos[file_index].file) + : file_infos[file_index].file.Duplicate(); + // base::Unretained is safe because |this| is guaranteed (by the + // contract that code using BlobTransportStrategy should adhere to) to + // outlive the BytesProvider. + request.provider->RequestAsFile( + request.source_offset, request.source_size, std::move(file), + file_offset, + base::BindOnce(&FileTransportStrategy::OnReply, + base::Unretained(this), + request.builder_element_index, + file_infos[file_index].file_reference)); + file_offset += request.source_size; + } + } + } + + private: + void OnReply(size_t builder_element_index, + const scoped_refptr<ShareableFileReference>& file_reference, + base::Optional<base::Time> time_file_modified) { + if (!time_file_modified) { + // Writing to the file failed in the renderer. + std::move(result_callback_).Run(BlobStatus::ERR_FILE_WRITE_FAILED); + return; + } + + bool populate_result = builder_->PopulateFutureFile( + builder_element_index, file_reference, *time_file_modified); + DCHECK(populate_result); + + if (--num_unresolved_requests_ == 0) + std::move(result_callback_).Run(BlobStatus::DONE); + } + + const BlobStorageLimits& limits_; + + // State used to assign bytes elements to individual files. + // The index of the first file that still has available space. + size_t current_file_index_ = 0; + // How big the current file already is. + uint64_t current_file_size_ = 0; + + struct Request { + // The BytesProvider to request this particular bit of data from. + mojom::BytesProvider* provider; + // Offset into the BytesProvider of the data to request. + uint64_t source_offset; + // Size of the bytes to request. + uint64_t source_size; + // Index of the element in the BlobDataBuilder the data should be populated + // into. + size_t builder_element_index; + }; + // For each file, a list of requests involving that file. + std::vector<std::vector<Request>> file_requests_; + + size_t num_unresolved_requests_ = 0; +}; + +} // namespace + +// static +std::unique_ptr<BlobTransportStrategy> BlobTransportStrategy::Create( + MemoryStrategy strategy, + BlobDataBuilder* builder, + ResultCallback result_callback, + const BlobStorageLimits& limits) { + switch (strategy) { + case MemoryStrategy::NONE_NEEDED: + return base::MakeUnique<NoneNeededTransportStrategy>( + builder, std::move(result_callback)); + case MemoryStrategy::IPC: + return base::MakeUnique<ReplyTransportStrategy>( + builder, std::move(result_callback)); + case MemoryStrategy::SHARED_MEMORY: + return base::MakeUnique<DataPipeTransportStrategy>( + builder, std::move(result_callback), limits); + case MemoryStrategy::FILE: + return base::MakeUnique<FileTransportStrategy>( + builder, std::move(result_callback), limits); + case MemoryStrategy::TOO_LARGE: + NOTREACHED(); + } + NOTREACHED(); + return nullptr; +} + +BlobTransportStrategy::~BlobTransportStrategy() {} + +BlobTransportStrategy::BlobTransportStrategy(BlobDataBuilder* builder, + ResultCallback result_callback) + : builder_(builder), result_callback_(std::move(result_callback)) {} + +} // namespace storage
diff --git a/storage/browser/blob/blob_transport_strategy.h b/storage/browser/blob/blob_transport_strategy.h new file mode 100644 index 0000000..fdc35e6 --- /dev/null +++ b/storage/browser/blob/blob_transport_strategy.h
@@ -0,0 +1,57 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef STORAGE_BROWSER_BLOB_BLOB_TRANSPORT_STRATEGY_H_ +#define STORAGE_BROWSER_BLOB_BLOB_TRANSPORT_STRATEGY_H_ + +#include "base/callback.h" +#include "storage/browser/blob/blob_memory_controller.h" +#include "storage/browser/storage_browser_export.h" + +namespace storage { + +class BlobDataBuilder; + +namespace mojom { +class DataElementBytes; +} + +// This class is responsible for transporting bytes for an under-construction +// blob, using a specified transport strategy. This is used by BlobRegistryImpl +// for the actual transportation of bytes. +class STORAGE_EXPORT BlobTransportStrategy { + public: + using ResultCallback = base::OnceCallback<void(BlobStatus)>; + + // Creates a BlobTransportStrategy instance for the specified memory strategy. + // The BlobDataBuilder and BlobStorageLimits must outlive the returned + // BlobTransportStrategy. + static std::unique_ptr<BlobTransportStrategy> Create( + BlobMemoryController::Strategy strategy, + BlobDataBuilder* builder, + ResultCallback result_callback, + const BlobStorageLimits& limits); + virtual ~BlobTransportStrategy(); + + // Called once for each DataElementBytes in a blob. The |bytes| passed in must + // outlive the BlobTransportStrategy instance. + virtual void AddBytesElement(mojom::DataElementBytes* bytes) = 0; + + // Called when quota has been allocated and transportation should begin. + // Implementations will call the |result_callback_| when transportation has + // completed, or failed. + virtual void BeginTransport( + std::vector<BlobMemoryController::FileCreationInfo> file_infos) = 0; + + protected: + BlobTransportStrategy(BlobDataBuilder* builder, + ResultCallback result_callback); + + BlobDataBuilder* builder_; + ResultCallback result_callback_; +}; + +} // namespace storage + +#endif // STORAGE_BROWSER_BLOB_BLOB_TRANSPORT_STRATEGY_H_
diff --git a/storage/browser/blob/blob_transport_strategy_unittest.cc b/storage/browser/blob/blob_transport_strategy_unittest.cc new file mode 100644 index 0000000..d876403 --- /dev/null +++ b/storage/browser/blob/blob_transport_strategy_unittest.cc
@@ -0,0 +1,520 @@ +// 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 "storage/browser/blob/blob_transport_strategy.h" + +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/rand_util.h" +#include "base/run_loop.h" +#include "base/task_scheduler/post_task.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_restrictions.h" +#include "mojo/edk/embedder/embedder.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "storage/browser/blob/blob_data_builder.h" +#include "storage/browser/test/mock_bytes_provider.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace storage { + +namespace { + +using MemoryStrategy = BlobMemoryController::Strategy; +using FileInfoVector = std::vector<BlobMemoryController::FileCreationInfo>; + +const size_t kTestBlobStorageIPCThresholdBytes = 5; +const size_t kTestBlobStorageMaxSharedMemoryBytes = 20; +const size_t kTestBlobStorageMaxBytesDataItemSize = 13; + +const size_t kTestBlobStorageMaxBlobMemorySize = 400; +const uint64_t kTestBlobStorageMaxDiskSpace = 4000; +const uint64_t kTestBlobStorageMinFileSizeBytes = 10; +const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; + +const char kId[] = "blob-id"; + +void BindBytesProvider(std::unique_ptr<MockBytesProvider> impl, + mojom::BytesProviderRequest request) { + mojo::MakeStrongBinding(std::move(impl), std::move(request)); +} + +class BlobTransportStrategyTest : public testing::Test { + public: + void SetUp() override { + ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); + + bytes_provider_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::WithBaseSyncPrimitives()}); + mock_time_ = base::Time::Now(); + + limits_.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes; + limits_.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes; + limits_.max_bytes_data_item_size = kTestBlobStorageMaxBytesDataItemSize; + limits_.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize; + limits_.desired_max_disk_space = kTestBlobStorageMaxDiskSpace; + limits_.effective_max_disk_space = kTestBlobStorageMaxDiskSpace; + limits_.min_page_file_size = kTestBlobStorageMinFileSizeBytes; + limits_.max_file_size = kTestBlobStorageMaxFileSizeBytes; + + mojo::edk::SetDefaultProcessErrorCallback(base::Bind( + &BlobTransportStrategyTest::OnBadMessage, base::Unretained(this))); + + // Disallow IO on the main loop. + base::ThreadRestrictions::SetIOAllowed(false); + } + + void TearDown() override { + base::ThreadRestrictions::SetIOAllowed(true); + + mojo::edk::SetDefaultProcessErrorCallback( + mojo::edk::ProcessErrorCallback()); + } + + void OnBadMessage(const std::string& error) { + bad_messages_.push_back(error); + } + + mojom::BytesProviderPtr CreateBytesProvider(const std::string& bytes, + base::Optional<base::Time> time) { + mojom::BytesProviderPtr result; + auto provider = base::MakeUnique<MockBytesProvider>( + std::vector<uint8_t>(bytes.begin(), bytes.end()), &reply_request_count_, + &stream_request_count_, &file_request_count_, time); + bytes_provider_runner_->PostTask( + FROM_HERE, base::BindOnce(&BindBytesProvider, std::move(provider), + MakeRequest(&result))); + return result; + } + + protected: + base::ScopedTempDir data_dir_; + base::test::ScopedTaskEnvironment scoped_task_environment_; + scoped_refptr<base::SequencedTaskRunner> bytes_provider_runner_; + base::Time mock_time_; + storage::BlobStorageLimits limits_; + + std::vector<std::string> bad_messages_; + + size_t reply_request_count_ = 0; + size_t stream_request_count_ = 0; + size_t file_request_count_ = 0; +}; + +class BasicTests : public BlobTransportStrategyTest, + public testing::WithParamInterface<MemoryStrategy> {}; + +TEST_P(BasicTests, NoBytes) { + BlobDataBuilder builder(kId); + BlobDataBuilder expected(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + GetParam(), &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + strategy->BeginTransport(FileInfoVector()); + loop.Run(); + + EXPECT_EQ(BlobStatus::DONE, status); + EXPECT_EQ(expected, builder); + EXPECT_EQ(0u, + reply_request_count_ + stream_request_count_ + file_request_count_); + EXPECT_TRUE(bad_messages_.empty()); +} + +TEST_P(BasicTests, WithBytes) { + BlobDataBuilder builder(kId); + BlobDataBuilder expected(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + GetParam(), &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + std::string data = base::RandBytesAsString(7); + mojom::DataElementBytes bytes1(data.size(), + std::vector<uint8_t>(data.begin(), data.end()), + CreateBytesProvider(data, mock_time_)); + strategy->AddBytesElement(&bytes1); + expected.AppendData(data); + + data = base::RandBytesAsString(3); + mojom::DataElementBytes bytes2(data.size(), + std::vector<uint8_t>(data.begin(), data.end()), + CreateBytesProvider(data, mock_time_)); + strategy->AddBytesElement(&bytes2); + expected.AppendData(data); + + data = base::RandBytesAsString(10); + mojom::DataElementBytes bytes3(data.size(), base::nullopt, + CreateBytesProvider(data, mock_time_)); + if (GetParam() != MemoryStrategy::NONE_NEEDED) { + strategy->AddBytesElement(&bytes3); + expected.AppendData(data); + } + + strategy->BeginTransport(FileInfoVector()); + loop.Run(); + + EXPECT_EQ(BlobStatus::DONE, status); + EXPECT_EQ(expected, builder); + EXPECT_TRUE(bad_messages_.empty()); + + if (GetParam() == MemoryStrategy::NONE_NEEDED) { + EXPECT_EQ( + 0u, reply_request_count_ + stream_request_count_ + file_request_count_); + } else { + EXPECT_EQ( + 3u, reply_request_count_ + stream_request_count_ + file_request_count_); + switch (GetParam()) { + case MemoryStrategy::IPC: + EXPECT_EQ(3u, reply_request_count_); + break; + case MemoryStrategy::SHARED_MEMORY: + EXPECT_EQ(3u, stream_request_count_); + break; + default: + NOTREACHED(); + } + } +} + +INSTANTIATE_TEST_CASE_P(BlobTransportStrategyTest, + BasicTests, + testing::Values(MemoryStrategy::NONE_NEEDED, + MemoryStrategy::IPC, + MemoryStrategy::SHARED_MEMORY)); + +class BasicErrorTests : public BlobTransportStrategyTest, + public testing::WithParamInterface<MemoryStrategy> {}; + +TEST_P(BasicErrorTests, NotEnoughBytesInProvider) { + BlobDataBuilder builder(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + GetParam(), &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + std::string data = base::RandBytesAsString(7); + mojom::DataElementBytes bytes( + data.size(), base::nullopt, + CreateBytesProvider(data.substr(0, 4), mock_time_)); + strategy->AddBytesElement(&bytes); + + strategy->BeginTransport(FileInfoVector()); + loop.Run(); + + EXPECT_TRUE(BlobStatusIsError(status)); + EXPECT_EQ(GetParam() == MemoryStrategy::SHARED_MEMORY, bad_messages_.empty()); +} + +TEST_P(BasicErrorTests, TooManyBytesInProvider) { + BlobDataBuilder builder(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + GetParam(), &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + std::string data = base::RandBytesAsString(4); + mojom::DataElementBytes bytes( + data.size(), base::nullopt, + CreateBytesProvider(data + "foobar", mock_time_)); + strategy->AddBytesElement(&bytes); + + strategy->BeginTransport(FileInfoVector()); + loop.Run(); + + if (GetParam() == MemoryStrategy::SHARED_MEMORY) { + EXPECT_TRUE(status == BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS || + status == BlobStatus::DONE); + } else { + EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, status); + EXPECT_FALSE(bad_messages_.empty()); + } +} + +INSTANTIATE_TEST_CASE_P(BlobTransportStrategyTest, + BasicErrorTests, + testing::Values(MemoryStrategy::IPC, + MemoryStrategy::SHARED_MEMORY)); + +TEST_F(BlobTransportStrategyTest, DataStreamChunksData) { + BlobDataBuilder builder(kId); + BlobDataBuilder expected(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + MemoryStrategy::SHARED_MEMORY, &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + std::string data = + base::RandBytesAsString(kTestBlobStorageMaxSharedMemoryBytes * 3 + 13); + mojom::DataElementBytes bytes(data.size(), base::nullopt, + CreateBytesProvider(data, mock_time_)); + strategy->AddBytesElement(&bytes); + + size_t offset = 0; + while (offset < data.size()) { + expected.AppendData( + data.substr(offset, kTestBlobStorageMaxBytesDataItemSize)); + offset += kTestBlobStorageMaxBytesDataItemSize; + } + + strategy->BeginTransport(FileInfoVector()); + loop.Run(); + + EXPECT_EQ(BlobStatus::DONE, status); + EXPECT_EQ(expected, builder); + + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(1u, stream_request_count_); + EXPECT_EQ(0u, file_request_count_); +} + +TEST_F(BlobTransportStrategyTest, Files_NoBytes) { + BlobDataBuilder builder(kId); + BlobDataBuilder expected(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + MemoryStrategy::FILE, &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + strategy->BeginTransport(FileInfoVector()); + loop.Run(); + + EXPECT_EQ(BlobStatus::DONE, status); + EXPECT_EQ(expected, builder); + EXPECT_EQ(0u, + reply_request_count_ + stream_request_count_ + file_request_count_); + EXPECT_TRUE(bad_messages_.empty()); +} + +TEST_F(BlobTransportStrategyTest, Files_WriteFailed) { + BlobDataBuilder builder(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + MemoryStrategy::FILE, &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + std::string data = base::RandBytesAsString(kTestBlobStorageMaxFileSizeBytes); + mojom::DataElementBytes bytes(data.size(), base::nullopt, + CreateBytesProvider(data, base::nullopt)); + strategy->AddBytesElement(&bytes); + + FileInfoVector files(1); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::FilePath path; + ASSERT_TRUE(base::CreateTemporaryFileInDir(data_dir_.GetPath(), &path)); + files[0].file = + base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE); + files[0].file_deletion_runner = base::ThreadTaskRunnerHandle::Get(); + files[0].file_reference = ShareableFileReference::GetOrCreate( + path, ShareableFileReference::DELETE_ON_FINAL_RELEASE, + bytes_provider_runner_.get()); + } + + strategy->BeginTransport(std::move(files)); + loop.Run(); + + EXPECT_EQ(BlobStatus::ERR_FILE_WRITE_FAILED, status); +} + +TEST_F(BlobTransportStrategyTest, Files_ValidBytesOneElement) { + BlobDataBuilder builder(kId); + BlobDataBuilder expected(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + MemoryStrategy::FILE, &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + std::string data = + base::RandBytesAsString(kTestBlobStorageMaxBlobMemorySize + 42); + mojom::DataElementBytes bytes(data.size(), base::nullopt, + CreateBytesProvider(data, mock_time_)); + strategy->AddBytesElement(&bytes); + + size_t expected_file_count = + 1 + data.size() / kTestBlobStorageMaxFileSizeBytes; + FileInfoVector files(expected_file_count); + for (size_t i = 0; i < expected_file_count; ++i) { + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::FilePath path; + ASSERT_TRUE(base::CreateTemporaryFileInDir(data_dir_.GetPath(), &path)); + files[i].file = + base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE); + files[i].file_deletion_runner = base::ThreadTaskRunnerHandle::Get(); + files[i].file_reference = ShareableFileReference::GetOrCreate( + path, ShareableFileReference::DELETE_ON_FINAL_RELEASE, + bytes_provider_runner_.get()); + size_t offset = i * kTestBlobStorageMaxFileSizeBytes; + size_t length = std::min<uint64_t>(kTestBlobStorageMaxFileSizeBytes, + data.size() - offset); + expected.AppendFile(path, 0, length, mock_time_); + } + + strategy->BeginTransport(std::move(files)); + loop.Run(); + + EXPECT_EQ(BlobStatus::DONE, status); + EXPECT_EQ(expected, builder); + EXPECT_TRUE(bad_messages_.empty()); + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(0u, stream_request_count_); + EXPECT_EQ(expected_file_count, file_request_count_); +} + +TEST_F(BlobTransportStrategyTest, Files_ValidBytesMultipleElements) { + BlobDataBuilder builder(kId); + BlobDataBuilder expected(kId); + + base::RunLoop loop; + BlobStatus status = BlobStatus::PENDING_TRANSPORT; + auto strategy = BlobTransportStrategy::Create( + MemoryStrategy::FILE, &builder, + base::BindOnce( + [](BlobStatus* result_out, base::OnceClosure closure, + BlobStatus result) { + *result_out = result; + std::move(closure).Run(); + }, + &status, loop.QuitClosure()), + limits_); + + std::string data = + base::RandBytesAsString(kTestBlobStorageMaxBlobMemorySize / 3); + + mojom::DataElementBytes bytes1(data.size(), base::nullopt, + CreateBytesProvider(data, mock_time_)); + strategy->AddBytesElement(&bytes1); + mojom::DataElementBytes bytes2(data.size(), base::nullopt, + CreateBytesProvider(data, mock_time_)); + strategy->AddBytesElement(&bytes2); + mojom::DataElementBytes bytes3(data.size(), base::nullopt, + CreateBytesProvider(data, mock_time_)); + strategy->AddBytesElement(&bytes3); + mojom::DataElementBytes bytes4(data.size(), base::nullopt, + CreateBytesProvider(data, mock_time_)); + strategy->AddBytesElement(&bytes4); + + size_t expected_file_count = + 1 + 4 * data.size() / kTestBlobStorageMaxFileSizeBytes; + FileInfoVector files(expected_file_count); + for (size_t i = 0; i < expected_file_count; ++i) { + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::FilePath path; + ASSERT_TRUE(base::CreateTemporaryFileInDir(data_dir_.GetPath(), &path)); + files[i].file = + base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE); + files[i].path = path; + files[i].file_deletion_runner = base::ThreadTaskRunnerHandle::Get(); + files[i].file_reference = ShareableFileReference::GetOrCreate( + path, ShareableFileReference::DELETE_ON_FINAL_RELEASE, + bytes_provider_runner_.get()); + } + + size_t file_offset = 0; + size_t file_index = 0; + size_t expected_request_count = 0; + for (size_t i = 0; i < 4; ++i) { + size_t remaining_size = data.size(); + while (remaining_size > 0) { + size_t block_size = std::min<uint64_t>( + kTestBlobStorageMaxFileSizeBytes - file_offset, remaining_size); + expected.AppendFile(files[file_index].path, file_offset, block_size, + mock_time_); + expected_request_count++; + remaining_size -= block_size; + file_offset += block_size; + if (file_offset >= kTestBlobStorageMaxFileSizeBytes) { + file_offset = 0; + file_index++; + } + } + } + + strategy->BeginTransport(std::move(files)); + loop.Run(); + + EXPECT_EQ(BlobStatus::DONE, status); + EXPECT_EQ(expected, builder); + EXPECT_TRUE(bad_messages_.empty()); + EXPECT_EQ(0u, reply_request_count_); + EXPECT_EQ(0u, stream_request_count_); + EXPECT_EQ(expected_request_count, file_request_count_); +} + +} // namespace + +} // namespace storage
diff --git a/storage/browser/test/mock_bytes_provider.cc b/storage/browser/test/mock_bytes_provider.cc new file mode 100644 index 0000000..80de185 --- /dev/null +++ b/storage/browser/test/mock_bytes_provider.cc
@@ -0,0 +1,58 @@ +// 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 "storage/browser/test/mock_bytes_provider.h" + +#include "mojo/common/data_pipe_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace storage { + +MockBytesProvider::MockBytesProvider( + std::vector<uint8_t> data, + size_t* reply_request_count, + size_t* stream_request_count, + size_t* file_request_count, + base::Optional<base::Time> file_modification_time) + : data_(std::move(data)), + reply_request_count_(reply_request_count), + stream_request_count_(stream_request_count), + file_request_count_(file_request_count), + file_modification_time_(file_modification_time) {} + +MockBytesProvider::~MockBytesProvider() {} + +void MockBytesProvider::RequestAsReply(RequestAsReplyCallback callback) { + if (reply_request_count_) + ++*reply_request_count_; + std::move(callback).Run(data_); +} + +void MockBytesProvider::RequestAsStream( + mojo::ScopedDataPipeProducerHandle pipe) { + if (stream_request_count_) + ++*stream_request_count_; + mojo::common::BlockingCopyFromString( + std::string(reinterpret_cast<const char*>(data_.data()), data_.size()), + pipe); +} + +void MockBytesProvider::RequestAsFile(uint64_t source_offset, + uint64_t source_size, + base::File file, + uint64_t file_offset, + RequestAsFileCallback callback) { + if (file_request_count_) + ++*file_request_count_; + EXPECT_LE(source_offset + source_size, data_.size()); + EXPECT_EQ(source_size, + static_cast<uint64_t>(file.Write( + file_offset, + reinterpret_cast<const char*>(data_.data() + source_offset), + source_size))); + EXPECT_TRUE(file.Flush()); + std::move(callback).Run(file_modification_time_); +} + +} // namespace storage
diff --git a/storage/browser/test/mock_bytes_provider.h b/storage/browser/test/mock_bytes_provider.h new file mode 100644 index 0000000..ef16b63 --- /dev/null +++ b/storage/browser/test/mock_bytes_provider.h
@@ -0,0 +1,44 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef STORAGE_BROWSER_TEST_MOCK_BYTES_PROVIDER_H_ +#define STORAGE_BROWSER_TEST_MOCK_BYTES_PROVIDER_H_ + +#include "storage/public/interfaces/blobs.mojom.h" + +namespace storage { + +// Mock BytesProvider implementation. RequestAsStream blocks, so make sure to +// bind this implementation to a pipe on a separate sequence from where the +// bytes are consumed. +class MockBytesProvider : public mojom::BytesProvider { + public: + explicit MockBytesProvider( + std::vector<uint8_t> data, + size_t* reply_request_count = nullptr, + size_t* stream_request_count = nullptr, + size_t* file_request_count = nullptr, + base::Optional<base::Time> file_modification_time = base::Time()); + ~MockBytesProvider() override; + + // BytesProvider implementation: + void RequestAsReply(RequestAsReplyCallback callback) override; + void RequestAsStream(mojo::ScopedDataPipeProducerHandle pipe) override; + void RequestAsFile(uint64_t source_offset, + uint64_t source_size, + base::File file, + uint64_t file_offset, + RequestAsFileCallback callback) override; + + private: + std::vector<uint8_t> data_; + size_t* reply_request_count_; + size_t* stream_request_count_; + size_t* file_request_count_; + base::Optional<base::Time> file_modification_time_; +}; + +} // namespace storage + +#endif // STORAGE_BROWSER_TEST_MOCK_BYTES_PROVIDER_H_
diff --git a/storage/common/blob_storage/blob_storage_constants.cc b/storage/common/blob_storage/blob_storage_constants.cc index a877255f..9269115f 100644 --- a/storage/common/blob_storage/blob_storage_constants.cc +++ b/storage/common/blob_storage/blob_storage_constants.cc
@@ -17,6 +17,7 @@ bool BlobStorageLimits::IsValid() const { return max_ipc_memory_size < max_shared_memory_size && + max_ipc_memory_size < max_bytes_data_item_size && min_page_file_size < max_file_size && min_page_file_size < max_blob_in_memory_space && effective_max_disk_space <= desired_max_disk_space;
diff --git a/storage/common/blob_storage/blob_storage_constants.h b/storage/common/blob_storage/blob_storage_constants.h index 788a063..7450943 100644 --- a/storage/common/blob_storage/blob_storage_constants.h +++ b/storage/common/blob_storage/blob_storage_constants.h
@@ -52,6 +52,12 @@ // This is the maximum size of a shared memory handle. size_t max_shared_memory_size = kDefaultSharedMemorySize; + // This is the maximum size of a bytes BlobDataItem. Only used for mojo + // based blob transportation, as the old IPC/shared memory based + // implementation doesn't support different values for this and + // max_shared_memory_size. + size_t max_bytes_data_item_size = kDefaultSharedMemorySize; + // This is the maximum amount of memory we can use to store blobs. size_t max_blob_in_memory_space = kDefaultMaxBlobInMemorySpace; // The ratio applied to |max_blob_in_memory_space| to reduce memory usage
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 6070e109..6580512c 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -234,783 +234,6 @@ } ] }, - "CFI Linux": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "angle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "app_shell_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "blink_heap_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "blink_platform_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "cacheinvalidation_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "cast_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "cc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "chromedriver_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "components_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "dbus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gfx_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gin_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gl_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gn_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gpu_ipc_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "latency_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_public_bindings_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_public_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "net_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "storage_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ui_touch_selection_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "webkit_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "wm_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "wtf_unittests" - } - ] - }, - "CFI Linux Full": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "angle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "app_shell_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_heap_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_platform_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cacheinvalidation_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cast_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chromedriver_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "dbus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gfx_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gin_unittests" - }, - { - "args": [ - "--use-gpu-in-tests", - "--no-xvfb" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Ubuntu" - } - ] - }, - "test": "gl_unittests", - "use_xvfb": false - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gn_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_ipc_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "latency_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_public_bindings_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_public_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "net_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "storage_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_touch_selection_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "webkit_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wm_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wtf_unittests" - } - ] - }, "CFI Linux ToT": { "gtest_tests": [ { @@ -1388,368 +611,6 @@ } ] }, - "CFI ThinLTO Linux ToT": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "angle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "app_shell_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "blink_heap_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "blink_platform_unittests" - }, - { - "args": [ - "--gtest_filter=-SaveType/SavePageMultiFrameBrowserTest.ObjectElements/0" - ], - "swarming": { - "can_use_on_swarming_builders": false, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "cacheinvalidation_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "cc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "chromedriver_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "components_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "dbus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gfx_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gin_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gl_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gn_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gpu_ipc_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_public_bindings_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_public_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "net_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ui_touch_selection_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "wm_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "wtf_unittests" - } - ] - }, "Chromium Mac 10.10 MacViews": { "gtest_tests": [ { @@ -11239,374 +10100,6 @@ } ] }, - "LTO Linux": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "angle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "app_shell_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "blink_heap_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "blink_platform_unittests" - }, - { - "args": [ - "--gtest_filter=-SaveType/SavePageMultiFrameBrowserTest.ObjectElements/0" - ], - "swarming": { - "can_use_on_swarming_builders": false, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "cacheinvalidation_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "cc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "chromedriver_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "components_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "dbus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gfx_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gin_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gl_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gn_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gpu_ipc_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_public_bindings_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_public_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "mojo_system_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "net_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "ui_touch_selection_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "webkit_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "wm_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "wtf_unittests" - } - ] - }, "Linux ARM": { "gtest_tests": [ {
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index 4fcfca8..4da910c1 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -4411,7 +4411,8 @@ "-v", "--upload-results", "--output-format=chartjson", - "--browser=release_x64" + "--browser=release_x64", + "--output-format=json-test-results" ], "isolate_name": "telemetry_perf_tests", "name": "system_health.common_desktop", @@ -4441,6 +4442,7 @@ "--upload-results", "--output-format=chartjson", "--browser=reference", + "--output-format=json-test-results", "--output-trace-tag=_ref" ], "isolate_name": "telemetry_perf_tests", @@ -4470,7 +4472,8 @@ "-v", "--upload-results", "--output-format=chartjson", - "--browser=release_x64" + "--browser=release_x64", + "--output-format=json-test-results" ], "isolate_name": "telemetry_perf_tests", "name": "system_health.memory_desktop", @@ -4500,6 +4503,7 @@ "--upload-results", "--output-format=chartjson", "--browser=reference", + "--output-format=json-test-results", "--output-trace-tag=_ref" ], "isolate_name": "telemetry_perf_tests", @@ -9479,7 +9483,8 @@ "-v", "--upload-results", "--output-format=chartjson", - "--browser=release_x64" + "--browser=release_x64", + "--output-format=json-test-results" ], "isolate_name": "telemetry_perf_tests", "name": "system_health.common_desktop", @@ -9509,6 +9514,7 @@ "--upload-results", "--output-format=chartjson", "--browser=reference", + "--output-format=json-test-results", "--output-trace-tag=_ref" ], "isolate_name": "telemetry_perf_tests", @@ -9538,7 +9544,8 @@ "-v", "--upload-results", "--output-format=chartjson", - "--browser=release_x64" + "--browser=release_x64", + "--output-format=json-test-results" ], "isolate_name": "telemetry_perf_tests", "name": "system_health.memory_desktop", @@ -9568,6 +9575,7 @@ "--upload-results", "--output-format=chartjson", "--browser=reference", + "--output-format=json-test-results", "--output-trace-tag=_ref" ], "isolate_name": "telemetry_perf_tests",
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 2a157a0d..6bea4f56 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2780,7 +2780,7 @@ { "name": "AdIdentifiers", "params": { - "tag_attribute_csv": "div,id,iframe,id" + "tag_attribute_csv": "div,data-google-query-id,div,id,iframe,id" }, "enable_features": [ "ThreatDomDetailsTagAttributes"
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index b28717d..a72431f 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -7363,7 +7363,6 @@ crbug.com/591099 fast/encoding/bracket-in-script.html [ Failure ] crbug.com/591099 fast/encoding/charset-invalid.html [ Failure ] crbug.com/591099 fast/encoding/charset-koi8-u.html [ Failure ] -crbug.com/591099 fast/encoding/charset-replacement.html [ Failure ] crbug.com/591099 fast/encoding/charset-xuser-defined.html [ Crash Failure ] crbug.com/591099 fast/encoding/css-charset-default.xhtml [ Failure ] crbug.com/591099 fast/encoding/css-charset.html [ Failure ] @@ -13669,13 +13668,13 @@ crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot.js [ Crash Failure Timeout ] crbug.com/591099 inspector-protocol/emulation/device-emulation-small-dw.js [ Failure ] crbug.com/591099 inspector-protocol/emulation/device-emulation-small.js [ Failure ] -crbug.com/591099 inspector-protocol/heap-profiler/heap-objects-tracking.html [ Failure ] -crbug.com/591099 inspector-protocol/heap-profiler/heap-samples-in-snapshot.html [ Failure ] -crbug.com/591099 inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html [ Failure ] -crbug.com/591099 inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.html [ Failure ] -crbug.com/591099 inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.html [ Failure ] -crbug.com/591099 inspector-protocol/heap-profiler/sampling-heap-profiler.html [ Failure ] -crbug.com/591099 inspector-protocol/heap-profiler/take-heap-snapshot.html [ Failure ] +crbug.com/591099 inspector-protocol/heap-profiler/heap-objects-tracking.js [ Failure ] +crbug.com/591099 inspector-protocol/heap-profiler/heap-samples-in-snapshot.js [ Failure ] +crbug.com/591099 inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js [ Failure ] +crbug.com/591099 inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js [ Failure ] +crbug.com/591099 inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js [ Failure ] +crbug.com/591099 inspector-protocol/heap-profiler/sampling-heap-profiler.js [ Failure ] +crbug.com/591099 inspector-protocol/heap-profiler/take-heap-snapshot.js [ Failure ] crbug.com/591099 inspector-protocol/layers/paint-profiler.js [ Failure ] crbug.com/591099 inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.html [ Failure ] crbug.com/591099 inspector/agents-enable-disable.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService index a8cc4d4..54d1719a 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -1408,10 +1408,10 @@ Bug(none) inspector-protocol/css/css-get-background-colors.html [ Timeout ] Bug(none) inspector-protocol/css/cssom-modify-rule-and-get-rule-list.html [ Timeout ] Bug(none) inspector-protocol/dom/dom-request-document-with-child-nodes.js [ Failure ] -Bug(none) inspector-protocol/heap-profiler/heap-samples-in-snapshot.html [ Failure ] -Bug(none) inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html [ Failure ] -Bug(none) inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.html [ Failure ] -Bug(none) inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.html [ Failure ] +Bug(none) inspector-protocol/heap-profiler/heap-samples-in-snapshot.js [ Failure ] +Bug(none) inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js [ Failure ] +Bug(none) inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js [ Failure ] +Bug(none) inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js [ Failure ] Bug(none) inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.html [ Failure ] Bug(none) inspector-protocol/network/resource-type.js [ Timeout ] Bug(none) inspector-protocol/network/websocket-initiator.js [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/MSANExpectations b/third_party/WebKit/LayoutTests/MSANExpectations index e7a990da..cf7d6fef 100644 --- a/third_party/WebKit/LayoutTests/MSANExpectations +++ b/third_party/WebKit/LayoutTests/MSANExpectations
@@ -32,10 +32,10 @@ crbug.com/704360 [ Linux ] shapedetection/detection-ImageData.html [ Timeout Pass ] # Times out on MSAN -crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-samples-in-snapshot.html [ Timeout ] -crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html [ Timeout ] -crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.html [ Timeout ] -crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.html [ Timeout ] +crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-samples-in-snapshot.js [ Timeout ] +crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js [ Timeout ] +crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js [ Timeout ] +crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js [ Timeout ] crbug.com/671556 [ Linux ] virtual/mojo-loading/http/tests/security/xssAuditor/report-script-tag-replace-state.html [ Timeout Pass ] crbug.com/671556 [ Linux ] virtual/mojo-loading/http/tests/security/xssAuditor/report-script-tag.html [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 8ce7227..0f316d7 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1429,6 +1429,8 @@ crbug.com/736319 [ Linux Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-003.html [ Failure Pass ] crbug.com/736319 [ Linux Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-004.html [ Failure Pass ] crbug.com/736319 [ Linux Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-005.html [ Failure Pass ] +crbug.com/736319 [ Linux Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-006a.html [ Failure Pass ] +crbug.com/736319 [ Linux Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-007.html [ Failure Pass ] # These need a rebaseline due crbug.com/504745 on Windows when they are activated again. crbug.com/521124 crbug.com/410145 [ Win7 ] fast/css/font-weight-1.html [ Pass Failure ] @@ -2542,6 +2544,251 @@ # ====== Random order flaky tests end here ====== +# ====== Tests from enabling .any.js/.worker.js tests begin here ====== +crbug.com/709227 external/wpt/FileAPI/idlharness.worker.html [ Failure ] +crbug.com/709227 external/wpt/IndexedDB/interfaces.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/digest/digest.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/encrypt_decrypt/aes_cbc.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/encrypt_decrypt/aes_ctr.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/encrypt_decrypt/aes_gcm.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/encrypt_decrypt/rsa.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_AES-CBC.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_AES-CTR.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_AES-GCM.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_AES-KW.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_ECDH.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_ECDSA.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_HMAC.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_RSA-OAEP.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_RSA-PSS.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/failures_RSASSA-PKCS1-v1_5.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_AES-CBC.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_AES-CTR.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_AES-GCM.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_AES-KW.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_ECDH.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_ECDSA.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_HMAC.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_RSA-OAEP.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_RSA-PSS.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/generateKey/successes_RSASSA-PKCS1-v1_5.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/idlharness.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/import_export/ec_importKey.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/import_export/rsa_importKey.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/import_export/symmetric_importKey.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/sign_verify/ecdsa.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/sign_verify/hmac.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/sign_verify/rsa_pkcs.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/sign_verify/rsa_pss.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.worker.html [ Failure ] +crbug.com/709227 external/wpt/WebIDL/ecmascript-binding/es-exceptions/constructor-object.worker.html [ Failure ] +crbug.com/709227 external/wpt/background-fetch/interfaces.worker.html [ Failure ] +crbug.com/709227 external/wpt/console/console-count-label-conversion.any.html [ Failure ] +crbug.com/709227 external/wpt/console/console-count-label-conversion.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/console/console-time-label-conversion.any.html [ Failure ] +crbug.com/709227 external/wpt/console/console-time-label-conversion.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/console/console-timeline-timelineEnd-historical.any.html [ Failure ] +crbug.com/709227 external/wpt/console/console-timeline-timelineEnd-historical.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/css/geometry-1/DOMMatrix-css-string.worker.html [ Failure ] +crbug.com/709227 external/wpt/css/geometry-1/interfaces.worker.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/basic/request-upload.any.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/basic/request-upload.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/basic/scheme-about.any.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/basic/scheme-about.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/cors/cors-preflight-redirect.any.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/cors/cors-preflight-redirect.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/cors/cors-preflight-referrer.any.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/cors/cors-preflight-referrer.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/cors/cors-preflight-star.any.html [ Failure ] +crbug.com/709227 external/wpt/fetch/api/cors/cors-preflight-star.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/html/browsers/history/the-location-interface/per-global.window.html [ Failure ] +crbug.com/709227 external/wpt/html/dom/interfaces.worker.html [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_isindex.html?run_type=uri [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_isindex.html?run_type=write [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_isindex.html?run_type=write_single [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_menuitem-element.html?run_type=uri [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_menuitem-element.html?run_type=write [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_menuitem-element.html?run_type=write_single [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_template.html?run_type=uri [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_template.html?run_type=write [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_template.html?run_type=write_single [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests11.html?run_type=uri [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests11.html?run_type=write [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests11.html?run_type=write_single [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests19.html?run_type=uri [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests19.html?run_type=write [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests19.html?run_type=write_single [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests2.html?run_type=uri [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests2.html?run_type=write [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests2.html?run_type=write_single [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests25.html?run_type=uri [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests25.html?run_type=write [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_tests25.html?run_type=write_single [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_webkit02.html?run_type=uri [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_webkit02.html?run_type=write [ Failure ] +crbug.com/709227 external/wpt/html/syntax/parsing/html5lib_webkit02.html?run_type=write_single [ Failure ] +crbug.com/709227 external/wpt/html/webappapis/scripting/events/event-handler-processing-algorithm-error/synthetic-errorevent-click.worker.html [ Failure ] +crbug.com/709227 external/wpt/html/webappapis/scripting/events/event-handler-processing-algorithm-error/workerglobalscope-synthetic-errorevent.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.gradient.radial.outside3.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/path-objects/2d.path.stroke.prune.arc.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/path-objects/2d.path.stroke.prune.closed.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/path-objects/2d.path.stroke.prune.curve.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/path-objects/2d.path.stroke.prune.line.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/path-objects/2d.path.stroke.prune.rect.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/pixel-manipulation/2d.imageData.create2.nonfinite.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/pixel-manipulation/2d.imageData.get.nonfinite.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/pixel-manipulation/2d.imageData.get.tiny.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/pixel-manipulation/2d.imageData.put.nonfinite.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/2d.getcontext.extraargs.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.idl.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.em.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.empty.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.junk.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.minus.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.onlyspace.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.percent.worker.html [ Failure ] +crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.trailingjunk.worker.html [ Failure ] +crbug.com/709227 external/wpt/performance-timeline/po-disconnect.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/performance-timeline/po-getentries.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/performance-timeline/po-mark-measure.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/performance-timeline/po-observe.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/storage/interfaces.worker.html [ Failure ] +crbug.com/709227 external/wpt/url/historical.any.html [ Failure ] +crbug.com/709227 external/wpt/url/historical.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/url/interfaces.any.html [ Failure ] +crbug.com/709227 external/wpt/url/interfaces.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/url/toascii.window.html [ Failure ] +crbug.com/709227 external/wpt/user-timing/invoke_with_timing_attributes.worker.html [ Failure ] +crbug.com/709227 external/wpt/websockets/closing-handshake/002.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/closing-handshake/003.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/closing-handshake/004.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/002.html [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/002.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/006.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/009.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/010.html [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/010.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/011.html [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/011.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/013.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/014.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/016.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/018.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/019.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/020.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/constructor/022.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/001.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/002.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/003.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/004.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/005.html [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/005.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/006.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/007.html [ Failure ] +crbug.com/709227 external/wpt/websockets/cookies/007.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/CloseEvent/clean-close.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-getting.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/close/close-connecting.html [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/close/close-connecting.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/close/close-nested.html [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/close/close-nested.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/events/016.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/readyState/003.html [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/readyState/003.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/readyState/006.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/readyState/007.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/readyState/008.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/007.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/008.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/009.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/011.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/012.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/keeping-connection-open/001.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/opening-handshake/002.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/opening-handshake/003.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/opening-handshake/005.html [ Failure ] +crbug.com/709227 external/wpt/websockets/unload-a-document/001.html [ Failure ] +crbug.com/709227 external/wpt/websockets/unload-a-document/001.html?wss [ Failure ] +crbug.com/709227 external/wpt/websockets/unload-a-document/002.html [ Failure ] +crbug.com/709227 external/wpt/websockets/unload-a-document/002.html?wss [ Failure ] +crbug.com/709227 external/wpt/workers/constructors/Worker/DedicatedWorkerGlobalScope-members.worker.html [ Failure ] +crbug.com/709227 external/wpt/workers/constructors/Worker/expected-self-properties.worker.html [ Failure ] +crbug.com/709227 external/wpt/workers/interfaces.worker.html [ Failure ] +crbug.com/709227 external/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker.html [ Failure ] +crbug.com/709227 external/wpt/workers/semantics/interface-objects/001.worker.html [ Failure ] +crbug.com/709227 external/wpt/workers/semantics/interface-objects/002.worker.html [ Failure ] +crbug.com/709227 http/tests/inspector-protocol/network/disable-interception-midway.html [ Failure ] +crbug.com/709227 external/wpt/WebIDL/ecmascript-binding/es-exceptions/DOMException-custom-bindings.any.html [ Failure ] +crbug.com/709227 external/wpt/WebIDL/ecmascript-binding/es-exceptions/DOMException-custom-bindings.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/dom/abort/event.any.html [ Failure ] +crbug.com/709227 external/wpt/dom/abort/event.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/dom/events/EventTarget-constructible.any.html [ Failure ] +crbug.com/709227 external/wpt/dom/events/EventTarget-constructible.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/performance-timeline/po-callback-mutate.any.html [ Failure ] +crbug.com/709227 external/wpt/performance-timeline/po-callback-mutate.any.worker.html [ Failure ] +crbug.com/709227 external/wpt/performance-timeline/po-disconnect.any.html [ Failure ] +crbug.com/709227 external/wpt/performance-timeline/po-entries-sort.any.worker.html [ Failure ] + +# Timeouts +crbug.com/709227 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.worker.html [ Timeout ] +crbug.com/709227 external/wpt/websockets/binary/001.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/binary/002.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/binary/004.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/binary/005.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/extended-payload-length.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-arraybuffer.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-blob.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-large.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-unicode.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/events/018.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/005.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/006.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/010.html?wss [ Timeout ] +crbug.com/709227 external/wpt/websockets/opening-handshake/003-sets-origin.worker.html [ Timeout ] +crbug.com/709227 external/wpt/websockets/opening-handshake/005.html?wss [ Timeout ] +crbug.com/709227 external/wpt/workers/nested_worker.worker.html [ Timeout ] + +# Crashes +crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.pattern.basic.nocontext.worker.html [ Crash ] + +# ====== Tests from enabling .any.js/.worker.js tests end here ======== + # ====== Begin of display: contents tests ====== crbug.com/657748 external/wpt/css/css-display-3/display-contents-before-after-002.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/fast/encoding/char-decoding.html b/third_party/WebKit/LayoutTests/fast/encoding/char-decoding.html index 9d7b4466..2ee9cd4 100644 --- a/third_party/WebKit/LayoutTests/fast/encoding/char-decoding.html +++ b/third_party/WebKit/LayoutTests/fast/encoding/char-decoding.html
@@ -144,7 +144,7 @@ testDecode('unicodeFFFE', '%D8%69%DE%D6', 'U+D869/U+DED6'); // Replacement encodings should decode non-empty streams as replacement (U+FFFD) then EOF -["csiso2022kr", "hz-gb-2312", "iso-2022-cn", "iso-2022-cn-ext", "iso-2022-kr"] +["replacement", "csiso2022kr", "hz-gb-2312", "iso-2022-cn", "iso-2022-cn-ext", "iso-2022-kr"] .forEach(function(encoding) { testDecode(encoding, "", ""); testDecode(encoding, "%41%42%43%61%62%63%31%32%33%A0", "U+FFFD");
diff --git a/third_party/WebKit/LayoutTests/fast/encoding/charset-replacement-expected.txt b/third_party/WebKit/LayoutTests/fast/encoding/charset-replacement-expected.txt deleted file mode 100644 index 4009bfa33..0000000 --- a/third_party/WebKit/LayoutTests/fast/encoding/charset-replacement-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -Should be your browser default encoding: windows-1252 - -If it's latin-1 (ISO-8859-1, windows-1252), this should be accented e: é - -If you got a render tree with U+FFFD instead, this failed
diff --git a/third_party/WebKit/LayoutTests/fast/encoding/charset-replacement.html b/third_party/WebKit/LayoutTests/fast/encoding/charset-replacement.html deleted file mode 100644 index 1e046fd..0000000 --- a/third_party/WebKit/LayoutTests/fast/encoding/charset-replacement.html +++ /dev/null
@@ -1,10 +0,0 @@ -<!DOCTYPE html> -<meta http-equiv="content-type" content="text/html; charset=replacement"> -<title>Replacement encoding - spec/implementation detail, not a real encoding</title> -<script> -if (window.testRunner) - testRunner.dumpAsText(); -document.write("<p>Should be your browser default encoding: " + document.characterSet + "</p>"); -document.write("<p>If it's latin-1 (ISO-8859-1, windows-1252), this should be accented e: é</p>"); -document.write("<p>If you got a render tree with U+FFFD instead, this failed</p>"); -</script>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking-expected.txt index 96e5fc7..4316c11c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking-expected.txt
@@ -1,5 +1,4 @@ Test that heap tracking actually reports data fragments. - SUCCESS: tracking started HeapProfiler.heapStatsUpdate has params: true HeapProfiler.heapStatsUpdate has statsUpdate: true
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking.html b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking.html deleted file mode 100644 index 0c6cd2fb..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking.html +++ /dev/null
@@ -1,86 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> - -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function junkGenerator() -{ - var junkArray = new Array(1000); - for (var i = 0; i < junkArray.length; ++i) - junkArray[i] = "42 " + i; - window.junkArray = junkArray; -} - -function setupIntervalAndRunTest() -{ - setInterval(junkGenerator, 0); - runTest(); -} - -function test() -{ - var lastSeenObjectIdEventCount = 0; - var heapStatsUpdateEventCount = 0; - function trackingStarted() - { - InspectorTest.log("SUCCESS: tracking started"); - } - - function trackingStopped() - { - InspectorTest.log("Number of heapStatsUpdate events >= numbrt of lastSeenObjectId events: " + (heapStatsUpdateEventCount >= lastSeenObjectIdEventCount)); - InspectorTest.log("At least 2 lastSeenObjectId arrived: " + (lastSeenObjectIdEventCount >= 2)); - InspectorTest.log("SUCCESS: tracking stopped"); - InspectorTest.completeTest(); - } - - var fragments = []; - InspectorTest.eventHandler["HeapProfiler.lastSeenObjectId"] = function(messageObject) - { - if (++lastSeenObjectIdEventCount <= 2) { - var params = messageObject["params"]; - InspectorTest.log("HeapProfiler.lastSeenObjectId has params: " + !!params); - InspectorTest.log("HeapProfiler.lastSeenObjectId has params.lastSeenObjectId: " + !!params.lastSeenObjectId); - InspectorTest.log("HeapProfiler.lastSeenObjectId has timestamp: " + !!params.timestamp); - InspectorTest.log("A heap stats fragment did arrive before HeapProfiler.lastSeenObjectId: " + !!fragments.length); - InspectorTest.log(""); - } - if (lastSeenObjectIdEventCount == 2) { - // Wait for two updates and then stop tracing. - InspectorTest.sendCommand("HeapProfiler.stopTrackingHeapObjects", {}, trackingStopped); - } - } - - InspectorTest.eventHandler["HeapProfiler.heapStatsUpdate"] = function(messageObject) - { - ++heapStatsUpdateEventCount - var params = messageObject["params"]; - if (heapStatsUpdateEventCount <= 2) - InspectorTest.log("HeapProfiler.heapStatsUpdate has params: " + !!params); - var statsUpdate = params.statsUpdate; - if (heapStatsUpdateEventCount <= 2) { - InspectorTest.log("HeapProfiler.heapStatsUpdate has statsUpdate: " + !!statsUpdate); - InspectorTest.log("statsUpdate length is not zero: " + !!statsUpdate.length); - InspectorTest.log("statsUpdate length is a multiple of three: " + !(statsUpdate.length % 3)); - InspectorTest.log("statsUpdate: first fragmentIndex in first update: " + statsUpdate[0]); - InspectorTest.log("statsUpdate: total count of objects is not zero: " + !!statsUpdate[1]); - InspectorTest.log("statsUpdate: total size of objects is not zero: " + !!statsUpdate[2]); - InspectorTest.log(""); - } - fragments.push(statsUpdate); - } - - InspectorTest.sendCommand("HeapProfiler.startTrackingHeapObjects", {}, trackingStarted); - //# sourceURL=heap-objects-tracking.html -} -</script> -</head> -<body onload="setupIntervalAndRunTest()"> -<p>Test that heap tracking actually reports data fragments.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking.js new file mode 100644 index 0000000..b312cc0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-objects-tracking.js
@@ -0,0 +1,58 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Test that heap tracking actually reports data fragments.'); + + await session.evaluate(` + var junkArray = new Array(1000); + function junkGenerator() { + for (var i = 0; i < junkArray.length; ++i) + junkArray[i] = '42 ' + i; + window.junkArray = junkArray; + } + setInterval(junkGenerator, 0) + `); + + var lastSeenObjectIdEventCount = 0; + var heapStatsUpdateEventCount = 0; + var fragments = []; + + dp.HeapProfiler.onLastSeenObjectId(async messageObject => { + ++lastSeenObjectIdEventCount; + if (lastSeenObjectIdEventCount <= 2) { + var params = messageObject['params']; + testRunner.log('HeapProfiler.lastSeenObjectId has params: ' + !!params); + testRunner.log('HeapProfiler.lastSeenObjectId has params.lastSeenObjectId: ' + !!params.lastSeenObjectId); + testRunner.log('HeapProfiler.lastSeenObjectId has timestamp: ' + !!params.timestamp); + testRunner.log('A heap stats fragment did arrive before HeapProfiler.lastSeenObjectId: ' + !!fragments.length); + testRunner.log(''); + } + if (lastSeenObjectIdEventCount === 2) { + // Wait for two updates and then stop tracing. + await dp.HeapProfiler.stopTrackingHeapObjects(); + testRunner.log('Number of heapStatsUpdate events >= numbrt of lastSeenObjectId events: ' + (heapStatsUpdateEventCount >= lastSeenObjectIdEventCount)); + testRunner.log('At least 2 lastSeenObjectId arrived: ' + (lastSeenObjectIdEventCount >= 2)); + testRunner.log('SUCCESS: tracking stopped'); + testRunner.completeTest(); + } + }); + + dp.HeapProfiler.onHeapStatsUpdate(messageObject => { + ++heapStatsUpdateEventCount; + var params = messageObject['params']; + if (heapStatsUpdateEventCount <= 2) + testRunner.log('HeapProfiler.heapStatsUpdate has params: ' + !!params); + var statsUpdate = params.statsUpdate; + if (heapStatsUpdateEventCount <= 2) { + testRunner.log('HeapProfiler.heapStatsUpdate has statsUpdate: ' + !!statsUpdate); + testRunner.log('statsUpdate length is not zero: ' + !!statsUpdate.length); + testRunner.log('statsUpdate length is a multiple of three: ' + !(statsUpdate.length % 3)); + testRunner.log('statsUpdate: first fragmentIndex in first update: ' + statsUpdate[0]); + testRunner.log('statsUpdate: total count of objects is not zero: ' + !!statsUpdate[1]); + testRunner.log('statsUpdate: total size of objects is not zero: ' + !!statsUpdate[2]); + testRunner.log(''); + } + fragments.push(statsUpdate); + }); + + await dp.HeapProfiler.startTrackingHeapObjects(); + testRunner.log('SUCCESS: tracking started'); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot-expected.txt index 85c68bc9..749f71c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot-expected.txt
@@ -1,5 +1,4 @@ Test that heap tracking actually reports data fragments. - Tracking started Took heap snapshot Parsed snapshot
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot.html b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot.html deleted file mode 100644 index a23b84e..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot.html +++ /dev/null
@@ -1,95 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> - -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function junkGenerator() -{ - var junkArray = new Array(1000); - for (var i = 0; i < junkArray.length; ++i) - junkArray[i] = "42 " + i; - window.junkArray = junkArray; -} - -function setupIntervalAndRunTest() -{ - setInterval(junkGenerator, 0); - runTest(); -} - -function test() -{ - InspectorTest.importScript("../../../../inspector-protocol/heap-profiler/resources/heap-snapshot-common.js"); - - function trackingStarted() - { - InspectorTest.log("Tracking started"); - } - - function arraysEqual(a, b) - { - var sa = a.join(", "); - var sb = b.join(", "); - if (sa === sb) - return true; - InspectorTest.log("FAIL:\na = [" + sa+ "]\nb = [" + sb + "]"); - return false; - } - - function trackingStopped(snapshot) - { - var samples = snapshot.getSamples(); - InspectorTest.log("Last assigned id arrays match: " + arraysEqual(lastAssignedIds, samples.lastAssignedIds)); - var sizesMatch = (sizes.length <= samples.sizes.length); - InspectorTest.log("Size arrays length is correct: " + sizesMatch); - if (!sizesMatch) { - // Print mismatch: - arraysEqual(sizes, samples.sizes); - } - var sizesNonGrowing = true; - for (var i = 0; i < samples.sizes.length; i++) { - if ((sizes[i] === undefined && samples.sizes[i] !== 0) || (sizes[i] < samples.sizes[i])) { - sizesNonGrowing = false; - InspectorTest.log("FAIL: total size of live objects from interval cannot increase."); - // Print mismatch: - arraysEqual(sizes, samples.sizes); - } - } - InspectorTest.log("Sizes non growing: " + sizesNonGrowing); - InspectorTest.completeTest(); - } - - var sizes = []; - var lastAssignedIds = []; - InspectorTest.eventHandler["HeapProfiler.lastSeenObjectId"] = function(messageObject) - { - lastAssignedIds.push(messageObject["params"]["lastSeenObjectId"]); - if (lastAssignedIds.length === 2) { - // Wait for two updates and then stop tracing. - InspectorTest.stopRecordingHeapTimeline(trackingStopped); - } - } - - InspectorTest.eventHandler["HeapProfiler.heapStatsUpdate"] = function(messageObject) - { - var samples = messageObject["params"]["statsUpdate"]; - for (var i = 0; i < samples.length; i += 3) { - index = samples[i]; - sizes[index] = samples[i+2]; - } - } - - InspectorTest.sendCommand("HeapProfiler.startTrackingHeapObjects", {}, trackingStarted); - //# sourceURL=heap-objects-tracking.html -} -</script> -</head> -<body onload="setupIntervalAndRunTest()"> -<p>Test that heap tracking actually reports data fragments.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot.js new file mode 100644 index 0000000..3439530 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-samples-in-snapshot.js
@@ -0,0 +1,65 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Test that heap tracking actually reports data fragments.'); + + await session.evaluate(` + var junkArray = new Array(1000); + function junkGenerator() { + for (var i = 0; i < junkArray.length; ++i) + junkArray[i] = '42 ' + i; + window.junkArray = junkArray; + } + setInterval(junkGenerator, 0) + `); + + var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js'); + var helper = await Helper(testRunner, session); + + function arraysEqual(a, b) { + var sa = a.join(', '); + var sb = b.join(', '); + if (sa === sb) + return true; + testRunner.log('FAIL:\na = [' + sa + ']\nb = [' + sb + ']'); + return false; + } + + var sizes = []; + var lastAssignedIds = []; + dp.HeapProfiler.onLastSeenObjectId(async messageObject => { + lastAssignedIds.push(messageObject['params']['lastSeenObjectId']); + if (lastAssignedIds.length === 2) { + // Wait for two updates and then stop tracing. + var snapshot = await helper.stopRecordingHeapTimeline(); + var samples = snapshot.getSamples(); + testRunner.log('Last assigned id arrays match: ' + arraysEqual(lastAssignedIds, samples.lastAssignedIds)); + var sizesMatch = (sizes.length <= samples.sizes.length); + testRunner.log('Size arrays length is correct: ' + sizesMatch); + if (!sizesMatch) { + // Print mismatch: + arraysEqual(sizes, samples.sizes); + } + var sizesNonGrowing = true; + for (var i = 0; i < samples.sizes.length; i++) { + if ((sizes[i] === undefined && samples.sizes[i] !== 0) || (sizes[i] < samples.sizes[i])) { + sizesNonGrowing = false; + testRunner.log('FAIL: total size of live objects from interval cannot increase.'); + // Print mismatch: + arraysEqual(sizes, samples.sizes); + } + } + testRunner.log('Sizes non growing: ' + sizesNonGrowing); + testRunner.completeTest(); + } + }); + + dp.HeapProfiler.onHeapStatsUpdate(messageObject => { + var samples = messageObject['params']['statsUpdate']; + for (var i = 0; i < samples.length; i += 3) { + var index = samples[i]; + sizes[index] = samples[i+2]; + } + }); + + await dp.HeapProfiler.startTrackingHeapObjects(); + testRunner.log('Tracking started'); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object-expected.txt index 7157aa1..bb87c1d1 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object-expected.txt
@@ -1,7 +1,5 @@ -CONSOLE MESSAGE: line 21: Created 2 MediaQueryList eleements Test that all ActiveDOMObjects with pending activities will get into one group in the heap snapshot. Bug 426809. - - Took heap snapshot +Took heap snapshot Parsed snapshot SUCCESS: found (Pending activities group) SUCCESS: found Pending activities / 3 entries
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html deleted file mode 100644 index 1b0c19c..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html +++ /dev/null
@@ -1,82 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function onChange(e) -{ - console.log("onChange " + e.matches); -} - -function createTwoActiveDOMObjectsAndRunTest() -{ - var m = window.matchMedia("(min-width: 1400px)"); - m.addListener(onChange); - m = window.matchMedia("(min-height: 1800px)"); - m.addListener(onChange); - console.log("Created 2 MediaQueryList eleements"); - runTest(); -} - -function test() -{ - InspectorTest.importScript("../../../../inspector-protocol/heap-profiler/resources/heap-snapshot-common.js"); - - function checkHeapSnapshot(snapshot) { - var node; - for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { - if (it.node.name() === "(Pending activities group)") { - node = it.node; - break; - } - } - if (node) - InspectorTest.log("SUCCESS: found " + node.name()); - else - return InspectorTest.fail("cannot find '(Pending activities group)'"); - - var pendingActivitiesRE = /^Pending activities/; - var pendingActivitiesFound = false; - for (var iter = node.edges(); iter.hasNext(); iter.next()) { - var node = iter.edge.node(); - if (pendingActivitiesRE.test(node.className())) { - if ("Pending activities / 3 entries" === node.name()) { - if (pendingActivitiesFound) - return InspectorTest.fail("second " + node.name()); - pendingActivitiesFound = true; - InspectorTest.log("SUCCESS: found " + node.name()); - checkPendingActivities(node); - } else - return InspectorTest.fail("unexpected 'Pending activities': " + node.name()); - } - } - InspectorTest.completeTest(); - } - - function checkPendingActivities(groupNode) - { - var mediaQuryListCount = 0; - for (var iter = groupNode.edges(); iter.hasNext(); iter.next()) { - var node = iter.edge.node(); - if (node.name() === "MediaQueryList") - ++mediaQuryListCount; - } - if (mediaQuryListCount === 2) - InspectorTest.log("SUCCESS: found " + mediaQuryListCount + " MediaQueryLists in " + groupNode.name()); - else - return InspectorTest.fail("unexpected MediaQueryLists count: " + mediaQuryListCount); - - } - - InspectorTest.takeHeapSnapshot(checkHeapSnapshot); -} -</script> -</head> -<body onload="createTwoActiveDOMObjectsAndRunTest()"> -<p>Test that all ActiveDOMObjects with pending activities will get into one group in the heap snapshot. <a href="https://crbug.com/426809">Bug 426809.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js new file mode 100644 index 0000000..7cab593 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js
@@ -0,0 +1,62 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Test that all ActiveDOMObjects with pending activities will get into one group in the heap snapshot. Bug 426809.`); + + await session.evaluate(` + function onChange(e) { + console.log('onChange ' + e.matches); + } + var m = window.matchMedia('(min-width: 1400px)'); + m.addListener(onChange); + m = window.matchMedia('(min-height: 1800px)'); + m.addListener(onChange); + console.log('Created 2 MediaQueryList elements'); + `); + + function checkPendingActivities(groupNode) { + var mediaQuryListCount = 0; + for (var iter = groupNode.edges(); iter.hasNext(); iter.next()) { + var node = iter.edge.node(); + if (node.name() === 'MediaQueryList') + ++mediaQuryListCount; + } + if (mediaQuryListCount === 2) + testRunner.log('SUCCESS: found ' + mediaQuryListCount + ' MediaQueryLists in ' + groupNode.name()); + else + return testRunner.fail('unexpected MediaQueryLists count: ' + mediaQuryListCount); + } + + var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js'); + var helper = await Helper(testRunner, session); + + var snapshot = await helper.takeHeapSnapshot(); + var node; + for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { + if (it.node.name() === '(Pending activities group)') { + node = it.node; + break; + } + } + if (node) + testRunner.log('SUCCESS: found ' + node.name()); + else + return testRunner.fail(`cannot find '(Pending activities group)'`); + + var pendingActivitiesRE = /^Pending activities/; + var pendingActivitiesFound = false; + for (var iter = node.edges(); iter.hasNext(); iter.next()) { + var node = iter.edge.node(); + if (pendingActivitiesRE.test(node.className())) { + if ('Pending activities / 3 entries' === node.name()) { + if (pendingActivitiesFound) + return testRunner.fail('second ' + node.name()); + pendingActivitiesFound = true; + testRunner.log('SUCCESS: found ' + node.name()); + checkPendingActivities(node); + } else { + return testRunner.fail(`unexpected 'Pending activities': ${node.name()}`); + } + } + } + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt index 82cc969..8042a9f 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt
@@ -1,6 +1,5 @@ Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. Bug 107819. - - Took heap snapshot +Took heap snapshot Parsed snapshot SUCCESS: found (Detached DOM trees) SUCCESS: found Detached DOM tree / 3 entries
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.html b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.html deleted file mode 100644 index 0bd34f6..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.html +++ /dev/null
@@ -1,82 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function createDetachedDomTreeAndRunTest() -{ - if (window.gc) - window.gc(); - window.retaining_wrapper = document.createElement("div"); - var t = document.createElement("div"); - retaining_wrapper.appendChild(t); - t.appendChild(document.createElement("div")); - - if (window.testRunner) - runTest(); -} - -function test() -{ - InspectorTest.importScript("../../../../inspector-protocol/heap-profiler/resources/heap-snapshot-common.js"); - - function checkHeapSnapshot(snapshot) { - var node; - for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { - if (it.node.name() === "(Detached DOM trees)") { - node = it.node; - break; - } - } - if (node) - InspectorTest.log("SUCCESS: found " + node.name()); - else - return InspectorTest.fail("cannot find detached DOM trees root"); - - var detachedDOMTreeRE = /^Detached DOM tree/; - var detachedDomTreeFound = false; - for (var iter = node.edges(); iter.hasNext(); iter.next()) { - var node = iter.edge.node(); - if (detachedDOMTreeRE.test(node.className())) { - if ("Detached DOM tree / 3 entries" === node.name()) { - if (detachedDomTreeFound) - return InspectorTest.fail("second " + node.name()); - detachedDomTreeFound = true; - InspectorTest.log("SUCCESS: found " + node.name()); - checkDetachedDOMTreeNodes(node); - } else - return InspectorTest.fail("unexpected detached DOM tree: " + node.name()); - } - } - InspectorTest.completeTest(); - } - - function checkDetachedDOMTreeNodes(treeNode) - { - var divCount = 0; - for (var iter = treeNode.edges(); iter.hasNext(); iter.next()) { - var node = iter.edge.node(); - if (node.name() === "HTMLDivElement") - ++divCount; - else - return InspectorTest.fail("unexpected DOM wrapper: " + node.name()); - } - if (divCount === 3) - InspectorTest.log("SUCCESS: found " + divCount + " DIVs in " + treeNode.name()); - else - return InspectorTest.fail("unexpected DIV count: " + divCount); - - } - - InspectorTest.takeHeapSnapshot(checkHeapSnapshot); -} -</script> -</head> -<body onload="createDetachedDomTreeAndRunTest()"> -<p>Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. <a href="https://bugs.webkit.org/show_bug.cgi?id=107819">Bug 107819.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js new file mode 100644 index 0000000..fa60d3d --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js
@@ -0,0 +1,61 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. Bug 107819.`); + + await session.evaluate(` + if (window.gc) + window.gc(); + window.retaining_wrapper = document.createElement('div'); + var t = document.createElement('div'); + retaining_wrapper.appendChild(t); + t.appendChild(document.createElement('div')); + `); + + function checkDetachedDOMTreeNodes(treeNode) { + var divCount = 0; + for (var iter = treeNode.edges(); iter.hasNext(); iter.next()) { + var node = iter.edge.node(); + if (node.name() === 'HTMLDivElement') + ++divCount; + else + return testRunner.fail('unexpected DOM wrapper: ' + node.name()); + } + if (divCount === 3) + testRunner.log('SUCCESS: found ' + divCount + ' DIVs in ' + treeNode.name()); + else + return testRunner.fail('unexpected DIV count: ' + divCount); + } + + var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js'); + var helper = await Helper(testRunner, session); + + var snapshot = await helper.takeHeapSnapshot(); + var node; + for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { + if (it.node.name() === '(Detached DOM trees)') { + node = it.node; + break; + } + } + if (node) + testRunner.log('SUCCESS: found ' + node.name()); + else + return testRunner.fail('cannot find detached DOM trees root'); + + var detachedDOMTreeRE = /^Detached DOM tree/; + var detachedDomTreeFound = false; + for (var iter = node.edges(); iter.hasNext(); iter.next()) { + var node = iter.edge.node(); + if (detachedDOMTreeRE.test(node.className())) { + if ('Detached DOM tree / 3 entries' === node.name()) { + if (detachedDomTreeFound) + return testRunner.fail('second ' + node.name()); + detachedDomTreeFound = true; + testRunner.log('SUCCESS: found ' + node.name()); + checkDetachedDOMTreeNodes(node); + } else + return testRunner.fail('unexpected detached DOM tree: ' + node.name()); + } + } + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener-expected.txt index 8dee329..4608a90 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener-expected.txt
@@ -1,7 +1,6 @@ Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. Bug 107819. - - Took heap snapshot +Took heap snapshot Parsed snapshot SUCCESS: found myEventListener -SUCCESS: found link from HTMLBodyElement to HTMLBodyElement +SUCCESS: found link from HTMLBodyElement to myEventListener
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.html b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.html deleted file mode 100644 index ff41be3..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.html +++ /dev/null
@@ -1,71 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function addEventListenerAndRunTest() -{ - function myEventListener(e) { - console.log("myEventListener"); - } - document.body.addEventListener("click", myEventListener, true); - - runTest(); -} - -function test() -{ - InspectorTest.importScript("../../../../inspector-protocol/heap-profiler/resources/heap-snapshot-common.js"); - - function checkHeapSnapshot(snapshot) - { - var node; - for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { - if (it.node.type() === "closure" && it.node.name() === "myEventListener") { - node = it.node; - break; - } - } - if (node) - InspectorTest.log("SUCCESS: found " + node.name()); - else - return fail("cannot find detached DOM trees root"); - - var nativeRetainers = 0; - for (var iter = node.retainers(); iter.hasNext(); iter.next()) { - var node = iter.retainer.node(); - var retainingEdge = iter.retainer; - if (retainingEdge.isInternal() && retainingEdge.name() === "native") { - if (++nativeRetainers === 1) { - var retainerName = retainingEdge.node().name(); - if (retainerName === "HTMLBodyElement") - InspectorTest.log("SUCCESS: found link from HTMLBodyElement to " + node.name()); - else - return fail("unexpected retainer of " + node.name() + ": " + retainerName); - } else - return fail("too many retainers of " + node.name()); - } else if (!retainingEdge.isWeak()) - return fail("unexpected retaining edge of " + node.name() + " type: " + retainingEdge.type() + ", name: " + retainingEdge.name()); - } - if (!nativeRetainers) - return fail("cannot find HTMLBodyElement among retainers of " + node.name()); - InspectorTest.completeTest(); - } - - function fail(message) { - InspectorTest.log("FAIL: " + message); - InspectorTest.completeTest(); - } - - InspectorTest.takeHeapSnapshot(checkHeapSnapshot); -} -</script> -</head> -<body onload="addEventListenerAndRunTest()"> -<p>Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. <a href="https://bugs.webkit.org/show_bug.cgi?id=107819">Bug 107819.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js new file mode 100644 index 0000000..286057b4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js
@@ -0,0 +1,49 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. Bug 107819.`); + + await session.evaluate(` + function addEventListenerAndRunTest() { + function myEventListener(e) { + console.log('myEventListener'); + } + document.body.addEventListener('click', myEventListener, true); + } + addEventListenerAndRunTest(); + `); + + var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js'); + var helper = await Helper(testRunner, session); + + var snapshot = await helper.takeHeapSnapshot(); + var node; + for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { + if (it.node.type() === 'closure' && it.node.name() === 'myEventListener') { + node = it.node; + break; + } + } + if (node) + testRunner.log('SUCCESS: found ' + node.name()); + else + return testRunner.fail('cannot find detached DOM trees root'); + + var nativeRetainers = 0; + for (var iter = node.retainers(); iter.hasNext(); iter.next()) { + var retainingEdge = iter.retainer; + if (retainingEdge.isInternal() && retainingEdge.name() === 'native') { + if (++nativeRetainers === 1) { + var retainerName = retainingEdge.node().name(); + if (retainerName === 'HTMLBodyElement') + testRunner.log('SUCCESS: found link from HTMLBodyElement to ' + node.name()); + else + return testRunner.fail('unexpected retainer of ' + node.name() + ': ' + retainerName); + } else + return testRunner.fail('too many retainers of ' + node.name()); + } else if (!retainingEdge.isWeak()) + return testRunner.fail('unexpected retaining edge of ' + node.name() + ' type: ' + retainingEdge.type() + ', name: ' + retainingEdge.name()); + } + if (!nativeRetainers) + return testRunner.fail('cannot find HTMLBodyElement among retainers of ' + node.name()); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js index f9363027..5927bf1e 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js
@@ -1,53 +1,40 @@ -// This script is supposed to be evaluated in dummy inspector front-end which is loaded from -// ../../../http/tests/inspector-protocol/resources/protocol-test.html and the relative paths -// below are relative to that location. +(async function(testRunner, session) { + self['Common'] = {}; + self['TextUtils'] = {}; + self['HeapSnapshotModel'] = {}; + self['HeapSnapshotWorker'] = {}; -if (!window.WebInspector) - window.WebInspector = {}; + // This script is supposed to be evaluated in inspector-protocol/heap-profiler tests + // and the relative paths below are relative to that location. + await testRunner.loadScript('../../../Source/devtools/front_end/platform/utilities.js'); + await testRunner.loadScript('../../../Source/devtools/front_end/common/UIString.js'); + await testRunner.loadScript('../../../Source/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js'); + await testRunner.loadScript('../../../Source/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js'); + await testRunner.loadScript('../../../Source/devtools/front_end/text_utils/TextUtils.js'); + await testRunner.loadScript('../../../Source/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js'); -self['Common'] = {}; -self['TextUtils'] = {}; -self['HeapSnapshotModel'] = {}; -self['HeapSnapshotWorker'] = {}; - -InspectorTest.importScript("../../../../../Source/devtools/front_end/platform/utilities.js"); -InspectorTest.importScript("../../../../../Source/devtools/front_end/common/UIString.js"); -InspectorTest.importScript("../../../../../Source/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js"); -InspectorTest.importScript("../../../../../Source/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js"); -InspectorTest.importScript("../../../../../Source/devtools/front_end/text_utils/TextUtils.js"); -InspectorTest.importScript("../../../../../Source/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js"); - -InspectorTest.fail = function(message) -{ - InspectorTest.log("FAIL: " + message); - InspectorTest.completeTest(); -} - -InspectorTest._takeHeapSnapshotInternal = function(command, callback) -{ + async function takeHeapSnapshotInternal(command) { var loader = new HeapSnapshotWorker.HeapSnapshotLoader(); - InspectorTest.eventHandler["HeapProfiler.addHeapSnapshotChunk"] = function(messageObject) - { - loader.write(messageObject["params"]["chunk"]); + function onChunk(messageObject) { + loader.write(messageObject['params']['chunk']); } + session.protocol.HeapProfiler.onAddHeapSnapshotChunk(onChunk); + await command(); + session.protocol.HeapProfiler.offAddHeapSnapshotChunk(onChunk); + testRunner.log('Took heap snapshot'); + loader.close(); + var snapshot = loader.buildSnapshot(false); + testRunner.log('Parsed snapshot'); + return snapshot; + } - function didTakeHeapSnapshot(messageObject) - { - InspectorTest.log("Took heap snapshot"); - loader.close(); - var snapshot = loader.buildSnapshot(false); - InspectorTest.log("Parsed snapshot"); - callback(snapshot); + return { + takeHeapSnapshot: function() { + return takeHeapSnapshotInternal(() => session.protocol.HeapProfiler.takeHeapSnapshot()); + }, + + stopRecordingHeapTimeline: function() { + return takeHeapSnapshotInternal(() => session.protocol.HeapProfiler.stopTrackingHeapObjects()); } - InspectorTest.sendCommand(command, {}, didTakeHeapSnapshot); -} - -InspectorTest.takeHeapSnapshot = function(callback) -{ - InspectorTest._takeHeapSnapshotInternal("HeapProfiler.takeHeapSnapshot", callback); -} - -InspectorTest.stopRecordingHeapTimeline = function(callback) -{ - InspectorTest._takeHeapSnapshotInternal("HeapProfiler.stopTrackingHeapObjects", callback); -} + }; +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler-expected.txt index e417d95..5efaaa1 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler-expected.txt
@@ -1,5 +1,4 @@ Test sampling heap profiler. - Sampling started Sampling stopped size=0 testMain:10:17
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler.html b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler.html deleted file mode 100644 index 4dea3a21..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler.html +++ /dev/null
@@ -1,79 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> - -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function testMain() -{ - makeDeepCallStack(10, junkGenerator); -} - -function makeDeepCallStack(depth, action) -{ - if (depth) - makeDeepCallStack(depth - 1, action); - else - action(); -} - -function junkGenerator() -{ - var junkArray = new Array(3000); - window.junkArray = junkArray; - for (var i = 1; i < junkArray.length; ++i) - junkArray[i] = new Array(i); -} - -function test() -{ - InspectorTest.sendCommand("HeapProfiler.startSampling", {}, samplingStarted); - - function samplingStarted() - { - InspectorTest.log("Sampling started"); - InspectorTest.sendCommand("Runtime.evaluate", { expression: "testMain()" }, stopSampling); - } - - function stopSampling() - { - InspectorTest.sendCommand("HeapProfiler.stopSampling", {}, samplingStopped); - } - - function samplingStopped(message) - { - InspectorTest.log("Sampling stopped"); - var profile = message.result.profile; - var head = profile.head; - logNode(findNode(head, "testMain", 1)); - logNode(findNode(head, "makeDeepCallStack", 11)); - logNode(findNode(head, "junkGenerator", 12)); - - InspectorTest.completeTest(); - } - - function findNode(root, name, depth) - { - if (depth < 1 && root.callFrame.functionName === name) - return root; - return root.children.reduce((found, child) => found || findNode(child, name, depth - 1), null); - } - - function logNode(node) - { - var size = typeof node.selfSize === "number" ? node.selfSize ? ">0" : "=0" : "-"; - InspectorTest.log(`size${size} ${node.callFrame.functionName}:${node.callFrame.lineNumber}:${node.callFrame.columnNumber}`); - } - - //# sourceURL=sampling-heap-profiler.html -} -</script> -</head> -<body onload="runTest()"> -<p>Test sampling heap profiler.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler.js new file mode 100644 index 0000000..427b0df --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/sampling-heap-profiler.js
@@ -0,0 +1,59 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank(`Test sampling heap profiler.`); + + function findNode(root, name, depth) { + if (depth < 1 && root.callFrame.functionName === name) + return root; + return root.children.reduce((found, child) => found || findNode(child, name, depth - 1), null); + } + + function logNode(node) { + var size = typeof node.selfSize === 'number' ? node.selfSize ? '>0' : '=0' : '-'; + testRunner.log(`size${size} ${node.callFrame.functionName}:${node.callFrame.lineNumber}:${node.callFrame.columnNumber}`); + } + + await dp.HeapProfiler.startSampling(); + testRunner.log('Sampling started'); + await session.evaluate(` + + + + + + + + + +function testMain() +{ + makeDeepCallStack(10, junkGenerator); +} + +function makeDeepCallStack(depth, action) +{ + if (depth) + makeDeepCallStack(depth - 1, action); + else + action(); +} + +function junkGenerator() +{ + var junkArray = new Array(3000); + window.junkArray = junkArray; + for (var i = 1; i < junkArray.length; ++i) + junkArray[i] = new Array(i); +} + +testMain(); + `); + + var message = await dp.HeapProfiler.stopSampling(); + testRunner.log('Sampling stopped'); + var profile = message.result.profile; + var head = profile.head; + logNode(findNode(head, 'testMain', 1)); + logNode(findNode(head, 'makeDeepCallStack', 11)); + logNode(findNode(head, 'junkGenerator', 12)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot-expected.txt index d48d9ba..16a424e 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot-expected.txt
@@ -1,5 +1,3 @@ Test that heap profiler doesn't crash while taking snapshot on a page where iframe was navigated to a new location after storing a hold of a function from the previous page. Bug 103076. - - SUCCESS: didTakeHeapSnapshot
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot.html b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot.html deleted file mode 100644 index 6805fde..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot.html +++ /dev/null
@@ -1,40 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -var fooRef; -function storeFunctionRefAndNavigateIFrame() -{ - var frame = document.getElementById("myframe"); - fooRef = frame.contentWindow.foo; - frame.src = "about:blank"; - frame.onload = didNavigate; -} - -function didNavigate() -{ - runTest(); -} -function test() -{ - function didTakeHeapSnapshot(messageObject) - { - InspectorTest.log("SUCCESS: didTakeHeapSnapshot"); - InspectorTest.completeTest(); - } - - InspectorTest.sendCommand("Profiler.takeHeapSnapshot", { "reportProgress": false }, didTakeHeapSnapshot); -} -</script> -</head> -<body> -<p>Test that heap profiler doesn't crash while taking snapshot on a page where iframe was navigated to a new location after -storing a hold of a function from the previous page. <a href="https://bugs.webkit.org/show_bug.cgi?id=103076">Bug 103076.</p> -<iframe id="myframe" src="resources/page-with-function.html" onload="storeFunctionRefAndNavigateIFrame()"></iframe> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot.js new file mode 100644 index 0000000..8a2382a --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/take-heap-snapshot.js
@@ -0,0 +1,22 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + 'Test that heap profiler doesn\'t crash while taking snapshot on a page where iframe was navigated to a new location after ' + + 'storing a hold of a function from the previous page. Bug 103076.'); + + await session.evaluateAsync(` + var frame = document.createElement('iframe'); + frame.src = '${testRunner.url('resources/page-with-function.html')}'; + document.body.appendChild(frame); + var loadPromise = new Promise(f => frame.onload = f); + var storeFunctionRefAndNavigateIFramePromise = loadPromise.then(() => { + window.fooRef = frame.contentWindow.foo; + frame.src = 'about:blank'; + return new Promise(f => frame.onload = f); + }); + storeFunctionRefAndNavigateIFramePromise + `); + + await dp.Profiler.takeHeapSnapshot({reportProgress: false}); + testRunner.log('SUCCESS: didTakeHeapSnapshot'); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/storage/websql/fts-crash-703507.html b/third_party/WebKit/LayoutTests/storage/websql/fts-crash-703507.html index 4d77c6c..d08e3512 100644 --- a/third_party/WebKit/LayoutTests/storage/websql/fts-crash-703507.html +++ b/third_party/WebKit/LayoutTests/storage/websql/fts-crash-703507.html
@@ -15,7 +15,7 @@ database.transaction(testCase.step_func(transaction => { transaction.executeSql( 'DROP TABLE IF EXISTS main;', [], () => {}, - testCase.unreached_func('FTS3 table drop should not fail')); + testCase.unreached_func('Table drop should not fail')); transaction.executeSql( 'CREATE VIRTUAL TABLE main USING FTS3(fts3table);', [], () => {}, testCase.unreached_func('FTS3 table creation should not fail'));
diff --git a/third_party/WebKit/LayoutTests/storage/websql/fts-pointer-leak-742407.html b/third_party/WebKit/LayoutTests/storage/websql/fts-pointer-leak-742407.html new file mode 100644 index 0000000..95add45 --- /dev/null +++ b/third_party/WebKit/LayoutTests/storage/websql/fts-pointer-leak-742407.html
@@ -0,0 +1,35 @@ +<!doctype html> +<meta charset="utf-8"> +<title>WebSQL: FTS3 Pointer Leak in bug 742407</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +'use strict'; + +async_test(testCase => { + const database = openDatabase( + 'Fts3CrashTest', '1.0', 'Database for FTS3 crash test', 1024 * 1024); + assert_not_equals(database, null, 'openDatabase should not fail'); + + database.transaction(testCase.step_func(transaction => { + transaction.executeSql( + 'DROP TABLE IF EXISTS main;', [], () => {}, + testCase.unreached_func('FTS3 table drop should not fail')); + transaction.executeSql( + 'CREATE VIRTUAL TABLE main USING FTS3(fts3table);', [], () => {}, + testCase.unreached_func('FTS3 table creation should not fail')); + transaction.executeSql( + "INSERT INTO main VALUES (x'0000000000000000');", [], () => {}, + testCase.unreached_func('FTS3 table insertion should not fail')); + + transaction.executeSql( + 'SELECT hex(main) AS h FROM main;', [], + testCase.step_func((_, result) => { + assert_equals(result.rows.item(0).h, ''); + testCase.done(); + }), testCase.unreached_func('FTS3 select should not fail')); + + })); +}, `SELECT should not return the value of an FTS3 pointer column`); + +</script>
diff --git a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py index db953b7..8eb8aa59 100755 --- a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py +++ b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
@@ -11,7 +11,7 @@ from name_utilities import ( enum_for_css_keyword, enum_type_name, enum_value_name, class_member_name, method_name, - class_name, join_name + class_name, join_names ) from itertools import chain @@ -77,8 +77,8 @@ self.fields = fields self.parent = None - self.type_name = class_name(join_name('style', name, 'data')) - self.member_name = class_member_name(join_name(name, 'data')) + self.type_name = class_name(['style', name, 'data']) + self.member_name = class_member_name([name, 'data']) self.num_32_bit_words_for_bit_fields = _num_32_bit_words_for_bit_fields( field for field in fields if field.is_bit_field ) @@ -188,17 +188,17 @@ self.is_independent = kwargs.pop('independent') assert self.is_inherited or not self.is_independent, 'Only inherited fields can be independent' - self.is_inherited_method_name = method_name(join_name(name_for_methods, 'is inherited')) + self.is_inherited_method_name = method_name([name_for_methods, 'is inherited']) # Method names # TODO(nainar): Method name generation is inconsistent. Fix. self.getter_method_name = getter_method_name self.setter_method_name = setter_method_name - self.internal_getter_method_name = method_name(join_name(self.name, 'Internal')) - self.internal_mutable_method_name = method_name(join_name('Mutable', name_for_methods, 'Internal')) - self.internal_setter_method_name = method_name(join_name(setter_method_name, 'Internal')) + self.internal_getter_method_name = method_name([self.name, 'internal']) + self.internal_mutable_method_name = method_name(['mutable', name_for_methods, 'internal']) + self.internal_setter_method_name = method_name([setter_method_name, 'internal']) self.initial_method_name = initial_method_name - self.resetter_method_name = method_name(join_name('Reset', name_for_methods)) + self.resetter_method_name = method_name(['reset', name_for_methods]) self.default_generated_functions = default_generated_functions # If the size of the field is not None, it means it is a bit field self.is_bit_field = self.size is not None @@ -415,7 +415,7 @@ Create the field used for an inheritance fast path from an independent CSS property, and return the Field object. """ - name_for_methods = join_name(property_['name_for_methods'], 'is inherited') + name_for_methods = join_names(property_['name_for_methods'], 'is', 'inherited') return Field( 'inherited_flag', name_for_methods, @@ -429,8 +429,8 @@ custom_compare=False, mutable=False, getter_method_name=method_name(name_for_methods), - setter_method_name=method_name(join_name('set', name_for_methods)), - initial_method_name=method_name(join_name('initial', name_for_methods)), + setter_method_name=method_name(['set', name_for_methods]), + initial_method_name=method_name(['initial', name_for_methods]), default_generated_functions=property_["default_generated_functions"] )
diff --git a/third_party/WebKit/Source/build/scripts/name_utilities.py b/third_party/WebKit/Source/build/scripts/name_utilities.py index ba2955e..07a8ef0 100644 --- a/third_party/WebKit/Source/build/scripts/name_utilities.py +++ b/third_party/WebKit/Source/build/scripts/name_utilities.py
@@ -132,45 +132,68 @@ upper_first_letter(name)) -def upper_camel_case(name): - return ''.join(upper_first_letter(word) for word in split_name(name)) +def join_names(*names): + """Given a list of names, join them into a single space-separated name.""" + result = [] + for name in names: + result.extend(split_name(name)) + return ' '.join(result) -def lower_camel_case(name): - return lower_first_letter(upper_camel_case(name)) +def naming_style(f): + """Decorator for name utility functions. + + Wraps a name utility function in a function that takes one or more names, + splits them into a list of words, and passes the list to the utility function. + """ + def inner(name_or_names): + names = name_or_names if isinstance(name_or_names, list) else [name_or_names] + words = [] + for name in names: + words.extend(split_name(name)) + return f(words) + return inner -def snake_case(name): - return '_'.join(word.lower() for word in split_name(name)) +@naming_style +def upper_camel_case(words): + return ''.join(upper_first_letter(word) for word in words) + + +@naming_style +def lower_camel_case(words): + return lower_first_letter(upper_camel_case(words)) + + +@naming_style +def snake_case(words): + return '_'.join(word.lower() for word in words) # Use these high level naming functions which describe the semantics of the name, # rather than a particular style. -def enum_type_name(name): - return upper_camel_case(name) +@naming_style +def enum_type_name(words): + return upper_camel_case(words) -def enum_value_name(name): - return 'k' + upper_camel_case(name) +@naming_style +def enum_value_name(words): + return 'k' + upper_camel_case(words) -def class_name(name): - return upper_camel_case(name) +@naming_style +def class_name(words): + return upper_camel_case(words) -def class_member_name(name): - return snake_case(name) + "_" +@naming_style +def class_member_name(words): + return snake_case(words) + "_" -def method_name(name): - return upper_camel_case(name) - - -def join_name(*names): - """Given a list of names, join them into a single space-separated name.""" - result = [] - for name in names: - result.extend(split_name(name)) - return ' '.join(result) +@naming_style +def method_name(words): + return upper_camel_case(words)
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp index 719dc16..0bc6b6c 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -61,6 +61,8 @@ PaintLayerScrollableArea* scrollable_area = ancestor_overflow_layer->GetScrollableArea(); + if (!scrollable_area) + return nullptr; auto it = scrollable_area->GetStickyConstraintsMap().find(obj->Layer()); if (it == scrollable_area->GetStickyConstraintsMap().end()) return nullptr;
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp index 30520de..3cfa7d8 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
@@ -194,8 +194,11 @@ // We ignore LCD text here because we are required to composite // scroll-dependant fixed position elements with composited descendants for // correctness - even if we lose LCD. + // + // TODO(smcgruer): Only composite fixed if needed (http://crbug.com/742213) const bool ignore_lcd_text = true; - if (compositing_reason_finder.RequiresCompositingForScrollDependentPosition( + if (layer->GetLayoutObject().Style()->GetPosition() == EPosition::kFixed || + compositing_reason_finder.RequiresCompositingForScrollDependentPosition( layer, ignore_lcd_text)) { subtree_reasons |= kCompositingReasonPositionFixedOrStickyWithCompositedDescendants;
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp index ed9f69a..755d78c 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -452,18 +452,18 @@ // relative to each other. The first item appended appears at the top of the // overflow menu. overflow_list_->AppendChild(play_button_->CreateOverflowElement( - *this, new MediaControlPlayButtonElement(*this))); + new MediaControlPlayButtonElement(*this))); overflow_list_->AppendChild(fullscreen_button_->CreateOverflowElement( - *this, new MediaControlFullscreenButtonElement(*this))); + new MediaControlFullscreenButtonElement(*this))); overflow_list_->AppendChild(download_button_->CreateOverflowElement( - *this, new MediaControlDownloadButtonElement(*this))); + new MediaControlDownloadButtonElement(*this))); overflow_list_->AppendChild(mute_button_->CreateOverflowElement( - *this, new MediaControlMuteButtonElement(*this))); + new MediaControlMuteButtonElement(*this))); overflow_list_->AppendChild(cast_button_->CreateOverflowElement( - *this, new MediaControlCastButtonElement(*this, false))); + new MediaControlCastButtonElement(*this, false))); overflow_list_->AppendChild( toggle_closed_captions_button_->CreateOverflowElement( - *this, new MediaControlToggleClosedCaptionsButtonElement(*this))); + new MediaControlToggleClosedCaptionsButtonElement(*this))); } Node::InsertionNotificationRequest MediaControlsImpl::InsertedInto(
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp index ed270064..28209ac4 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp
@@ -34,7 +34,6 @@ } HTMLElement* MediaControlInputElement::CreateOverflowElement( - MediaControlsImpl& media_controls, MediaControlInputElement* button) { if (!button) return nullptr; @@ -42,11 +41,10 @@ // We don't want the button visible within the overflow menu. button->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone); - overflow_menu_text_ = Text::Create(media_controls.GetDocument(), - button->GetOverflowMenuString()); + overflow_menu_text_ = + Text::Create(GetDocument(), button->GetOverflowMenuString()); - HTMLLabelElement* element = - HTMLLabelElement::Create(media_controls.GetDocument()); + HTMLLabelElement* element = HTMLLabelElement::Create(GetDocument()); element->SetShadowPseudoId( AtomicString("-internal-media-controls-overflow-menu-list-item")); // Appending a button to a label element ensures that clicks on the label
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h index 3c59b03..abfe535 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h
@@ -23,8 +23,7 @@ static bool ShouldRecordDisplayStates(const HTMLMediaElement&); // Creates an overflow menu element with the given button as a child. - HTMLElement* CreateOverflowElement(MediaControlsImpl&, - MediaControlInputElement*); + HTMLElement* CreateOverflowElement(MediaControlInputElement*); // Implements MediaControlElementBase. void SetOverflowElementIsWanted(bool) final;
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElementTest.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElementTest.cpp index ff4a4da..a21bdf5 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElementTest.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElementTest.cpp
@@ -181,7 +181,7 @@ Persistent<HTMLElement> overflow_container = ControlInputElement().CreateOverflowElement( - MediaControls(), new MediaControlInputElementImpl(MediaControls())); + new MediaControlInputElementImpl(MediaControls())); ControlInputElement().SetIsWanted(true); ControlInputElement().SetDoesFit(false); @@ -198,7 +198,7 @@ Persistent<HTMLElement> overflow_container = ControlInputElement().CreateOverflowElement( - MediaControls(), new MediaControlInputElementImpl(MediaControls())); + new MediaControlInputElementImpl(MediaControls())); ControlInputElement().SetIsWanted(true); ControlInputElement().SetDoesFit(false); @@ -220,7 +220,7 @@ Persistent<HTMLElement> overflow_container = ControlInputElement().CreateOverflowElement( - MediaControls(), new MediaControlInputElementImpl(MediaControls())); + new MediaControlInputElementImpl(MediaControls())); ControlInputElement().SetIsWanted(true); ControlInputElement().SetDoesFit(true);
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp index e786161..9a8d89f5 100644 --- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp +++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
@@ -154,7 +154,7 @@ frames_[index].orientation_ = source_.OrientationAtIndex(index); frames_[index].have_metadata_ = true; - frames_[index].is_complete_ = source_.FrameIsCompleteAtIndex(index); + frames_[index].is_complete_ = source_.FrameIsReceivedAtIndex(index); if (RepetitionCount(false) != kAnimationNone) frames_[index].duration_ = source_.FrameDurationAtIndex(index); frames_[index].has_alpha_ = source_.FrameHasAlphaAtIndex(index); @@ -349,12 +349,12 @@ return DecodeAndCacheFrame(index); } -bool BitmapImage::FrameIsCompleteAtIndex(size_t index) const { +bool BitmapImage::FrameIsReceivedAtIndex(size_t index) const { if (index < frames_.size() && frames_[index].have_metadata_ && frames_[index].is_complete_) return true; - return source_.FrameIsCompleteAtIndex(index); + return source_.FrameIsReceivedAtIndex(index); } float BitmapImage::FrameDurationAtIndex(size_t index) const { @@ -406,7 +406,7 @@ } bool BitmapImage::CurrentFrameIsComplete() { - return FrameIsCompleteAtIndex(CurrentFrame()); + return FrameIsReceivedAtIndex(CurrentFrame()); } bool BitmapImage::CurrentFrameIsLazyDecoded() { @@ -464,7 +464,7 @@ // Don't advance the animation to an incomplete frame. size_t next_frame = (current_frame_ + 1) % FrameCount(); - if (!all_data_received_ && !FrameIsCompleteAtIndex(next_frame)) + if (!all_data_received_ && !FrameIsReceivedAtIndex(next_frame)) return; // Don't advance past the last frame if we haven't decoded the whole image @@ -517,7 +517,7 @@ // case we need to skip some frames entirely. Remember not to advance // to an incomplete frame. for (size_t frame_after_next = (next_frame + 1) % FrameCount(); - FrameIsCompleteAtIndex(frame_after_next); + FrameIsReceivedAtIndex(frame_after_next); frame_after_next = (next_frame + 1) % FrameCount()) { // Should we skip the next frame? double frame_after_next_start_time =
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.h b/third_party/WebKit/Source/platform/graphics/BitmapImage.h index 2c7af2a..c60d02b 100644 --- a/third_party/WebKit/Source/platform/graphics/BitmapImage.h +++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.h
@@ -123,7 +123,7 @@ sk_sp<SkImage> FrameAtIndex(size_t); - bool FrameIsCompleteAtIndex(size_t) const; + bool FrameIsReceivedAtIndex(size_t) const; float FrameDurationAtIndex(size_t) const; bool FrameHasAlphaAtIndex(size_t); ImageOrientation FrameOrientationAtIndex(size_t);
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp index adf65ce9..d37faba7 100644 --- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp
@@ -46,13 +46,13 @@ DeferredFrameData() : orientation_(kDefaultImageOrientation), duration_(0), - is_complete_(false), + is_received_(false), frame_bytes_(0), unique_id_(DecodingImageGenerator::kNeedNewImageUniqueID) {} ImageOrientation orientation_; float duration_; - bool is_complete_; + bool is_received_; size_t frame_bytes_; uint32_t unique_id_; }; @@ -219,11 +219,11 @@ return true; } -bool DeferredImageDecoder::FrameIsCompleteAtIndex(size_t index) const { +bool DeferredImageDecoder::FrameIsReceivedAtIndex(size_t index) const { if (actual_decoder_) - return actual_decoder_->FrameIsCompleteAtIndex(index); + return actual_decoder_->FrameIsReceivedAtIndex(index); if (index < frame_data_.size()) - return frame_data_[index].is_complete_; + return frame_data_[index].is_received_; return false; } @@ -291,15 +291,15 @@ for (size_t i = previous_size; i < frame_data_.size(); ++i) { frame_data_[i].duration_ = actual_decoder_->FrameDurationAtIndex(i); frame_data_[i].orientation_ = actual_decoder_->Orientation(); - frame_data_[i].is_complete_ = actual_decoder_->FrameIsCompleteAtIndex(i); + frame_data_[i].is_received_ = actual_decoder_->FrameIsReceivedAtIndex(i); } // The last lazy decoded frame created from previous call might be // incomplete so update its state. if (previous_size) { const size_t last_frame = previous_size - 1; - frame_data_[last_frame].is_complete_ = - actual_decoder_->FrameIsCompleteAtIndex(last_frame); + frame_data_[last_frame].is_received_ = + actual_decoder_->FrameIsReceivedAtIndex(last_frame); } if (all_data_received_) { @@ -336,7 +336,7 @@ // We can consider decoded bitmap constant and reuse uniqueID only after all // data is received. We reuse it also for multiframe images when image data // is partially received but the frame data is fully received. - if (all_data_received_ || frame_data_[index].is_complete_) { + if (all_data_received_ || frame_data_[index].is_received_) { DCHECK(frame_data_[index].unique_id_ == DecodingImageGenerator::kNeedNewImageUniqueID || frame_data_[index].unique_id_ == image->uniqueID());
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h index 73eafe8a..6b0f4cf 100644 --- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h +++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
@@ -74,7 +74,7 @@ int RepetitionCount() const; size_t ClearCacheExceptFrame(size_t index); bool FrameHasAlphaAtIndex(size_t index) const; - bool FrameIsCompleteAtIndex(size_t index) const; + bool FrameIsReceivedAtIndex(size_t index) const; float FrameDurationAtIndex(size_t index) const; size_t FrameBytesAtIndex(size_t index) const; ImageOrientation OrientationAtIndex(size_t index) const;
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp index c580df1..053a2a5 100644 --- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
@@ -233,18 +233,18 @@ TEST_F(DeferredImageDecoderTest, singleFrameImageLoading) { status_ = ImageFrame::kFramePartial; lazy_decoder_->SetData(data_, false); - EXPECT_FALSE(lazy_decoder_->FrameIsCompleteAtIndex(0)); + EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0)); sk_sp<SkImage> image = lazy_decoder_->CreateFrameAtIndex(0); ASSERT_TRUE(image); unsigned first_id = image->uniqueID(); - EXPECT_FALSE(lazy_decoder_->FrameIsCompleteAtIndex(0)); + EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0)); EXPECT_TRUE(actual_decoder_); status_ = ImageFrame::kFrameComplete; data_->Append(" ", 1u); lazy_decoder_->SetData(data_, true); EXPECT_FALSE(actual_decoder_); - EXPECT_TRUE(lazy_decoder_->FrameIsCompleteAtIndex(0)); + EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0)); image = lazy_decoder_->CreateFrameAtIndex(0); ASSERT_TRUE(image); @@ -263,7 +263,7 @@ sk_sp<SkImage> image = lazy_decoder_->CreateFrameAtIndex(0); ASSERT_TRUE(image); unsigned first_id = image->uniqueID(); - EXPECT_FALSE(lazy_decoder_->FrameIsCompleteAtIndex(0)); + EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0)); EXPECT_EQ(10.0f, lazy_decoder_->FrameDurationAtIndex(0)); frame_count_ = 2; @@ -276,8 +276,8 @@ ASSERT_TRUE(image); unsigned second_id = image->uniqueID(); EXPECT_NE(first_id, second_id); - EXPECT_TRUE(lazy_decoder_->FrameIsCompleteAtIndex(0)); - EXPECT_TRUE(lazy_decoder_->FrameIsCompleteAtIndex(1)); + EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0)); + EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(1)); EXPECT_EQ(20.0f, lazy_decoder_->FrameDurationAtIndex(1)); EXPECT_TRUE(actual_decoder_); @@ -286,9 +286,9 @@ status_ = ImageFrame::kFrameComplete; lazy_decoder_->SetData(data_, true); EXPECT_FALSE(actual_decoder_); - EXPECT_TRUE(lazy_decoder_->FrameIsCompleteAtIndex(0)); - EXPECT_TRUE(lazy_decoder_->FrameIsCompleteAtIndex(1)); - EXPECT_TRUE(lazy_decoder_->FrameIsCompleteAtIndex(2)); + EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0)); + EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(1)); + EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(2)); EXPECT_EQ(10.0f, lazy_decoder_->FrameDurationAtIndex(0)); EXPECT_EQ(20.0f, lazy_decoder_->FrameDurationAtIndex(1)); EXPECT_EQ(30.0f, lazy_decoder_->FrameDurationAtIndex(2));
diff --git a/third_party/WebKit/Source/platform/graphics/ImageSource.cpp b/third_party/WebKit/Source/platform/graphics/ImageSource.cpp index 38c5eff0..a10c7b71 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageSource.cpp +++ b/third_party/WebKit/Source/platform/graphics/ImageSource.cpp
@@ -141,8 +141,8 @@ return !decoder_ || decoder_->FrameHasAlphaAtIndex(index); } -bool ImageSource::FrameIsCompleteAtIndex(size_t index) const { - return decoder_ && decoder_->FrameIsCompleteAtIndex(index); +bool ImageSource::FrameIsReceivedAtIndex(size_t index) const { + return decoder_ && decoder_->FrameIsReceivedAtIndex(index); } size_t ImageSource::FrameBytesAtIndex(size_t index) const {
diff --git a/third_party/WebKit/Source/platform/graphics/ImageSource.h b/third_party/WebKit/Source/platform/graphics/ImageSource.h index a6a9eac2..9432054aa 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageSource.h +++ b/third_party/WebKit/Source/platform/graphics/ImageSource.h
@@ -96,7 +96,7 @@ float FrameDurationAtIndex(size_t) const; bool FrameHasAlphaAtIndex( size_t) const; // Whether or not the frame actually used any alpha. - bool FrameIsCompleteAtIndex( + bool FrameIsReceivedAtIndex( size_t) const; // Whether or not the frame is fully received. ImageOrientation OrientationAtIndex(size_t) const; // EXIF image orientation
diff --git a/third_party/WebKit/Source/platform/graphics/test/MockImageDecoder.h b/third_party/WebKit/Source/platform/graphics/test/MockImageDecoder.h index 74fe6ff..7fd410f 100644 --- a/third_party/WebKit/Source/platform/graphics/test/MockImageDecoder.h +++ b/third_party/WebKit/Source/platform/graphics/test/MockImageDecoder.h
@@ -83,7 +83,7 @@ int RepetitionCount() const override { return client_->RepetitionCount(); } - bool FrameIsCompleteAtIndex(size_t) const override { + bool FrameIsReceivedAtIndex(size_t) const override { return client_->GetStatus() == ImageFrame::kFrameComplete; }
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp index e9f93aec..9f070089 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -150,11 +150,11 @@ } bool ImageDecoder::FrameHasAlphaAtIndex(size_t index) const { - return !FrameIsCompleteAtIndex(index) || + return !FrameIsReceivedAtIndex(index) || frame_buffer_cache_[index].HasAlpha(); } -bool ImageDecoder::FrameIsCompleteAtIndex(size_t index) const { +bool ImageDecoder::FrameIsReceivedAtIndex(size_t index) const { // Animated images override this method to return the status based on the data // received for the queried frame. return IsAllDataReceived();
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h index 96e6159..36d8027 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h +++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
@@ -191,7 +191,7 @@ virtual bool FrameHasAlphaAtIndex(size_t) const; // Whether or not the frame is fully received. - virtual bool FrameIsCompleteAtIndex(size_t) const; + virtual bool FrameIsReceivedAtIndex(size_t) const; // Returns true if a cached complete decode is available. bool FrameIsDecodedAtIndex(size_t) const;
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp index b954a98..dc4823d 100644 --- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -79,7 +79,7 @@ return repetition_count_; } -bool GIFImageDecoder::FrameIsCompleteAtIndex(size_t index) const { +bool GIFImageDecoder::FrameIsReceivedAtIndex(size_t index) const { return reader_ && (index < reader_->ImagesCount()) && reader_->FrameContext(index)->IsComplete(); }
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.h index dec862c..54069d7b 100644 --- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.h +++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.h
@@ -50,7 +50,7 @@ String FilenameExtension() const override { return "gif"; } void OnSetData(SegmentReader* data) override; int RepetitionCount() const override; - bool FrameIsCompleteAtIndex(size_t) const override; + bool FrameIsReceivedAtIndex(size_t) const override; float FrameDurationAtIndex(size_t) const override; // CAUTION: SetFailed() deletes |reader_|. Be careful to avoid // accessing deleted memory, especially when calling this from inside
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoderTest.cpp b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoderTest.cpp index 05e56e9f..8bc212a2 100644 --- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoderTest.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoderTest.cpp
@@ -197,8 +197,8 @@ EXPECT_EQ(2u, decoder->FrameCount()); EXPECT_FALSE(decoder->Failed()); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(0)); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(1)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(1)); EXPECT_EQ(kAnimationLoopInfinite, decoder->RepetitionCount()); } @@ -217,13 +217,13 @@ EXPECT_EQ(2u, decoder->FrameCount()); EXPECT_FALSE(decoder->Failed()); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(0)); - EXPECT_FALSE(decoder->FrameIsCompleteAtIndex(1)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); + EXPECT_FALSE(decoder->FrameIsReceivedAtIndex(1)); decoder->SetData(data_buffer.Get(), true); EXPECT_EQ(2u, decoder->FrameCount()); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(0)); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(1)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(1)); } TEST(GIFImageDecoderTest, badTerminator) {
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp index 65b2dc1..357ceea 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp
@@ -82,7 +82,7 @@ : ((IntSize(width, height) == frame_size_) || SetFailed()); } -bool ICOImageDecoder::FrameIsCompleteAtIndex(size_t index) const { +bool ICOImageDecoder::FrameIsReceivedAtIndex(size_t index) const { if (index >= dir_entries_.size()) return false;
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h index d42a53a..a6ceb69 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h +++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h
@@ -53,7 +53,7 @@ IntSize Size() const override; IntSize FrameSizeAtIndex(size_t) const override; bool SetSize(unsigned width, unsigned height) override; - bool FrameIsCompleteAtIndex(size_t) const override; + bool FrameIsReceivedAtIndex(size_t) const override; // CAUTION: SetFailed() deletes all readers and decoders. Be careful to // avoid accessing deleted memory, especially when calling this from // inside BMPImageReader!
diff --git a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp index 0e12da8..44ee333 100644 --- a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -468,17 +468,16 @@ buffer.SetStatus(ImageFrame::kFrameComplete); } -bool PNGImageDecoder::FrameIsCompleteAtIndex(size_t index) const { +bool PNGImageDecoder::FrameIsReceivedAtIndex(size_t index) const { if (!IsDecodedSizeAvailable()) return false; DCHECK(!Failed() && reader_); - // For non-animated images, return whether the status of the frame is - // ImageFrame::FrameComplete with ImageDecoder::FrameIsCompleteAtIndex. + // For non-animated images, return ImageDecoder::FrameIsReceivedAtIndex. // This matches the behavior of WEBPImageDecoder. if (reader_->ParseCompleted() && reader_->FrameCount() == 1) - return ImageDecoder::FrameIsCompleteAtIndex(index); + return ImageDecoder::FrameIsReceivedAtIndex(index); return reader_->FrameIsReceivedAtIndex(index); }
diff --git a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.h index 8e30a3e..3075bfa1 100644 --- a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.h +++ b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.h
@@ -46,7 +46,7 @@ String FilenameExtension() const override { return "png"; } bool SetSize(unsigned, unsigned) override; int RepetitionCount() const override; - bool FrameIsCompleteAtIndex(size_t) const override; + bool FrameIsReceivedAtIndex(size_t) const override; float FrameDurationAtIndex(size_t) const override; bool SetFailed() override;
diff --git a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp index e99ca52..dfdacf58 100644 --- a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp
@@ -1007,21 +1007,21 @@ SharedBuffer::Create(full_data->Data(), rec.offset_in_first_frame); decoder->SetData(data.Get(), false); - EXPECT_FALSE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_FALSE(decoder->FrameIsReceivedAtIndex(0)); // Parsing the size is not enough to mark the frame as complete. EXPECT_TRUE(decoder->IsSizeAvailable()); - EXPECT_FALSE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_FALSE(decoder->FrameIsReceivedAtIndex(0)); const auto partial_frame_count = decoder->FrameCount(); EXPECT_EQ(1u, partial_frame_count); // Frame is not complete, even after decoding partially. - EXPECT_FALSE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_FALSE(decoder->FrameIsReceivedAtIndex(0)); auto* frame = decoder->FrameBufferAtIndex(0); ASSERT_TRUE(frame); EXPECT_NE(ImageFrame::kFrameComplete, frame->GetStatus()); - EXPECT_FALSE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_FALSE(decoder->FrameIsReceivedAtIndex(0)); decoder->SetData(full_data.Get(), true); @@ -1029,21 +1029,21 @@ // complete for animated images. EXPECT_TRUE(decoder->IsSizeAvailable()); if (rec.expected_frame_count > 1) - EXPECT_FALSE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_FALSE(decoder->FrameIsReceivedAtIndex(0)); else - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); const auto frame_count = decoder->FrameCount(); ASSERT_EQ(rec.expected_frame_count, frame_count); // After parsing (the full file), all frames are complete. for (size_t i = 0; i < frame_count; ++i) - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(i)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(i)); frame = decoder->FrameBufferAtIndex(0); ASSERT_TRUE(frame); EXPECT_EQ(ImageFrame::kFrameComplete, frame->GetStatus()); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); } }
diff --git a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp index 06aee19..1d4fad0 100644 --- a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp
@@ -162,11 +162,11 @@ return Failed() ? kAnimationLoopOnce : repetition_count_; } -bool WEBPImageDecoder::FrameIsCompleteAtIndex(size_t index) const { +bool WEBPImageDecoder::FrameIsReceivedAtIndex(size_t index) const { if (!demux_ || demux_state_ <= WEBP_DEMUX_PARSING_HEADER) return false; if (!(format_flags_ & ANIMATION_FLAG)) - return ImageDecoder::FrameIsCompleteAtIndex(index); + return ImageDecoder::FrameIsReceivedAtIndex(index); bool frame_is_received_at_index = index < frame_buffer_cache_.size(); return frame_is_received_at_index; } @@ -514,7 +514,7 @@ ClearDecoder(); return true; case VP8_STATUS_SUSPENDED: - if (!IsAllDataReceived() && !FrameIsCompleteAtIndex(frame_index)) { + if (!IsAllDataReceived() && !FrameIsReceivedAtIndex(frame_index)) { ApplyPostProcessing(frame_index); return false; }
diff --git a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h index ba2bd3d1..68d6bc5 100644 --- a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h +++ b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h
@@ -48,7 +48,7 @@ String FilenameExtension() const override { return "webp"; } void OnSetData(SegmentReader* data) override; int RepetitionCount() const override; - bool FrameIsCompleteAtIndex(size_t) const override; + bool FrameIsReceivedAtIndex(size_t) const override; float FrameDurationAtIndex(size_t) const override; private:
diff --git a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoderTest.cpp b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoderTest.cpp index 4ba3df7..30eb7daf 100644 --- a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoderTest.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoderTest.cpp
@@ -352,18 +352,18 @@ EXPECT_EQ(2u, decoder->FrameCount()); EXPECT_FALSE(decoder->Failed()); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); EXPECT_EQ(1000, decoder->FrameDurationAtIndex(0)); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(1)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(1)); EXPECT_EQ(500, decoder->FrameDurationAtIndex(1)); decoder->SetData(data_buffer.Get(), true); EXPECT_EQ(3u, decoder->FrameCount()); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(0)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(0)); EXPECT_EQ(1000, decoder->FrameDurationAtIndex(0)); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(1)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(1)); EXPECT_EQ(500, decoder->FrameDurationAtIndex(1)); - EXPECT_TRUE(decoder->FrameIsCompleteAtIndex(2)); + EXPECT_TRUE(decoder->FrameIsReceivedAtIndex(2)); EXPECT_EQ(1000.0, decoder->FrameDurationAtIndex(2)); }
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacement.cpp b/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacement.cpp index a3aa1140..e4ec3f8 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacement.cpp +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacement.cpp
@@ -16,12 +16,8 @@ void TextCodecReplacement::RegisterEncodingNames( EncodingNameRegistrar registrar) { - // The 'replacement' label itself should not be referenceable by - // resources or script - it's a specification convenience - but much of - // the wtf/text API asserts that an encoding name is a label for itself. - // This is handled in TextEncoding by marking it as not valid. + // Taken from the alias table at·https://encoding.spec.whatwg.org/ registrar("replacement", "replacement"); - registrar("csiso2022kr", "replacement"); registrar("hz-gb-2312", "replacement"); registrar("iso-2022-cn", "replacement");
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacement.h b/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacement.h index c03167f..f6862056 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacement.h +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacement.h
@@ -10,6 +10,11 @@ namespace WTF { +// The "replacement" encoding exists to prevent attacks that abuse a mismatch +// between encodings supported on the server and the client. The encoder is +// the same as UTF-8; and for a non-empty input the decoder emits U+FFFD and +// terminates. See: https://encoding.spec.whatwg.org/#replacement and +// https://encoding.spec.whatwg.org/#output-encodings class TextCodecReplacement final : public TextCodecUTF8 { public: TextCodecReplacement();
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacementTest.cpp b/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacementTest.cpp index de1d0d6..3d45c47b 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacementTest.cpp +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodecReplacementTest.cpp
@@ -20,9 +20,8 @@ const char* g_replacement_alias = "iso-2022-kr"; TEST(TextCodecReplacement, Aliases) { - // "replacement" is not a valid alias for itself - EXPECT_FALSE(TextEncoding("replacement").IsValid()); - EXPECT_FALSE(TextEncoding("rEpLaCeMeNt").IsValid()); + EXPECT_TRUE(TextEncoding("replacement").IsValid()); + EXPECT_TRUE(TextEncoding("rEpLaCeMeNt").IsValid()); EXPECT_TRUE(TextEncoding(g_replacement_alias).IsValid()); EXPECT_STREQ("replacement", TextEncoding(g_replacement_alias).GetName());
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextEncoding.cpp b/third_party/WebKit/Source/platform/wtf/text/TextEncoding.cpp index 95fd28f..680c678 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextEncoding.cpp +++ b/third_party/WebKit/Source/platform/wtf/text/TextEncoding.cpp
@@ -44,16 +44,10 @@ TextEncoding::TextEncoding(const char* name) : name_(AtomicCanonicalTextEncodingName(name)) { - // Aliases are valid, but not "replacement" itself. - if (name_ && IsReplacementEncoding(name)) - name_ = 0; } TextEncoding::TextEncoding(const String& name) : name_(AtomicCanonicalTextEncodingName(name)) { - // Aliases are valid, but not "replacement" itself. - if (name_ && IsReplacementEncoding(name)) - name_ = 0; } String TextEncoding::Decode(const char* data,
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextEncodingRegistry.cpp b/third_party/WebKit/Source/platform/wtf/text/TextEncodingRegistry.cpp index b0709fb..7e4c1339 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextEncodingRegistry.cpp +++ b/third_party/WebKit/Source/platform/wtf/text/TextEncodingRegistry.cpp
@@ -222,14 +222,6 @@ TextCodecUserDefined::RegisterCodecs(AddToTextCodecMap); } -bool IsReplacementEncoding(const char* alias) { - return alias && !strcasecmp(alias, "replacement"); -} - -bool IsReplacementEncoding(const String& alias) { - return alias == "replacement"; -} - static void ExtendTextCodecMaps() { TextCodecReplacement::RegisterEncodingNames(AddToTextEncodingNameMap); TextCodecReplacement::RegisterCodecs(AddToTextCodecMap);
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextEncodingRegistry.h b/third_party/WebKit/Source/platform/wtf/text/TextEncodingRegistry.h index e92fcc3..1a715dc 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextEncodingRegistry.h +++ b/third_party/WebKit/Source/platform/wtf/text/TextEncodingRegistry.h
@@ -46,8 +46,6 @@ const char* AtomicCanonicalTextEncodingName(const CharacterType*, size_t); const char* AtomicCanonicalTextEncodingName(const String&); bool NoExtendedTextEncodingNameUsed(); -bool IsReplacementEncoding(const char* alias); -bool IsReplacementEncoding(const String& alias); #ifndef NDEBUG void DumpTextEncodingNameMap();
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/test_result_writer.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/test_result_writer.py index 1edcba9fd..e3b5857 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/test_result_writer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/test_result_writer.py
@@ -145,7 +145,22 @@ """ fs = self._filesystem output_filename = fs.join(self._root_output_dir, self._test_name) - return fs.splitext(output_filename)[0] + modifier + base, extension = fs.splitext(output_filename) + + # Below is an affordance for WPT test files that become multiple tests using different URL params, + # For example, + # - html/syntax/parsing/html5lib_adoption01.html + # Becomes two tests: + # - html/syntax/parsing/html5lib_adoption01.html?run_type=write + # - html/syntax/parsing/html5lib_adoption01.html?run_type=uri + # But previously their result file would be the same, since everything after the extension + # is removed. Instead, for files with URL params, we use the whole filename for writing results. + if '?' in extension: + # Question marks are reserved characters in Windows filenames. + sanitized_filename = output_filename.replace('?', '_') + return sanitized_filename + modifier + + return base + modifier def _write_file(self, path, contents): if contents is not None:
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/lint_test_expectations.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/lint_test_expectations.py index ca7dfe15..c357dfd 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/lint_test_expectations.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/lint_test_expectations.py
@@ -35,6 +35,7 @@ from webkitpy.common import exit_codes from webkitpy.layout_tests.models import test_expectations from webkitpy.layout_tests.port.factory import platform_options +from webkitpy.w3c.wpt_manifest import WPTManifest _log = logging.getLogger(__name__) @@ -151,6 +152,11 @@ else: host = Host() + # Need to generate MANIFEST.json since some expectations correspond to WPT + # tests that aren't files and only exist in the manifest. + _log.info('Generating MANIFEST.json for web-platform-tests ...') + WPTManifest.ensure_manifest(host) + try: exit_status = run_checks(host, options, stderr) except KeyboardInterrupt:
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 93ec408..1fab56b7 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
@@ -34,7 +34,6 @@ import collections import errno -import functools import json import logging import optparse @@ -667,22 +666,43 @@ return reftest_list def tests(self, paths): - """Returns the list of tests found matching paths.""" + """Returns all tests or tests matching supplied paths. + + Args: + paths: Array of paths to match. If supplied, this function will only + return tests matching at least one path in paths. + + Returns: + An array of test paths and test names. The latter are web platform + tests that don't correspond to file paths but are valid tests, + for instance a file path test.any.js could correspond to two test + names: test.any.html and test.any.worker.html. + """ tests = self.real_tests(paths) suites = self.virtual_test_suites() if paths: tests.extend(self._virtual_tests_matching_paths(paths, suites)) + tests.extend(self._wpt_test_urls_matching_paths(paths)) else: tests.extend(self._all_virtual_tests(suites)) + tests.extend(['external/wpt' + test for test in self._wpt_manifest().all_urls()]) + return tests def real_tests(self, paths): # When collecting test cases, skip these directories. - skipped_directories = set(['platform', 'resources', 'support', 'script-tests', 'reference', 'reftest']) - files = find_files.find(self._filesystem, self.layout_tests_dir(), paths, - skipped_directories, functools.partial(Port.is_test_file, self), self.test_key) - return self._convert_wpt_file_paths_to_url_paths([self.relative_test_filename(f) for f in files]) + skipped_directories = set([ + 'platform', 'resources', 'support', 'script-tests', + 'reference', 'reftest', 'external' + ]) + is_non_wpt_real_test_file = lambda fs, dirname, filename: ( + self.is_test_file(fs, dirname, filename) + and not re.search(r'[/\\]external[/\\]wpt([/\\].*)?$', dirname) + ) + files = find_files.find(self._filesystem, self.layout_tests_dir(), paths, skipped_directories, + is_non_wpt_real_test_file, self.test_key) + return [self.relative_test_filename(f) for f in files] @staticmethod # If any changes are made here be sure to update the isUsedInReftest method in old-run-webkit-tests as well. @@ -722,17 +742,15 @@ return Port._has_supported_extension( filesystem, filename) and not Port.is_reference_html_file(filesystem, dirname, filename) - def _convert_wpt_file_paths_to_url_paths(self, files): + def _convert_wpt_file_path_to_url_paths(self, file_path): tests = [] - for file_path in files: - # Path separators are normalized by relative_test_filename(). - match = re.search(r'external/wpt/(.*)$', file_path) - if not match: - tests.append(file_path) - continue - urls = self._wpt_manifest().file_path_to_url_paths(match.group(1)) - for url in urls: - tests.append(file_path[0:match.start(1)] + url) + # Path separators are normalized by relative_test_filename(). + match = re.search(r'external/wpt/(.*)$', file_path) + if not match: + return [file_path] + urls = self._wpt_manifest().file_path_to_url_paths(match.group(1)) + for url in urls: + tests.append(file_path[0:match.start(1)] + url) return tests @memoized @@ -828,7 +846,7 @@ """Returns True if the test name refers to an existing test or baseline.""" # Used by test_expectations.py to determine if an entry refers to a # valid test and by printing.py to determine if baselines exist. - return self.test_isfile(test_name) or self.test_isdir(test_name) + return self.is_wpt_test(test_name) or self.test_isfile(test_name) or self.test_isdir(test_name) def split_test(self, test_name): """Splits a test name into the 'directory' part and the 'basename' part.""" @@ -1518,9 +1536,42 @@ tests.append(test) return tests + def _wpt_test_urls_matching_paths(self, paths): + tests = [] + + for test_url_path in self._wpt_manifest().all_urls(): + if test_url_path[0] == '/': + test_url_path = test_url_path[1:] + + full_test_url_path = 'external/wpt/' + test_url_path + + for path in paths: + if 'external' not in path: + continue + + wpt_path = path.replace('external/wpt/', '') + + # When `test_url_path` is test.any.html or test.any.worker.html and path is test.any.js + matches_any_js_test = ( + self._wpt_manifest().is_test_file(wpt_path) + and test_url_path.startswith(re.sub(r'\.js$', '', wpt_path)) + ) + + # Get a list of directories for both paths, filter empty strings + full_test_url_directories = filter(None, full_test_url_path.split(self._filesystem.sep)) + path_directories = filter(None, path.split(self._filesystem.sep)) + + # For all other path matches within WPT + if matches_any_js_test or path_directories == full_test_url_directories[0:len(path_directories)]: + wpt_file_paths = self._convert_wpt_file_path_to_url_paths(test_url_path) + tests.extend('external/wpt/' + wpt_file_path for wpt_file_path in wpt_file_paths) + + return tests + def _populate_virtual_suite(self, suite): if not suite.tests: base_tests = self.real_tests([suite.base]) + base_tests.extend(self._wpt_test_urls_matching_paths([suite.base])) suite.tests = {} for test in base_tests: suite.tests[test.replace(suite.base, suite.name, 1)] = test
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py index 28827c8..522643e 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py
@@ -281,14 +281,72 @@ PortTest._add_manifest_to_mock_file_system(port.host.filesystem) self.assertIn('external/wpt/dom/ranges/Range-attributes.html', port.tests([])) self.assertNotIn('external/wpt/console/console-is-a-namespace.any.js', port.tests([])) - self.assertEqual(port.tests(['external']), ['external/wpt/dom/ranges/Range-attributes.html']) - self.assertEqual(port.tests(['external/']), ['external/wpt/dom/ranges/Range-attributes.html']) + + # test.any.js shows up on the filesystem as one file but it effectively becomes two test files: + # test.any.html and test.any.worker.html. We should support running test.any.js by name and + # indirectly by specifying a parent directory. + self.assertEqual(port.tests(['external']), + ['external/wpt/html/dom/elements/global-attributes/dir_auto-EN-L.html', + 'external/wpt/dom/ranges/Range-attributes.html', + 'external/wpt/console/console-is-a-namespace.any.worker.html', + 'external/wpt/console/console-is-a-namespace.any.html']) + self.assertEqual(port.tests(['external/']), + ['external/wpt/html/dom/elements/global-attributes/dir_auto-EN-L.html', + 'external/wpt/dom/ranges/Range-attributes.html', + 'external/wpt/console/console-is-a-namespace.any.worker.html', + 'external/wpt/console/console-is-a-namespace.any.html']) self.assertEqual(port.tests(['external/csswg-test']), []) - self.assertEqual(port.tests(['external/wpt']), ['external/wpt/dom/ranges/Range-attributes.html']) - self.assertEqual(port.tests(['external/wpt/']), ['external/wpt/dom/ranges/Range-attributes.html']) + self.assertEqual(port.tests(['external/wpt']), + ['external/wpt/html/dom/elements/global-attributes/dir_auto-EN-L.html', + 'external/wpt/dom/ranges/Range-attributes.html', + 'external/wpt/console/console-is-a-namespace.any.worker.html', + 'external/wpt/console/console-is-a-namespace.any.html']) + self.assertEqual(port.tests(['external/wpt/']), + ['external/wpt/html/dom/elements/global-attributes/dir_auto-EN-L.html', + 'external/wpt/dom/ranges/Range-attributes.html', + 'external/wpt/console/console-is-a-namespace.any.worker.html', + 'external/wpt/console/console-is-a-namespace.any.html']) + self.assertEqual(port.tests(['external/wpt/console']), + ['external/wpt/console/console-is-a-namespace.any.worker.html', + 'external/wpt/console/console-is-a-namespace.any.html']) + self.assertEqual(port.tests(['external/wpt/console/']), + ['external/wpt/console/console-is-a-namespace.any.worker.html', + 'external/wpt/console/console-is-a-namespace.any.html']) + self.assertEqual(port.tests(['external/wpt/console/console-is-a-namespace.any.js']), + ['external/wpt/console/console-is-a-namespace.any.worker.html', + 'external/wpt/console/console-is-a-namespace.any.html']) + self.assertEqual(port.tests(['external/wpt/console/console-is-a-namespace.any.html']), + ['external/wpt/console/console-is-a-namespace.any.html']) + self.assertEqual(port.tests(['external/wpt/dom']), + ['external/wpt/dom/ranges/Range-attributes.html']) + self.assertEqual(port.tests(['external/wpt/dom/']), + ['external/wpt/dom/ranges/Range-attributes.html']) self.assertEqual(port.tests(['external/wpt/dom/ranges/Range-attributes.html']), ['external/wpt/dom/ranges/Range-attributes.html']) + def test_virtual_wpt_tests_paths(self): + port = self.make_port(with_tests=True) + PortTest._add_manifest_to_mock_file_system(port.host.filesystem) + all_wpt = [ + 'virtual/virtual_wpt/external/wpt/console/console-is-a-namespace.any.html', + 'virtual/virtual_wpt/external/wpt/html/dom/elements/global-attributes/dir_auto-EN-L.html', + 'virtual/virtual_wpt/external/wpt/console/console-is-a-namespace.any.worker.html', + 'virtual/virtual_wpt/external/wpt/dom/ranges/Range-attributes.html', + ] + dom_wpt = [ + 'virtual/virtual_wpt_dom/external/wpt/dom/ranges/Range-attributes.html', + ] + + self.assertEqual(port.tests(['virtual/virtual_wpt/external/']), all_wpt) + self.assertEqual(port.tests(['virtual/virtual_wpt/external/wpt/']), all_wpt) + self.assertEqual(port.tests(['virtual/virtual_wpt/external/wpt/console']), + ['virtual/virtual_wpt/external/wpt/console/console-is-a-namespace.any.html', + 'virtual/virtual_wpt/external/wpt/console/console-is-a-namespace.any.worker.html']) + + self.assertEqual(port.tests(['virtual/virtual_wpt_dom/external/wpt/dom/']), dom_wpt) + self.assertEqual(port.tests(['virtual/virtual_wpt_dom/external/wpt/dom/ranges/']), dom_wpt) + self.assertEqual(port.tests(['virtual/virtual_wpt_dom/external/wpt/dom/ranges/Range-attributes.html']), dom_wpt) + def test_is_test_file(self): port = self.make_port(with_tests=True) is_test_file = functools.partial(Port.is_test_file, port, port.host.filesystem) @@ -329,6 +387,16 @@ # A file in external/wpt_automation. self.assertTrue(port.is_test_file(filesystem, LAYOUT_TEST_DIR + '/external/wpt_automation', 'foo.html')) + def test_is_wpt_test(self): + port = self.make_port(with_tests=True) + filesystem = port.host.filesystem + PortTest._add_manifest_to_mock_file_system(filesystem) + + self.assertTrue(port.is_wpt_test('external/wpt/dom/ranges/Range-attributes.html')) + self.assertTrue(port.is_wpt_test('external/wpt/html/dom/elements/global-attributes/dir_auto-EN-L.html')) + self.assertFalse(port.is_wpt_test('dom/domparsing/namespaces-1.html')) + self.assertFalse(port.is_wpt_test('rutabaga')) + def test_is_slow_wpt_test(self): port = self.make_port(with_tests=True) filesystem = port.host.filesystem
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py index e133fdb..40774ab3 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py
@@ -533,6 +533,8 @@ VirtualTestSuite(prefix='skipped', base='failures/expected', args=['--virtual-arg2']), VirtualTestSuite(prefix='references_use_default_args', base='passes/reftest.html', args=['--virtual-arg'], references_use_default_args=True), + VirtualTestSuite(prefix='virtual_wpt', base='external/wpt', args=['--virtual-arg']), + VirtualTestSuite(prefix='virtual_wpt_dom', base='external/wpt/dom', args=['--virtual-arg']), ]
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py index d7eac77..a68714d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py
@@ -101,6 +101,8 @@ self.mac_port.layout_tests_dir(), test) self._write(path, 'contents') + self.mac_port.host.filesystem.write_text_file('/test.checkout/LayoutTests/external/wpt/MANIFEST.json', '{}') + def tearDown(self): BaseTestCase.tearDown(self) LoggingTestCase.tearDown(self)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_manifest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_manifest.py index 25be40d..128a038 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_manifest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_manifest.py
@@ -13,6 +13,7 @@ import logging from webkitpy.common.path_finder import PathFinder +from webkitpy.common.memoized import memoized _log = logging.getLogger(__file__) @@ -23,6 +24,7 @@ # TODO(tkent): Create a Manifest object by Manifest.from_json(). # See ../thirdparty/wpt/wpt/tools/manifest/manifest.py. self.raw_dict = json.loads(json_content) + self.test_types = ('manual', 'reftest', 'testharness') def _items_for_path(self, path_in_wpt): """Returns manifest items for the given WPT path, or None if not found. @@ -35,28 +37,50 @@ it will be a list with three items ([url, references, extras]). """ items = self.raw_dict['items'] - if path_in_wpt in items['manual']: - return items['manual'][path_in_wpt] - elif path_in_wpt in items['reftest']: - return items['reftest'][path_in_wpt] - elif path_in_wpt in items['testharness']: - return items['testharness'][path_in_wpt] + for test_type in self.test_types: + if path_in_wpt in items[test_type]: + return items[test_type][path_in_wpt] return None + @memoized + def all_urls(self): + """Returns a set of the urls for all items in the manifest.""" + urls = set() + if 'items' in self.raw_dict: + items = self.raw_dict['items'] + for category in self.test_types: + if category in items: + for records in items[category].values(): + urls.update([item[0] for item in records]) + return urls + + @memoized + def all_wpt_tests(self): + if 'items' not in self.raw_dict: + return [] + + all_tests = [] + for test_type in self.test_types: + for path_in_wpt in self.raw_dict['items'][test_type]: + all_tests.append(path_in_wpt) + return all_tests + def is_test_file(self, path_in_wpt): return self._items_for_path(path_in_wpt) is not None + def is_test_url(self, url): + """Checks if url is a valid test in the manifest. + + The url must be the WPT test name with a leading slash (/). + """ + if url[0] != '/': + raise Exception('Test url missing leading /: %s' % url) + return url in self.all_urls() + def file_path_to_url_paths(self, path_in_wpt): manifest_items = self._items_for_path(path_in_wpt) assert manifest_items is not None - if len(manifest_items) != 1: - return [] - url = manifest_items[0][0] - if url[1:] != path_in_wpt: - # TODO(tkent): foo.any.js and bar.worker.js should be accessed - # as foo.any.html, foo.any.worker, and bar.worker with WPTServe. - return [] - return [path_in_wpt] + return [item[0][1:] for item in manifest_items] @staticmethod def _get_extras_from_item(item):
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c index f0075cfb..68fd2604 100644 --- a/third_party/sqlite/amalgamation/sqlite3.c +++ b/third_party/sqlite/amalgamation/sqlite3.c
@@ -4065,6 +4065,15 @@ ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** +** ^The sqlite3_bind_pointer(S,I,P) routine causes the I-th parameter in +** [prepared statement] S to have an SQL value of NULL, but to also be +** associated with the pointer P. +** ^The sqlite3_bind_pointer() routine can be used to pass +** host-language pointers into [application-defined SQL functions]. +** ^A parameter that is initialized using [sqlite3_bind_pointer()] appears +** to be an ordinary SQL NULL value to everything other than +** [sqlite3_value_pointer()]. +** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], @@ -4098,6 +4107,7 @@ SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*); SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -4867,6 +4877,11 @@ ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** +** ^If [sqlite3_value] object V was initialized +** using [sqlite3_bind_pointer(S,I,P)] or [sqlite3_result_pointer(C,P)], then +** sqlite3_value_pointer(V) will return the pointer P. Otherwise, +** sqlite3_value_pointer(V) returns a NULL. +** ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If @@ -4894,6 +4909,7 @@ SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API void *sqlite3_value_pointer(sqlite3_value*); SQLITE_API int sqlite3_value_type(sqlite3_value*); SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); @@ -4906,10 +4922,6 @@ ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. -** -** SQLite makes no use of subtype itself. It merely passes the subtype -** from the result of one [application-defined SQL function] into the -** input of another. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -5187,6 +5199,14 @@ ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** +** ^The sqlite3_result_pointer(C,P) interface sets the result to an +** SQL NULL value, just like [sqlite3_result_null(C)], except that it +** also associates the host-language pointer P with that NULL value such +** that the pointer can be retrieved within an +** [application-defined SQL function] using [sqlite3_value_pointer()]. +** This mechanism can be used to pass non-SQL values between +** application-defined functions. +** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. @@ -5210,6 +5230,7 @@ SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*); SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); @@ -18089,6 +18110,7 @@ double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Used when bit MEM_Zero is set in flags */ + void *pPtr; /* Pointer when flags=MEM_NULL and eSubtype='p' */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ @@ -18374,6 +18396,7 @@ #else SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); #endif +SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*); SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); @@ -70280,6 +70303,17 @@ } } +/* +** Set the value stored in *pMem should already be a NULL. +** Also store a pointer to go with it. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem *pMem, void *pPtr){ + assert( pMem->flags==MEM_Null ); + pMem->flags = MEM_Null|MEM_Subtype; + pMem->u.pPtr = pPtr; + pMem->eSubtype = 'p'; +} + #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Delete any previous value and set the value stored in *pMem to val, @@ -76159,6 +76193,14 @@ Mem *pMem = (Mem*)pVal; return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } +SQLITE_API void *sqlite3_value_pointer(sqlite3_value *pVal){ + Mem *p = (Mem*)pVal; + if( (p->flags & MEM_TypeMask)==(MEM_Null|MEM_Subtype) && p->eSubtype=='p' ){ + return p->u.pPtr; + }else{ + return 0; + } +} SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } @@ -76337,6 +76379,12 @@ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } +SQLITE_API void sqlite3_result_pointer(sqlite3_context *pCtx, void *pPtr){ + Mem *pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetPointer(pOut, pPtr); +} SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); @@ -77322,6 +77370,16 @@ } return rc; } +SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} SQLITE_API int sqlite3_bind_text( sqlite3_stmt *pStmt, int i, @@ -148237,9 +148295,8 @@ sqlite3_result_int64(pCtx, pCsr->iPrevId); }else if( iCol==p->nColumn ){ /* The extra column whose name is the same as the table. - ** Return a blob which is a pointer to the cursor. */ - sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); - sqlite3_result_subtype(pCtx, '3'); + ** Return a pointer to the cursor. */ + sqlite3_result_pointer(pCtx, pCsr); }else if( iCol==p->nColumn+2 && pCsr->pExpr ){ sqlite3_result_int64(pCtx, pCsr->iLangid); }else{ @@ -148451,17 +148508,13 @@ sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ - Fts3Cursor *pRet; - if( sqlite3_value_type(pVal)!=SQLITE_BLOB - || sqlite3_value_subtype(pVal)!='3' - || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *) - ){ + Fts3Cursor *pRet = (Fts3Cursor*)sqlite3_value_pointer(pVal); + if( pRet==0 ){ char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); sqlite3_result_error(pContext, zErr, -1); sqlite3_free(zErr); return SQLITE_ERROR; } - memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *)); *ppCsr = pRet; return SQLITE_OK; }
diff --git a/third_party/sqlite/amalgamation/sqlite3.h b/third_party/sqlite/amalgamation/sqlite3.h index 8e4e11e..a476a98 100644 --- a/third_party/sqlite/amalgamation/sqlite3.h +++ b/third_party/sqlite/amalgamation/sqlite3.h
@@ -3786,6 +3786,15 @@ ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** +** ^The sqlite3_bind_pointer(S,I,P) routine causes the I-th parameter in +** [prepared statement] S to have an SQL value of NULL, but to also be +** associated with the pointer P. +** ^The sqlite3_bind_pointer() routine can be used to pass +** host-language pointers into [application-defined SQL functions]. +** ^A parameter that is initialized using [sqlite3_bind_pointer()] appears +** to be an ordinary SQL NULL value to everything other than +** [sqlite3_value_pointer()]. +** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], @@ -3819,6 +3828,7 @@ SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*); SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -4588,6 +4598,11 @@ ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** +** ^If [sqlite3_value] object V was initialized +** using [sqlite3_bind_pointer(S,I,P)] or [sqlite3_result_pointer(C,P)], then +** sqlite3_value_pointer(V) will return the pointer P. Otherwise, +** sqlite3_value_pointer(V) returns a NULL. +** ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If @@ -4615,6 +4630,7 @@ SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API void *sqlite3_value_pointer(sqlite3_value*); SQLITE_API int sqlite3_value_type(sqlite3_value*); SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); @@ -4627,10 +4643,6 @@ ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. -** -** SQLite makes no use of subtype itself. It merely passes the subtype -** from the result of one [application-defined SQL function] into the -** input of another. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -4908,6 +4920,14 @@ ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** +** ^The sqlite3_result_pointer(C,P) interface sets the result to an +** SQL NULL value, just like [sqlite3_result_null(C)], except that it +** also associates the host-language pointer P with that NULL value such +** that the pointer can be retrieved within an +** [application-defined SQL function] using [sqlite3_value_pointer()]. +** This mechanism can be used to pass non-SQL values between +** application-defined functions. +** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. @@ -4931,6 +4951,7 @@ SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*); SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
diff --git a/third_party/sqlite/patches/0013-Add-new-interfaces-sqlite3_bind_pointer-sqlite3_resu.patch b/third_party/sqlite/patches/0013-Add-new-interfaces-sqlite3_bind_pointer-sqlite3_resu.patch new file mode 100644 index 0000000..e65e75f --- /dev/null +++ b/third_party/sqlite/patches/0013-Add-new-interfaces-sqlite3_bind_pointer-sqlite3_resu.patch
@@ -0,0 +1,420 @@ +From 3dac6f0ce5313f60acc6b7abca1d431001ad0187 Mon Sep 17 00:00:00 2001 +From: Victor Costan <pwnall@chromium.org> +Date: Sat, 15 Jul 2017 12:30:42 -0700 +Subject: [PATCH 13/13] Add new interfaces sqlite3_bind_pointer(), + sqlite3_result_pointer(), and sqlite3_value_pointer() used to safely move + pointer values through SQL without exposing underlying memory address + information. + +--- + third_party/sqlite/src/ext/fts3/fts3.c | 13 +++------ + third_party/sqlite/src/ext/misc/carray.c | 46 ++++++++++++++++++++++++++---- + third_party/sqlite/src/ext/misc/remember.c | 6 ++-- + third_party/sqlite/src/src/sqlite.h.in | 29 ++++++++++++++++--- + third_party/sqlite/src/src/vdbeInt.h | 2 ++ + third_party/sqlite/src/src/vdbeapi.c | 24 ++++++++++++++++ + third_party/sqlite/src/src/vdbemem.c | 11 +++++++ + third_party/sqlite/src/test/tabfunc01.test | 25 ++++++++-------- + 8 files changed, 122 insertions(+), 34 deletions(-) + +diff --git a/third_party/sqlite/src/ext/fts3/fts3.c b/third_party/sqlite/src/ext/fts3/fts3.c +index 827769881616..5d2f21d2937f 100644 +--- a/third_party/sqlite/src/ext/fts3/fts3.c ++++ b/third_party/sqlite/src/ext/fts3/fts3.c +@@ -3347,9 +3347,8 @@ static int fts3ColumnMethod( + sqlite3_result_int64(pCtx, pCsr->iPrevId); + }else if( iCol==p->nColumn ){ + /* The extra column whose name is the same as the table. +- ** Return a blob which is a pointer to the cursor. */ +- sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); +- sqlite3_result_subtype(pCtx, '3'); ++ ** Return a pointer to the cursor. */ ++ sqlite3_result_pointer(pCtx, pCsr); + }else if( iCol==p->nColumn+2 && pCsr->pExpr ){ + sqlite3_result_int64(pCtx, pCsr->iLangid); + }else{ +@@ -3561,17 +3560,13 @@ static int fts3FunctionArg( + sqlite3_value *pVal, /* argv[0] passed to function */ + Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ + ){ +- Fts3Cursor *pRet; +- if( sqlite3_value_type(pVal)!=SQLITE_BLOB +- || sqlite3_value_subtype(pVal)!='3' +- || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *) +- ){ ++ Fts3Cursor *pRet = (Fts3Cursor*)sqlite3_value_pointer(pVal); ++ if( pRet==0 ){ + char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); + sqlite3_result_error(pContext, zErr, -1); + sqlite3_free(zErr); + return SQLITE_ERROR; + } +- memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *)); + *ppCsr = pRet; + return SQLITE_OK; + } +diff --git a/third_party/sqlite/src/ext/misc/carray.c b/third_party/sqlite/src/ext/misc/carray.c +index 025eb5db2c0e..2fdff0cd3afc 100644 +--- a/third_party/sqlite/src/ext/misc/carray.c ++++ b/third_party/sqlite/src/ext/misc/carray.c +@@ -73,7 +73,7 @@ typedef struct carray_cursor carray_cursor; + struct carray_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3_int64 iRowid; /* The rowid */ +- sqlite3_int64 iPtr; /* Pointer to array of values */ ++ void* pPtr; /* Pointer to the array of values */ + sqlite3_int64 iCnt; /* Number of integers in the array */ + unsigned char eType; /* One of the CARRAY_type values */ + }; +@@ -167,7 +167,7 @@ static int carrayColumn( + carray_cursor *pCur = (carray_cursor*)cur; + sqlite3_int64 x = 0; + switch( i ){ +- case CARRAY_COLUMN_POINTER: x = pCur->iPtr; break; ++ case CARRAY_COLUMN_POINTER: return SQLITE_OK; + case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break; + case CARRAY_COLUMN_CTYPE: { + sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC); +@@ -232,8 +232,8 @@ static int carrayFilter( + ){ + carray_cursor *pCur = (carray_cursor *)pVtabCursor; + if( idxNum ){ +- pCur->iPtr = sqlite3_value_int64(argv[0]); +- pCur->iCnt = sqlite3_value_int64(argv[1]); ++ pCur->pPtr = sqlite3_value_pointer(argv[0]); ++ pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0; + if( idxNum<3 ){ + pCur->eType = CARRAY_INT32; + }else{ +@@ -251,7 +251,7 @@ static int carrayFilter( + } + } + }else{ +- pCur->iPtr = 0; ++ pCur->pPtr = 0; + pCur->iCnt = 0; + } + pCur->iRowid = 1; +@@ -345,6 +345,34 @@ static sqlite3_module carrayModule = { + 0, /* xRename */ + }; + ++/* ++** For testing purpose in the TCL test harness, we need a method for ++** setting the pointer value. The inttoptr(X) SQL function accomplishes ++** this. Tcl script will bind an integer to X and the inttoptr() SQL ++** function will use sqlite3_result_pointer() to convert that integer into ++** a pointer. ++** ++** This is for testing on TCL only. ++*/ ++#ifdef SQLITE_TEST ++static void inttoptrFunc( ++ sqlite3_context *context, ++ int argc, ++ sqlite3_value **argv ++){ ++ void *p; ++ sqlite3_int64 i64; ++ i64 = sqlite3_value_int64(argv[0]); ++ if( sizeof(i64)==sizeof(p) ){ ++ memcpy(&p, &i64, sizeof(p)); ++ }else{ ++ int i32 = i64 & 0xffffffff; ++ memcpy(&p, &i32, sizeof(p)); ++ } ++ sqlite3_result_pointer(context, p); ++} ++#endif /* SQLITE_TEST */ ++ + #endif /* SQLITE_OMIT_VIRTUALTABLE */ + + #ifdef _WIN32 +@@ -359,6 +387,12 @@ int sqlite3_carray_init( + SQLITE_EXTENSION_INIT2(pApi); + #ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3_create_module(db, "carray", &carrayModule, 0); +-#endif ++#ifdef SQLITE_TEST ++ if( rc==SQLITE_OK ){ ++ rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0, ++ inttoptrFunc, 0, 0); ++ } ++#endif /* SQLITE_TEST */ ++#endif /* SQLITE_OMIT_VIRTUALTABLE */ + return rc; + } +diff --git a/third_party/sqlite/src/ext/misc/remember.c b/third_party/sqlite/src/ext/misc/remember.c +index aa3eff8a3f8b..587d44a12cdc 100644 +--- a/third_party/sqlite/src/ext/misc/remember.c ++++ b/third_party/sqlite/src/ext/misc/remember.c +@@ -44,11 +44,11 @@ static void rememberFunc( + sqlite3_value **argv + ){ + sqlite3_int64 v; +- sqlite3_int64 ptr; ++ sqlite3_int64 *ptr; + assert( argc==2 ); + v = sqlite3_value_int64(argv[0]); +- ptr = sqlite3_value_int64(argv[1]); +- *((sqlite3_int64*)ptr) = v; ++ ptr = sqlite3_value_pointer(argv[1]); ++ if( ptr ) *ptr = v; + sqlite3_result_int64(pCtx, v); + } + +diff --git a/third_party/sqlite/src/src/sqlite.h.in b/third_party/sqlite/src/src/sqlite.h.in +index fbbf4b9f2db3..371ae5848bbc 100644 +--- a/third_party/sqlite/src/src/sqlite.h.in ++++ b/third_party/sqlite/src/src/sqlite.h.in +@@ -3786,6 +3786,15 @@ typedef struct sqlite3_context sqlite3_context; + ** [sqlite3_blob_open | incremental BLOB I/O] routines. + ** ^A negative value for the zeroblob results in a zero-length BLOB. + ** ++** ^The sqlite3_bind_pointer(S,I,P) routine causes the I-th parameter in ++** [prepared statement] S to have an SQL value of NULL, but to also be ++** associated with the pointer P. ++** ^The sqlite3_bind_pointer() routine can be used to pass ++** host-language pointers into [application-defined SQL functions]. ++** ^A parameter that is initialized using [sqlite3_bind_pointer()] appears ++** to be an ordinary SQL NULL value to everything other than ++** [sqlite3_value_pointer()]. ++** + ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer + ** for the [prepared statement] or with a prepared statement for which + ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +@@ -3819,6 +3828,7 @@ int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); + int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, + void(*)(void*), unsigned char encoding); + int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); ++int sqlite3_bind_pointer(sqlite3_stmt*, int, void*); + int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); + +@@ -4588,6 +4598,11 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), + ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces + ** extract UTF-16 strings as big-endian and little-endian respectively. + ** ++** ^If [sqlite3_value] object V was initialized ++** using [sqlite3_bind_pointer(S,I,P)] or [sqlite3_result_pointer(C,P)], then ++** sqlite3_value_pointer(V) will return the pointer P. Otherwise, ++** sqlite3_value_pointer(V) returns a NULL. ++** + ** ^(The sqlite3_value_numeric_type() interface attempts to apply + ** numeric affinity to the value. This means that an attempt is + ** made to convert the value to an integer or floating point. If +@@ -4615,6 +4630,7 @@ const unsigned char *sqlite3_value_text(sqlite3_value*); + const void *sqlite3_value_text16(sqlite3_value*); + const void *sqlite3_value_text16le(sqlite3_value*); + const void *sqlite3_value_text16be(sqlite3_value*); ++void *sqlite3_value_pointer(sqlite3_value*); + int sqlite3_value_type(sqlite3_value*); + int sqlite3_value_numeric_type(sqlite3_value*); + +@@ -4627,10 +4643,6 @@ int sqlite3_value_numeric_type(sqlite3_value*); + ** information can be used to pass a limited amount of context from + ** one SQL function to another. Use the [sqlite3_result_subtype()] + ** routine to set the subtype for the return value of an SQL function. +-** +-** SQLite makes no use of subtype itself. It merely passes the subtype +-** from the result of one [application-defined SQL function] into the +-** input of another. + */ + unsigned int sqlite3_value_subtype(sqlite3_value*); + +@@ -4908,6 +4920,14 @@ typedef void (*sqlite3_destructor_type)(void*); + ** [unprotected sqlite3_value] object is required, so either + ** kind of [sqlite3_value] object can be used with this interface. + ** ++** ^The sqlite3_result_pointer(C,P) interface sets the result to an ++** SQL NULL value, just like [sqlite3_result_null(C)], except that it ++** also associates the host-language pointer P with that NULL value such ++** that the pointer can be retrieved within an ++** [application-defined SQL function] using [sqlite3_value_pointer()]. ++** This mechanism can be used to pass non-SQL values between ++** application-defined functions. ++** + ** If these routines are called from within the different thread + ** than the one containing the application-defined function that received + ** the [sqlite3_context] pointer, the results are undefined. +@@ -4931,6 +4951,7 @@ void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); + void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); + void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); + void sqlite3_result_value(sqlite3_context*, sqlite3_value*); ++void sqlite3_result_pointer(sqlite3_context*, void*); + void sqlite3_result_zeroblob(sqlite3_context*, int n); + int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); + +diff --git a/third_party/sqlite/src/src/vdbeInt.h b/third_party/sqlite/src/src/vdbeInt.h +index 989cdfd34617..69eab56bc578 100644 +--- a/third_party/sqlite/src/src/vdbeInt.h ++++ b/third_party/sqlite/src/src/vdbeInt.h +@@ -189,6 +189,7 @@ struct Mem { + double r; /* Real value used when MEM_Real is set in flags */ + i64 i; /* Integer value used when MEM_Int is set in flags */ + int nZero; /* Used when bit MEM_Zero is set in flags */ ++ void *pPtr; /* Pointer when flags=MEM_NULL and eSubtype='p' */ + FuncDef *pDef; /* Used only when flags==MEM_Agg */ + RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ + VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ +@@ -474,6 +475,7 @@ void sqlite3VdbeMemSetInt64(Mem*, i64); + #else + void sqlite3VdbeMemSetDouble(Mem*, double); + #endif ++void sqlite3VdbeMemSetPointer(Mem*, void*); + void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); + void sqlite3VdbeMemSetNull(Mem*); + void sqlite3VdbeMemSetZeroBlob(Mem*,int); +diff --git a/third_party/sqlite/src/src/vdbeapi.c b/third_party/sqlite/src/src/vdbeapi.c +index 6eb97f1d1ddb..c54490c077cd 100644 +--- a/third_party/sqlite/src/src/vdbeapi.c ++++ b/third_party/sqlite/src/src/vdbeapi.c +@@ -198,6 +198,14 @@ unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ + Mem *pMem = (Mem*)pVal; + return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); + } ++void *sqlite3_value_pointer(sqlite3_value *pVal){ ++ Mem *p = (Mem*)pVal; ++ if( (p->flags & MEM_TypeMask)==(MEM_Null|MEM_Subtype) && p->eSubtype=='p' ){ ++ return p->u.pPtr; ++ }else{ ++ return 0; ++ } ++} + const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ + return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); + } +@@ -376,6 +384,12 @@ void sqlite3_result_null(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); + } ++void sqlite3_result_pointer(sqlite3_context *pCtx, void *pPtr){ ++ Mem *pOut = pCtx->pOut; ++ assert( sqlite3_mutex_held(pOut->db->mutex) ); ++ sqlite3VdbeMemSetNull(pOut); ++ sqlite3VdbeMemSetPointer(pOut, pPtr); ++} + void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ + Mem *pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); +@@ -1361,6 +1375,16 @@ int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ + } + return rc; + } ++int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr){ ++ int rc; ++ Vdbe *p = (Vdbe*)pStmt; ++ rc = vdbeUnbind(p, i); ++ if( rc==SQLITE_OK ){ ++ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr); ++ sqlite3_mutex_leave(p->db->mutex); ++ } ++ return rc; ++} + int sqlite3_bind_text( + sqlite3_stmt *pStmt, + int i, +diff --git a/third_party/sqlite/src/src/vdbemem.c b/third_party/sqlite/src/src/vdbemem.c +index 656e19bfa890..2f7aedb32171 100644 +--- a/third_party/sqlite/src/src/vdbemem.c ++++ b/third_party/sqlite/src/src/vdbemem.c +@@ -697,6 +697,17 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ + } + } + ++/* ++** Set the value stored in *pMem should already be a NULL. ++** Also store a pointer to go with it. ++*/ ++void sqlite3VdbeMemSetPointer(Mem *pMem, void *pPtr){ ++ assert( pMem->flags==MEM_Null ); ++ pMem->flags = MEM_Null|MEM_Subtype; ++ pMem->u.pPtr = pPtr; ++ pMem->eSubtype = 'p'; ++} ++ + #ifndef SQLITE_OMIT_FLOATING_POINT + /* + ** Delete any previous value and set the value stored in *pMem to val, +diff --git a/third_party/sqlite/src/test/tabfunc01.test b/third_party/sqlite/src/test/tabfunc01.test +index dcaafa420c25..bb89aec1e706 100644 +--- a/third_party/sqlite/src/test/tabfunc01.test ++++ b/third_party/sqlite/src/test/tabfunc01.test +@@ -150,62 +150,63 @@ do_execsql_test tabfunc01-600 { + do_test tabfunc01-700 { + set PTR1 [intarray_addr 5 7 13 17 23] + db eval { +- SELECT b FROM t600, carray($PTR1,5) WHERE a=value; ++ SELECT b FROM t600, carray(inttoptr($PTR1),5) WHERE a=value; + } + } {(005) (007) (013) (017) (023)} + do_test tabfunc01-701 { + db eval { +- SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int32'); ++ SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),5,'int32'); + } + } {(005) (007) (013) (017) (023)} + do_test tabfunc01-702 { + db eval { +- SELECT b FROM t600 WHERE a IN carray($PTR1,4,'int32'); ++ SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),4,'int32'); + } + } {(005) (007) (013) (017)} + do_catchsql_test tabfunc01-710 { +- SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int33'); ++ SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),5,'int33'); + } {1 {unknown datatype: 'int33'}} + + do_test tabfunc01-720 { + set PTR2 [int64array_addr 5 7 13 17 23] + db eval { +- SELECT b FROM t600, carray($PTR2,5,'int64') WHERE a=value; ++ SELECT b FROM t600, carray(inttoptr($PTR2),5,'int64') WHERE a=value; + } + } {(005) (007) (013) (017) (023)} + do_test tabfunc01-721 { + db eval { + SELECT remember(123,$PTR2); +- SELECT value FROM carray($PTR2,5,'int64'); ++ SELECT value FROM carray(inttoptr($PTR2),5,'int64'); + } + } {123 123 7 13 17 23} + do_test tabfunc01-722 { + set PTR3 [expr {$PTR2+16}] + db eval { +- SELECT remember(987,$PTR3); +- SELECT value FROM carray($PTR2,5,'int64'); ++ SELECT remember(987,inttoptr($PTR3)); ++ SELECT value FROM carray(inttoptr($PTR2),5,'int64'); + } + } {987 123 7 987 17 23} + + do_test tabfunc01-730 { + set PTR4 [doublearray_addr 5.0 7.0 13.0 17.0 23.0] + db eval { +- SELECT b FROM t600, carray($PTR4,5,'double') WHERE a=value; ++ SELECT b FROM t600, carray(inttoptr($PTR4),5,'double') WHERE a=value; + } + } {(005) (007) (013) (017) (023)} + + do_test tabfunc01-740 { + set PTR5 [textarray_addr x5 x7 x13 x17 x23] + db eval { +- SELECT b FROM t600, carray($PTR5,5,'char*') WHERE a=trim(value,'x'); ++ SELECT b FROM t600, carray(inttoptr($PTR5),5,'char*') ++ WHERE a=trim(value,'x'); + } + } {(005) (007) (013) (017) (023)} + + do_test tabfunc01-750 { + db eval { + SELECT aa.value, bb.value, '|' +- FROM carray($PTR4,5,'double') AS aa +- JOIN carray($PTR5,5,'char*') AS bb ON aa.rowid=bb.rowid; ++ FROM carray(inttoptr($PTR4),5,'double') AS aa ++ JOIN carray(inttoptr($PTR5),5,'char*') AS bb ON aa.rowid=bb.rowid; + } + } {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |} + +-- +2.11
diff --git a/third_party/sqlite/src/ext/fts3/fts3.c b/third_party/sqlite/src/ext/fts3/fts3.c index 8277698..5d2f21d 100644 --- a/third_party/sqlite/src/ext/fts3/fts3.c +++ b/third_party/sqlite/src/ext/fts3/fts3.c
@@ -3347,9 +3347,8 @@ sqlite3_result_int64(pCtx, pCsr->iPrevId); }else if( iCol==p->nColumn ){ /* The extra column whose name is the same as the table. - ** Return a blob which is a pointer to the cursor. */ - sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); - sqlite3_result_subtype(pCtx, '3'); + ** Return a pointer to the cursor. */ + sqlite3_result_pointer(pCtx, pCsr); }else if( iCol==p->nColumn+2 && pCsr->pExpr ){ sqlite3_result_int64(pCtx, pCsr->iLangid); }else{ @@ -3561,17 +3560,13 @@ sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ - Fts3Cursor *pRet; - if( sqlite3_value_type(pVal)!=SQLITE_BLOB - || sqlite3_value_subtype(pVal)!='3' - || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *) - ){ + Fts3Cursor *pRet = (Fts3Cursor*)sqlite3_value_pointer(pVal); + if( pRet==0 ){ char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); sqlite3_result_error(pContext, zErr, -1); sqlite3_free(zErr); return SQLITE_ERROR; } - memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *)); *ppCsr = pRet; return SQLITE_OK; }
diff --git a/third_party/sqlite/src/ext/misc/carray.c b/third_party/sqlite/src/ext/misc/carray.c index 025eb5db..2fdff0cd 100644 --- a/third_party/sqlite/src/ext/misc/carray.c +++ b/third_party/sqlite/src/ext/misc/carray.c
@@ -73,7 +73,7 @@ struct carray_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ sqlite3_int64 iRowid; /* The rowid */ - sqlite3_int64 iPtr; /* Pointer to array of values */ + void* pPtr; /* Pointer to the array of values */ sqlite3_int64 iCnt; /* Number of integers in the array */ unsigned char eType; /* One of the CARRAY_type values */ }; @@ -167,7 +167,7 @@ carray_cursor *pCur = (carray_cursor*)cur; sqlite3_int64 x = 0; switch( i ){ - case CARRAY_COLUMN_POINTER: x = pCur->iPtr; break; + case CARRAY_COLUMN_POINTER: return SQLITE_OK; case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break; case CARRAY_COLUMN_CTYPE: { sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC); @@ -232,8 +232,8 @@ ){ carray_cursor *pCur = (carray_cursor *)pVtabCursor; if( idxNum ){ - pCur->iPtr = sqlite3_value_int64(argv[0]); - pCur->iCnt = sqlite3_value_int64(argv[1]); + pCur->pPtr = sqlite3_value_pointer(argv[0]); + pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0; if( idxNum<3 ){ pCur->eType = CARRAY_INT32; }else{ @@ -251,7 +251,7 @@ } } }else{ - pCur->iPtr = 0; + pCur->pPtr = 0; pCur->iCnt = 0; } pCur->iRowid = 1; @@ -345,6 +345,34 @@ 0, /* xRename */ }; +/* +** For testing purpose in the TCL test harness, we need a method for +** setting the pointer value. The inttoptr(X) SQL function accomplishes +** this. Tcl script will bind an integer to X and the inttoptr() SQL +** function will use sqlite3_result_pointer() to convert that integer into +** a pointer. +** +** This is for testing on TCL only. +*/ +#ifdef SQLITE_TEST +static void inttoptrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + void *p; + sqlite3_int64 i64; + i64 = sqlite3_value_int64(argv[0]); + if( sizeof(i64)==sizeof(p) ){ + memcpy(&p, &i64, sizeof(p)); + }else{ + int i32 = i64 & 0xffffffff; + memcpy(&p, &i32, sizeof(p)); + } + sqlite3_result_pointer(context, p); +} +#endif /* SQLITE_TEST */ + #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifdef _WIN32 @@ -359,6 +387,12 @@ SQLITE_EXTENSION_INIT2(pApi); #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_create_module(db, "carray", &carrayModule, 0); -#endif +#ifdef SQLITE_TEST + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0, + inttoptrFunc, 0, 0); + } +#endif /* SQLITE_TEST */ +#endif /* SQLITE_OMIT_VIRTUALTABLE */ return rc; }
diff --git a/third_party/sqlite/src/ext/misc/remember.c b/third_party/sqlite/src/ext/misc/remember.c index aa3eff8..587d44a 100644 --- a/third_party/sqlite/src/ext/misc/remember.c +++ b/third_party/sqlite/src/ext/misc/remember.c
@@ -44,11 +44,11 @@ sqlite3_value **argv ){ sqlite3_int64 v; - sqlite3_int64 ptr; + sqlite3_int64 *ptr; assert( argc==2 ); v = sqlite3_value_int64(argv[0]); - ptr = sqlite3_value_int64(argv[1]); - *((sqlite3_int64*)ptr) = v; + ptr = sqlite3_value_pointer(argv[1]); + if( ptr ) *ptr = v; sqlite3_result_int64(pCtx, v); }
diff --git a/third_party/sqlite/src/src/sqlite.h.in b/third_party/sqlite/src/src/sqlite.h.in index fbbf4b9f..371ae584 100644 --- a/third_party/sqlite/src/src/sqlite.h.in +++ b/third_party/sqlite/src/src/sqlite.h.in
@@ -3786,6 +3786,15 @@ ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** +** ^The sqlite3_bind_pointer(S,I,P) routine causes the I-th parameter in +** [prepared statement] S to have an SQL value of NULL, but to also be +** associated with the pointer P. +** ^The sqlite3_bind_pointer() routine can be used to pass +** host-language pointers into [application-defined SQL functions]. +** ^A parameter that is initialized using [sqlite3_bind_pointer()] appears +** to be an ordinary SQL NULL value to everything other than +** [sqlite3_value_pointer()]. +** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], @@ -3819,6 +3828,7 @@ int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_pointer(sqlite3_stmt*, int, void*); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -4588,6 +4598,11 @@ ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** +** ^If [sqlite3_value] object V was initialized +** using [sqlite3_bind_pointer(S,I,P)] or [sqlite3_result_pointer(C,P)], then +** sqlite3_value_pointer(V) will return the pointer P. Otherwise, +** sqlite3_value_pointer(V) returns a NULL. +** ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If @@ -4615,6 +4630,7 @@ const void *sqlite3_value_text16(sqlite3_value*); const void *sqlite3_value_text16le(sqlite3_value*); const void *sqlite3_value_text16be(sqlite3_value*); +void *sqlite3_value_pointer(sqlite3_value*); int sqlite3_value_type(sqlite3_value*); int sqlite3_value_numeric_type(sqlite3_value*); @@ -4627,10 +4643,6 @@ ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. -** -** SQLite makes no use of subtype itself. It merely passes the subtype -** from the result of one [application-defined SQL function] into the -** input of another. */ unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -4908,6 +4920,14 @@ ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** +** ^The sqlite3_result_pointer(C,P) interface sets the result to an +** SQL NULL value, just like [sqlite3_result_null(C)], except that it +** also associates the host-language pointer P with that NULL value such +** that the pointer can be retrieved within an +** [application-defined SQL function] using [sqlite3_value_pointer()]. +** This mechanism can be used to pass non-SQL values between +** application-defined functions. +** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. @@ -4931,6 +4951,7 @@ void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_pointer(sqlite3_context*, void*); void sqlite3_result_zeroblob(sqlite3_context*, int n); int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
diff --git a/third_party/sqlite/src/src/vdbeInt.h b/third_party/sqlite/src/src/vdbeInt.h index 989cdfd3..69eab56 100644 --- a/third_party/sqlite/src/src/vdbeInt.h +++ b/third_party/sqlite/src/src/vdbeInt.h
@@ -189,6 +189,7 @@ double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Used when bit MEM_Zero is set in flags */ + void *pPtr; /* Pointer when flags=MEM_NULL and eSubtype='p' */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ @@ -474,6 +475,7 @@ #else void sqlite3VdbeMemSetDouble(Mem*, double); #endif +void sqlite3VdbeMemSetPointer(Mem*, void*); void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); void sqlite3VdbeMemSetNull(Mem*); void sqlite3VdbeMemSetZeroBlob(Mem*,int);
diff --git a/third_party/sqlite/src/src/vdbeapi.c b/third_party/sqlite/src/src/vdbeapi.c index 6eb97f1..c54490c 100644 --- a/third_party/sqlite/src/src/vdbeapi.c +++ b/third_party/sqlite/src/src/vdbeapi.c
@@ -198,6 +198,14 @@ Mem *pMem = (Mem*)pVal; return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } +void *sqlite3_value_pointer(sqlite3_value *pVal){ + Mem *p = (Mem*)pVal; + if( (p->flags & MEM_TypeMask)==(MEM_Null|MEM_Subtype) && p->eSubtype=='p' ){ + return p->u.pPtr; + }else{ + return 0; + } +} const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } @@ -376,6 +384,12 @@ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } +void sqlite3_result_pointer(sqlite3_context *pCtx, void *pPtr){ + Mem *pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetPointer(pOut, pPtr); +} void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); @@ -1361,6 +1375,16 @@ } return rc; } +int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} int sqlite3_bind_text( sqlite3_stmt *pStmt, int i,
diff --git a/third_party/sqlite/src/src/vdbemem.c b/third_party/sqlite/src/src/vdbemem.c index 656e19bfa..2f7aedb3 100644 --- a/third_party/sqlite/src/src/vdbemem.c +++ b/third_party/sqlite/src/src/vdbemem.c
@@ -697,6 +697,17 @@ } } +/* +** Set the value stored in *pMem should already be a NULL. +** Also store a pointer to go with it. +*/ +void sqlite3VdbeMemSetPointer(Mem *pMem, void *pPtr){ + assert( pMem->flags==MEM_Null ); + pMem->flags = MEM_Null|MEM_Subtype; + pMem->u.pPtr = pPtr; + pMem->eSubtype = 'p'; +} + #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Delete any previous value and set the value stored in *pMem to val,
diff --git a/third_party/sqlite/src/test/tabfunc01.test b/third_party/sqlite/src/test/tabfunc01.test index dcaafa42..bb89aec 100644 --- a/third_party/sqlite/src/test/tabfunc01.test +++ b/third_party/sqlite/src/test/tabfunc01.test
@@ -150,62 +150,63 @@ do_test tabfunc01-700 { set PTR1 [intarray_addr 5 7 13 17 23] db eval { - SELECT b FROM t600, carray($PTR1,5) WHERE a=value; + SELECT b FROM t600, carray(inttoptr($PTR1),5) WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-701 { db eval { - SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int32'); + SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),5,'int32'); } } {(005) (007) (013) (017) (023)} do_test tabfunc01-702 { db eval { - SELECT b FROM t600 WHERE a IN carray($PTR1,4,'int32'); + SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),4,'int32'); } } {(005) (007) (013) (017)} do_catchsql_test tabfunc01-710 { - SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int33'); + SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),5,'int33'); } {1 {unknown datatype: 'int33'}} do_test tabfunc01-720 { set PTR2 [int64array_addr 5 7 13 17 23] db eval { - SELECT b FROM t600, carray($PTR2,5,'int64') WHERE a=value; + SELECT b FROM t600, carray(inttoptr($PTR2),5,'int64') WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-721 { db eval { SELECT remember(123,$PTR2); - SELECT value FROM carray($PTR2,5,'int64'); + SELECT value FROM carray(inttoptr($PTR2),5,'int64'); } } {123 123 7 13 17 23} do_test tabfunc01-722 { set PTR3 [expr {$PTR2+16}] db eval { - SELECT remember(987,$PTR3); - SELECT value FROM carray($PTR2,5,'int64'); + SELECT remember(987,inttoptr($PTR3)); + SELECT value FROM carray(inttoptr($PTR2),5,'int64'); } } {987 123 7 987 17 23} do_test tabfunc01-730 { set PTR4 [doublearray_addr 5.0 7.0 13.0 17.0 23.0] db eval { - SELECT b FROM t600, carray($PTR4,5,'double') WHERE a=value; + SELECT b FROM t600, carray(inttoptr($PTR4),5,'double') WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-740 { set PTR5 [textarray_addr x5 x7 x13 x17 x23] db eval { - SELECT b FROM t600, carray($PTR5,5,'char*') WHERE a=trim(value,'x'); + SELECT b FROM t600, carray(inttoptr($PTR5),5,'char*') + WHERE a=trim(value,'x'); } } {(005) (007) (013) (017) (023)} do_test tabfunc01-750 { db eval { SELECT aa.value, bb.value, '|' - FROM carray($PTR4,5,'double') AS aa - JOIN carray($PTR5,5,'char*') AS bb ON aa.rowid=bb.rowid; + FROM carray(inttoptr($PTR4),5,'double') AS aa + JOIN carray(inttoptr($PTR5),5,'char*') AS bb ON aa.rowid=bb.rowid; } } {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |}
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 0e6abe6..18ecefa 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -103,9 +103,6 @@ 'Browser Side Navigation Linux': 'release_bot', 'CFI Linux CF': 'cfi_full_cfi_diag_recover_release_static', 'CFI Linux ToT': 'cfi_full_clang_tot_release_static', - 'CFI Linux': 'cfi_release_static', - 'CFI Linux Full': 'cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on_goma', - 'CFI ThinLTO Linux ToT': 'cfi_thin_lto_clang_tot_full_symbols_release_static_use_lld', 'Chromium Linux Goma Canary': 'release_bot', 'Chromium Linux Goma Canary': 'release_bot', 'Chromium Linux Goma Canary (clobber)': 'release_bot', @@ -187,8 +184,6 @@ 'MD Top Chrome ChromeOS non-material': 'chromeos_with_codecs_debug_bot', 'MD Top Chrome Win material': 'debug_bot_minimal_symbols', 'MD Top Chrome Linux material': 'debug_bot', - 'LTO Linux': 'official_goma_thin_lto_use_lld', - 'LTO Linux Perf': 'official_goma_thin_lto_use_lld', 'Libfuzzer Upload Linux ASan': 'release_libfuzzer_asan', 'Libfuzzer Upload Linux ASan Debug': 'debug_libfuzzer_asan', 'Libfuzzer Upload Linux MSan': 'release_libfuzzer_msan', @@ -999,14 +994,6 @@ 'cfi_full', 'cfi_diag', 'thin_lto', 'release', 'static', 'dcheck_always_on', 'goma', ], - 'cfi_release_static': [ - 'cfi', 'release', 'static', - ], - - 'cfi_thin_lto_clang_tot_full_symbols_release_static_use_lld': [ - 'cfi', 'thin_lto', 'clang_tot', 'full_symbols', 'release', 'static', 'use_lld', - ], - 'chrome_with_codecs_blink_logging_release_trybot': [ 'chrome_with_codecs', 'blink_logging', 'release_trybot', ], @@ -1364,10 +1351,6 @@ 'official', 'goma', 'chromeos', ], - 'official_goma_thin_lto_use_lld': [ - 'official', 'goma', 'thin_lto', 'use_lld', - ], - 'official_goma_minimal_symbols_android': [ 'official', 'goma', 'minimal_symbols', 'android', ], @@ -1615,13 +1598,8 @@ 'gn_args': 'is_cast_audio_only=true enable_webrtc=false' }, - 'cfi': { - 'gn_args': 'is_cfi=true', - }, - 'cfi_full': { - 'gn_args': 'use_cfi_cast=true', - 'mixins': ['cfi'], + 'gn_args': 'is_cfi=true use_cfi_cast=true', }, 'cfi_diag': {
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 0457c56e..561132c 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -31686,7 +31686,7 @@ </summary> </histogram> -<histogram name="MediaRouter.Source.FileFormat" enum="MediaContainers"> +<histogram name="MediaRouter.Source.LocalFileFormat" enum="MediaContainers"> <owner>paezagon@chromium.org</owner> <summary> The file format of a local media Media Router session. This is recorded when @@ -31695,6 +31695,16 @@ </summary> </histogram> +<histogram name="MediaRouter.Source.LocalFileSize" units="MB"> + <owner>paezagon@chromium.org</owner> + <summary> + The file size of a local media Media Router session. This is recorded when a + casting session begins to keep track of what kind of media is being + streamed, specifically, whether it is a clip or a song, or a full length + film or podcast. + </summary> +</histogram> + <histogram name="MediaRouter.Ui.Action.CloseLatency" units="ms"> <owner>apacible@chromium.org</owner> <summary> @@ -92754,6 +92764,7 @@ label="in-document existing page renderer-initiated navigation"/> <suffix name="ExistingPageDifferentDocumentRendererInitiated" label="existing page renderer-initiated navigation"/> + <suffix name="SamePage" label="same page navigation"/> <suffix name="NewSubFrame" label="new subframe navigation"/> <affected-histogram name="Navigation.SecureSchemeHasSSLStatus"/> </histogram_suffixes>
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 9752d21a..80e436e1 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -582,7 +582,14 @@ return result -def generate_telemetry_test(swarming_dimensions, benchmark_name, browser): +BENCHMARKS_TO_UPLOAD_TO_FLAKINESS_DASHBOARD = ['system_health.common_desktop', + 'system_health.common_mobile', + 'system_health.memory_desktop', + 'system_health.memory_mobile'] + + +def generate_telemetry_test(swarming_dimensions, + benchmark_name, browser, for_fyi_waterfall=False): # The step name must end in 'test' or 'tests' in order for the # results to automatically show up on the flakiness dashboard. # (At least, this was true some time ago.) Continue to use this @@ -598,6 +605,10 @@ # When this is enabled on more than just windows machines we will need # --device=android + if (for_fyi_waterfall and + benchmark_name in BENCHMARKS_TO_UPLOAD_TO_FLAKINESS_DASHBOARD): + test_args.append('--output-format=json-test-results') + ignore_task_failure = False step_name = benchmark_name if browser == 'reference': @@ -672,7 +683,8 @@ def generate_telemetry_tests(name, tester_config, benchmarks, benchmark_sharding_map, - benchmark_ref_build_blacklist): + benchmark_ref_build_blacklist, + for_fyi_waterfall=False): isolated_scripts = [] # First determine the browser that you need based on the tester browser_name = '' @@ -709,7 +721,7 @@ dimension, device)) test = generate_telemetry_test( - swarming_dimensions, benchmark.Name(), browser_name) + swarming_dimensions, benchmark.Name(), browser_name, for_fyi_waterfall) isolated_scripts.append(test) # Now create another executable for this benchmark on the reference browser # if it is not blacklisted from running on the reference browser. @@ -717,7 +729,7 @@ if not tester_config.get('replace_system_webview', False) and ( benchmark.Name() not in benchmark_ref_build_blacklist): reference_test = generate_telemetry_test( - swarming_dimensions, benchmark.Name(),'reference') + swarming_dimensions, benchmark.Name(),'reference', for_fyi_waterfall) isolated_scripts.append(reference_test) return isolated_scripts @@ -792,7 +804,7 @@ # Generate benchmarks isolated_scripts = generate_telemetry_tests( name, config, all_benchmarks, benchmark_sharding_map, - BENCHMARK_REF_BUILD_BLACKLIST) + BENCHMARK_REF_BUILD_BLACKLIST, waterfall['name']=='chromium.perf.fyi') # Generate swarmed non-telemetry tests if present if config['swarming_dimensions'][0].get('perf_tests', False): isolated_scripts += generate_cplusplus_isolate_script_test(
diff --git a/tools/perf/core/perf_data_generator_unittest.py b/tools/perf/core/perf_data_generator_unittest.py index 786e3fe3..d30afe16e 100644 --- a/tools/perf/core/perf_data_generator_unittest.py +++ b/tools/perf/core/perf_data_generator_unittest.py
@@ -148,6 +148,28 @@ '--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk']) self.assertEquals(test['isolate_name'], 'telemetry_perf_webview_tests') + def testGenerateTelemetryTestsWithUploadToFlakinessDashboard(self): + swarming_dimensions = [{'os': 'SkyNet', 'id': 'T-850', 'pool': 'T-RIP'}] + test = perf_data_generator.generate_telemetry_test( + swarming_dimensions, 'system_health.common_desktop', 'release', True) + expected_generated_test = { + 'override_compile_targets': ['telemetry_perf_tests'], + 'args': ['system_health.common_desktop', '-v', '--upload-results', + '--output-format=chartjson', '--browser=release', + '--output-format=json-test-results'], + 'swarming': { + 'ignore_task_failure': False, + 'dimension_sets': [{'os': 'SkyNet', 'id': 'T-850', 'pool': 'T-RIP'}], + 'hard_timeout': 10800, + 'can_use_on_swarming_builders': True, + 'expiration': 36000, + 'io_timeout': 3600, + }, + 'name': 'system_health.common_desktop', + 'isolate_name': 'telemetry_perf_tests', + } + self.assertEquals(test, expected_generated_test) + def testGenerateTelemetryTestsBlacklistedReferenceBuildTest(self): class BlacklistedBenchmark(benchmark.Benchmark): @classmethod
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc index 0bf08b5..e5197e7 100644 --- a/ui/android/delegated_frame_host_android.cc +++ b/ui/android/delegated_frame_host_android.cc
@@ -65,7 +65,7 @@ DCHECK(view_); DCHECK(client_); - frame_sink_manager_->RegisterFrameSinkId(frame_sink_id_); + frame_sink_manager_->surface_manager()->RegisterFrameSinkId(frame_sink_id_); CreateNewCompositorFrameSinkSupport(); } @@ -73,7 +73,7 @@ DestroyDelegatedContent(); DetachFromCompositor(); support_.reset(); - frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id_); + frame_sink_manager_->surface_manager()->InvalidateFrameSinkId(frame_sink_id_); } void DelegatedFrameHostAndroid::SubmitCompositorFrame(
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc index 4cefb83..d97a15dc 100644 --- a/ui/app_list/app_list_constants.cc +++ b/ui/app_list/app_list_constants.cc
@@ -127,6 +127,9 @@ const int kSearchBoxTopPadding = 24; const int kSearchBoxBottomPadding = 21; +// The preferred height of the search box. +const int kSearchBoxPreferredHeight = 48; + // The background border corner radius of the search box in fullscreen mode. const int kSearchBoxBorderCornerRadiusFullscreen = 24; @@ -161,7 +164,7 @@ "Apps.AppListSearchResultDistanceFromOrigin"; // The height of tiles in search result. -const int kSearchTileHeight = 90; +const int kSearchTileHeight = 92; // The size of the search icon in the search box. const int kSearchIconSize = 24;
diff --git a/ui/app_list/app_list_constants.h b/ui/app_list/app_list_constants.h index 3f8cddb..36d0be2 100644 --- a/ui/app_list/app_list_constants.h +++ b/ui/app_list/app_list_constants.h
@@ -96,6 +96,7 @@ APP_LIST_EXPORT extern const int kSearchBoxPadding; APP_LIST_EXPORT extern const int kSearchBoxTopPadding; APP_LIST_EXPORT extern const int kSearchBoxBottomPadding; +APP_LIST_EXPORT extern const int kSearchBoxPreferredHeight; APP_LIST_EXPORT extern const int kSearchBoxBorderCornerRadiusFullscreen; APP_LIST_EXPORT extern size_t kMaxFolderItems;
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index da134c66..9d9a5bb 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -846,12 +846,9 @@ // Make sure to layout |app_list_main_view_| and |speech_view_| at the // center of the widget. gfx::Rect centered_bounds = contents_bounds; - ContentsView* contents_view = app_list_main_view_->contents_view(); - centered_bounds.ClampToCenteredSize( - gfx::Size(is_fullscreen_app_list_enabled_ - ? contents_view->GetMaximumContentsSize().width() - : contents_view->GetDefaultContentsBounds().width(), - contents_bounds.height())); + centered_bounds.ClampToCenteredSize(gfx::Size( + app_list_main_view_->contents_view()->GetDefaultContentsBounds().width(), + contents_bounds.height())); app_list_main_view_->SetBoundsRect(centered_bounds); @@ -866,7 +863,7 @@ } if (is_fullscreen_app_list_enabled_) { - contents_view->Layout(); + app_list_main_view_->contents_view()->Layout(); app_list_background_shield_->SetBoundsRect(contents_bounds); } }
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc index d58e40c..23a4465 100644 --- a/ui/app_list/views/contents_view.cc +++ b/ui/app_list/views/contents_view.cc
@@ -372,8 +372,8 @@ gfx::Rect search_box_bounds; if (is_fullscreen_app_list_enabled_) { search_box_bounds.set_size(GetSearchBoxView()->GetPreferredSize()); - search_box_bounds.Offset((bounds().width() - search_box_bounds.width()) / 2, - 0); + search_box_bounds.Offset( + (GetDefaultContentsSize().width() - search_box_bounds.width()) / 2, 0); search_box_bounds.set_y(kSearchBoxTopPadding); } else { search_box_bounds = @@ -392,24 +392,12 @@ } gfx::Rect ContentsView::GetDefaultContentsBounds() const { - gfx::Size contents_size(GetDefaultContentsSize()); - gfx::Point origin(0, GetDefaultSearchBoxBounds().bottom()); - if (is_fullscreen_app_list_enabled_) { - origin.Offset((bounds().width() - contents_size.width()) / 2, - kSearchBoxBottomPadding); - } - return gfx::Rect(origin, contents_size); -} - -gfx::Size ContentsView::GetMaximumContentsSize() const { - int max_width = 0; - int max_height = 0; - for (AppListPage* page : app_list_pages_) { - gfx::Size size(page->GetPreferredSize()); - max_width = std::max(size.width(), max_width); - max_height = std::max(size.height(), max_height); - } - return gfx::Size(max_width, max_height); + gfx::Rect bounds(gfx::Point(0, GetDefaultSearchBoxBounds().bottom() + + (is_fullscreen_app_list_enabled_ + ? kSearchBoxBottomPadding + : 0)), + GetDefaultContentsSize()); + return bounds; } bool ContentsView::Back() {
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h index e723e55..277a09460 100644 --- a/ui/app_list/views/contents_view.h +++ b/ui/app_list/views/contents_view.h
@@ -119,9 +119,6 @@ // specify their own custom layout. gfx::Rect GetDefaultContentsBounds() const; - // Returns the maximum preferred size of the all pages. - gfx::Size GetMaximumContentsSize() const; - // Performs the 'back' action for the active page. Returns whether the action // was handled. bool Back();
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index 38127c3..bfd701e 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -52,7 +52,6 @@ constexpr int kInnerPadding = 24; constexpr int kPreferredWidth = 360; constexpr int kPreferredWidthFullscreen = 544; -constexpr int kSearchBoxPreferredHeight = 48; constexpr SkColor kHintTextColor = SkColorSetARGBMacro(0xFF, 0xA0, 0xA0, 0xA0);
diff --git a/ui/app_list/views/search_result_list_view.cc b/ui/app_list/views/search_result_list_view.cc index 7370eded..1f820a44 100644 --- a/ui/app_list/views/search_result_list_view.cc +++ b/ui/app_list/views/search_result_list_view.cc
@@ -11,7 +11,6 @@ #include "base/message_loop/message_loop.h" #include "base/time/time.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/app_list/app_list_features.h" #include "ui/app_list/app_list_switches.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/search_result.h" @@ -25,11 +24,10 @@ namespace { -constexpr int kMaxResults = 6; -constexpr int kMaxResultsFullscreen = 5; -constexpr int kTimeoutIndicatorHeight = 2; -constexpr int kTimeoutFramerate = 60; -constexpr SkColor kTimeoutIndicatorColor = SkColorSetRGB(30, 144, 255); +const int kMaxResults = 6; +const int kTimeoutIndicatorHeight = 2; +const int kTimeoutFramerate = 60; +const SkColor kTimeoutIndicatorColor = SkColorSetRGB(30, 144, 255); } // namespace @@ -45,10 +43,7 @@ results_container_->SetLayoutManager( new views::BoxLayout(views::BoxLayout::kVertical)); - int max_results = features::IsFullscreenAppListEnabled() - ? kMaxResultsFullscreen - : kMaxResults; - for (int i = 0; i < max_results; ++i) + for (int i = 0; i < kMaxResults; ++i) results_container_->AddChildView(new SearchResultView(this)); AddChildView(results_container_);
diff --git a/ui/app_list/views/search_result_page_view.cc b/ui/app_list/views/search_result_page_view.cc index 20aa7566..92162c4d 100644 --- a/ui/app_list/views/search_result_page_view.cc +++ b/ui/app_list/views/search_result_page_view.cc
@@ -34,7 +34,6 @@ constexpr int kGroupSpacing = 6; constexpr int kTopPadding = 8; constexpr int kFullscreenHeight = 440; -constexpr int kFullscreenWidth = 640; // The z-height of the search box and cards in this view. constexpr int kSearchResultZHeight = 1; @@ -43,9 +42,6 @@ constexpr int kSeparatorPadding = 12; constexpr int kSeparatorThickness = 1; -// The height of the search box in this page. -constexpr int kSearchBoxHeight = 56; - constexpr SkColor kSeparatorColor = SkColorSetARGBMacro(0x1F, 0x00, 0x00, 0x00); // A container view that ensures the card background and the shadow are painted @@ -96,7 +92,7 @@ canvas->DrawRoundRect(bounds, corner_radius_, flags); // Draws a separator between SearchBoxView and SearchResultPageView. - bounds.set_y(kSearchBoxHeight); + bounds.set_y(kSearchBoxPreferredHeight); bounds.set_height(kSeparatorThickness); canvas->FillRect(bounds, kSeparatorColor); } @@ -168,7 +164,7 @@ if (is_fullscreen_app_list_enabled_) { // Leaves a placeholder area for the search box and the separator below it. scroller->SetBorder(views::CreateEmptyBorder( - gfx::Insets(kSearchBoxHeight + kSeparatorThickness, 0, 0, 0))); + gfx::Insets(kSearchBoxPreferredHeight + kSeparatorThickness, 0, 0, 0))); } scroller->SetContents(contents_view_); // Setting clip height is necessary to make ScrollView take into account its @@ -249,12 +245,6 @@ return "SearchResultPageView"; } -gfx::Size SearchResultPageView::CalculatePreferredSize() const { - if (!is_fullscreen_app_list_enabled_) - return GetDefaultContentsBounds().size(); - return gfx::Size(kFullscreenWidth, kFullscreenHeight); -} - void SearchResultPageView::ClearSelectedIndex() { if (HasSelection()) result_container_views_[selected_index_]->ClearSelectedIndex(); @@ -369,9 +359,9 @@ return AppListPage::GetSearchBoxBounds(); } - gfx::Rect onscreen_bounds(AppListPage::GetSearchBoxBounds()); - onscreen_bounds.Offset((onscreen_bounds.width() - kFullscreenWidth) / 2, 0); - onscreen_bounds.set_size(GetPreferredSize()); + gfx::Rect onscreen_bounds(GetDefaultContentsBounds()); + onscreen_bounds.set_y(AppListPage::GetSearchBoxBounds().y()); + onscreen_bounds.set_height(kFullscreenHeight); return onscreen_bounds; } @@ -419,8 +409,9 @@ gfx::Rect SearchResultPageView::GetSearchBoxBounds() const { gfx::Rect rect(AppListPage::GetSearchBoxBounds()); if (is_fullscreen_app_list_enabled_) { - rect.Offset((rect.width() - kFullscreenWidth) / 2, 0); - rect.set_size(gfx::Size(kFullscreenWidth, kSearchBoxHeight)); + gfx::Rect contents_bounds(GetDefaultContentsBounds()); + rect.set_x(contents_bounds.x()); + rect.set_width(contents_bounds.width()); } return rect; }
diff --git a/ui/app_list/views/search_result_page_view.h b/ui/app_list/views/search_result_page_view.h index c60e900..238eb707 100644 --- a/ui/app_list/views/search_result_page_view.h +++ b/ui/app_list/views/search_result_page_view.h
@@ -39,7 +39,6 @@ // Overridden from views::View: bool OnKeyPressed(const ui::KeyEvent& event) override; const char* GetClassName() const override; - gfx::Size CalculatePreferredSize() const override; // AppListPage overrides: gfx::Rect GetPageBoundsForState(AppListModel::State state) const override;
diff --git a/ui/aura/mus/DEPS b/ui/aura/mus/DEPS index c447b50..2f08e4b 100644 --- a/ui/aura/mus/DEPS +++ b/ui/aura/mus/DEPS
@@ -11,6 +11,7 @@ "+cc/surfaces/surface_reference_factory.h", "+components/discardable_memory/client/client_discardable_shared_memory_manager.h", "+components/viz/client", + "+components/viz/common/gpu", "+gpu/command_buffer/client/gpu_memory_buffer_manager.h", "+gpu/ipc/client/gpu_channel_host.h", "+mojo/public/cpp/system/buffer.h",
diff --git a/ui/aura/mus/mus_context_factory.cc b/ui/aura/mus/mus_context_factory.cc index bfe06f3..2b6e28d 100644 --- a/ui/aura/mus/mus_context_factory.cc +++ b/ui/aura/mus/mus_context_factory.cc
@@ -67,7 +67,7 @@ weak_ptr_factory_.GetWeakPtr(), compositor)); } -scoped_refptr<cc::ContextProvider> +scoped_refptr<viz::ContextProvider> MusContextFactory::SharedMainThreadContextProvider() { if (!shared_main_thread_context_provider_) { scoped_refptr<gpu::GpuChannelHost> gpu_channel =
diff --git a/ui/aura/mus/mus_context_factory.h b/ui/aura/mus/mus_context_factory.h index 4c84377b..e675b61 100644 --- a/ui/aura/mus/mus_context_factory.h +++ b/ui/aura/mus/mus_context_factory.h
@@ -10,9 +10,9 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "cc/output/context_provider.h" #include "cc/output/renderer_settings.h" #include "cc/surfaces/surface_manager.h" +#include "components/viz/common/gpu/context_provider.h" #include "services/ui/public/cpp/raster_thread_helper.h" #include "services/ui/public/interfaces/window_tree.mojom.h" #include "ui/aura/aura_export.h" @@ -46,7 +46,8 @@ // ContextFactory: void CreateLayerTreeFrameSink( base::WeakPtr<ui::Compositor> compositor) override; - scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider() override; + scoped_refptr<viz::ContextProvider> SharedMainThreadContextProvider() + override; void RemoveCompositor(ui::Compositor* compositor) override; double GetRefreshRate() const override; gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override; @@ -58,7 +59,7 @@ ui::RasterThreadHelper raster_thread_helper_; ui::Gpu* gpu_; const cc::RendererSettings renderer_settings_; - scoped_refptr<cc::ContextProvider> shared_main_thread_context_provider_; + scoped_refptr<viz::ContextProvider> shared_main_thread_context_provider_; base::WeakPtrFactory<MusContextFactory> weak_ptr_factory_;
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc index 3a7adaf..4915a5e 100644 --- a/ui/aura/mus/window_port_mus.cc +++ b/ui/aura/mus/window_port_mus.cc
@@ -105,7 +105,7 @@ std::unique_ptr<viz::ClientLayerTreeFrameSink> WindowPortMus::RequestLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) { cc::mojom::CompositorFrameSinkPtrInfo sink_info; cc::mojom::CompositorFrameSinkRequest sink_request =
diff --git a/ui/aura/mus/window_port_mus.h b/ui/aura/mus/window_port_mus.h index 9311c812..68936714 100644 --- a/ui/aura/mus/window_port_mus.h +++ b/ui/aura/mus/window_port_mus.h
@@ -90,7 +90,7 @@ const ui::mojom::WindowTree::EmbedCallback& callback); std::unique_ptr<viz::ClientLayerTreeFrameSink> RequestLayerTreeFrameSink( - scoped_refptr<cc::ContextProvider> context_provider, + scoped_refptr<viz::ContextProvider> context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager); private:
diff --git a/ui/base/cocoa/touch_bar_util.h b/ui/base/cocoa/touch_bar_util.h index d35d50f..94e0852b 100644 --- a/ui/base/cocoa/touch_bar_util.h +++ b/ui/base/cocoa/touch_bar_util.h
@@ -7,6 +7,7 @@ #import <Cocoa/Cocoa.h> +#include "base/mac/availability.h" #include "ui/base/ui_base_export.h" namespace ui { @@ -19,6 +20,15 @@ // Returns a stylized blue button for the touch bar. The button performs // |action| from the |target|. +// The __attribute__ visibility annotation is necessary to work around a clang +// bug: https://bugs.llvm.org/show_bug.cgi?id=33796. +#if defined(UI_BASE_IMPLEMENTATION) && defined(COMPONENT_BUILD) +// UI_BASE_EXPORT specifies "default" visibility. +API_AVAILABLE(macosx(10.12.2)) +#else +API_AVAILABLE(macosx(10.12.2)) +__attribute__((visibility("hidden"))) +#endif UI_BASE_EXPORT NSButton* GetBlueTouchBarButton(NSString* title, id target, SEL action);
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index b80e735..fb127d2 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -28,11 +28,11 @@ #include "cc/input/input_handler.h" #include "cc/layers/layer.h" #include "cc/output/begin_frame_args.h" -#include "cc/output/context_provider.h" #include "cc/output/latency_info_swap_promise.h" #include "cc/scheduler/begin_frame_source.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/quads/resource_format.h" #include "components/viz/common/resources/resource_settings.h" #include "components/viz/common/surfaces/local_surface_id_allocator.h" @@ -69,8 +69,9 @@ weak_ptr_factory_(this), lock_timeout_weak_ptr_factory_(this) { if (context_factory_private) { - context_factory_private->GetFrameSinkManager()->RegisterFrameSinkId( - frame_sink_id_); + context_factory_private->GetFrameSinkManager() + ->surface_manager() + ->RegisterFrameSinkId(frame_sink_id_); } root_web_layer_ = cc::Layer::Create(); @@ -217,7 +218,7 @@ DCHECK(client.is_valid()); manager->UnregisterFrameSinkHierarchy(frame_sink_id_, client); } - manager->InvalidateFrameSinkId(frame_sink_id_); + manager->surface_manager()->InvalidateFrameSinkId(frame_sink_id_); } }
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index 3664ff58..12e8f3637 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -40,7 +40,6 @@ namespace cc { class AnimationHost; class AnimationTimeline; -class ContextProvider; class Layer; class LayerTreeDebugState; class LayerTreeFrameSink; @@ -60,6 +59,7 @@ namespace viz { class FrameSinkManager; +class ContextProvider; class HostFrameSinkManager; class LocalSurfaceId; class ResourceSettings; @@ -80,7 +80,7 @@ public: virtual ~ContextFactoryObserver() {} - // Notifies that the ContextProvider returned from + // Notifies that the viz::ContextProvider returned from // ui::ContextFactory::SharedMainThreadContextProvider was lost. When this // is called, the old resources (e.g. shared context, GL helper) still // exist, but are about to be destroyed. Getting a reference to those @@ -153,7 +153,7 @@ // Return a reference to a shared offscreen context provider usable from the // main thread. - virtual scoped_refptr<cc::ContextProvider> + virtual scoped_refptr<viz::ContextProvider> SharedMainThreadContextProvider() = 0; // Destroys per-compositor data.
diff --git a/ui/compositor/test/DEPS b/ui/compositor/test/DEPS index b8b2938..c827f173 100644 --- a/ui/compositor/test/DEPS +++ b/ui/compositor/test/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/viz/common/gpu", "+components/viz/service/display", "+components/viz/service/frame_sinks", "+gpu/command_buffer/client",
diff --git a/ui/compositor/test/fake_context_factory.cc b/ui/compositor/test/fake_context_factory.cc index 73be3539..3417eeea 100644 --- a/ui/compositor/test/fake_context_factory.cc +++ b/ui/compositor/test/fake_context_factory.cc
@@ -52,7 +52,7 @@ compositor->SetLayerTreeFrameSink(std::move(frame_sink)); } -scoped_refptr<cc::ContextProvider> +scoped_refptr<viz::ContextProvider> FakeContextFactory::SharedMainThreadContextProvider() { return nullptr; }
diff --git a/ui/compositor/test/fake_context_factory.h b/ui/compositor/test/fake_context_factory.h index a69a1fc..8a29767 100644 --- a/ui/compositor/test/fake_context_factory.h +++ b/ui/compositor/test/fake_context_factory.h
@@ -12,13 +12,16 @@ namespace cc { class CompositorFrame; -class ContextProvider; class FakeLayerTreeFrameSink; class ResourceSettings; class TestTaskGraphRunner; class TestGpuMemoryBufferManager; } +namespace viz { +class ContextProvider; +} + namespace ui { class FakeContextFactory : public ui::ContextFactory { @@ -31,7 +34,8 @@ // ui::ContextFactory: void CreateLayerTreeFrameSink( base::WeakPtr<ui::Compositor> compositor) override; - scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider() override; + scoped_refptr<viz::ContextProvider> SharedMainThreadContextProvider() + override; void RemoveCompositor(ui::Compositor* compositor) override; double GetRefreshRate() const override; gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc index b36a7ac..c3630a7 100644 --- a/ui/compositor/test/in_process_context_factory.cc +++ b/ui/compositor/test/in_process_context_factory.cc
@@ -12,13 +12,13 @@ #include "base/memory/ptr_util.h" #include "base/threading/thread.h" #include "cc/base/switches.h" -#include "cc/output/context_provider.h" #include "cc/output/output_surface_client.h" #include "cc/output/output_surface_frame.h" #include "cc/output/texture_mailbox_deleter.h" #include "cc/scheduler/begin_frame_source.h" #include "cc/scheduler/delay_based_time_source.h" #include "cc/test/pixel_test_output_surface.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/local_surface_id_allocator.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/display/display.h" @@ -271,7 +271,7 @@ void InProcessContextFactory::RemoveReflector(Reflector* reflector) { } -scoped_refptr<cc::ContextProvider> +scoped_refptr<viz::ContextProvider> InProcessContextFactory::SharedMainThreadContextProvider() { if (shared_main_thread_contexts_ && shared_main_thread_contexts_->ContextGL()->GetGraphicsResetStatusKHR() ==
diff --git a/ui/compositor/test/in_process_context_factory.h b/ui/compositor/test/in_process_context_factory.h index 53be48be..aed33b5 100644 --- a/ui/compositor/test/in_process_context_factory.h +++ b/ui/compositor/test/in_process_context_factory.h
@@ -63,7 +63,8 @@ Layer* mirroring_layer) override; void RemoveReflector(Reflector* reflector) override; - scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider() override; + scoped_refptr<viz::ContextProvider> SharedMainThreadContextProvider() + override; void RemoveCompositor(Compositor* compositor) override; double GetRefreshRate() const override; gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
diff --git a/ui/compositor/test/in_process_context_provider.cc b/ui/compositor/test/in_process_context_provider.cc index 45ce6fc..ef4918a 100644 --- a/ui/compositor/test/in_process_context_provider.cc +++ b/ui/compositor/test/in_process_context_provider.cc
@@ -11,8 +11,8 @@ #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" -#include "cc/output/context_cache_controller.h" #include "cc/output/managed_memory_policy.h" +#include "components/viz/common/gpu/context_cache_controller.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/client/gles2_lib.h" #include "gpu/command_buffer/client/shared_memory_limits.h" @@ -96,7 +96,7 @@ if (!context_) return false; - cache_controller_.reset(new cc::ContextCacheController( + cache_controller_.reset(new viz::ContextCacheController( context_->GetImplementation(), base::ThreadTaskRunnerHandle::Get())); } @@ -142,7 +142,7 @@ return gr_context_->get(); } -cc::ContextCacheController* InProcessContextProvider::CacheController() { +viz::ContextCacheController* InProcessContextProvider::CacheController() { DCHECK(context_thread_checker_.CalledOnValidThread()); return cache_controller_.get(); }
diff --git a/ui/compositor/test/in_process_context_provider.h b/ui/compositor/test/in_process_context_provider.h index 2d2501f4..2fced24 100644 --- a/ui/compositor/test/in_process_context_provider.h +++ b/ui/compositor/test/in_process_context_provider.h
@@ -13,7 +13,7 @@ #include "base/macros.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" -#include "cc/output/context_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/ipc/common/surface_handle.h" #include "ui/gfx/native_widget_types.h" @@ -30,7 +30,7 @@ namespace ui { -class InProcessContextProvider : public cc::ContextProvider { +class InProcessContextProvider : public viz::ContextProvider { public: static scoped_refptr<InProcessContextProvider> Create( const gpu::gles2::ContextCreationAttribHelper& attribs, @@ -53,7 +53,7 @@ gpu::gles2::GLES2Interface* ContextGL() override; gpu::ContextSupport* ContextSupport() override; class GrContext* GrContext() override; - cc::ContextCacheController* CacheController() override; + viz::ContextCacheController* CacheController() override; void InvalidateGrContext(uint32_t state) override; base::Lock* GetLock() override; void SetLostContextCallback( @@ -78,7 +78,7 @@ std::unique_ptr<gpu::GLInProcessContext> context_; std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_; - std::unique_ptr<cc::ContextCacheController> cache_controller_; + std::unique_ptr<viz::ContextCacheController> cache_controller_; gpu::gles2::ContextCreationAttribHelper attribs_; InProcessContextProvider* shared_context_;
diff --git a/ui/events/test/device_data_manager_test_api.h b/ui/events/test/device_data_manager_test_api.h index a9d009c..92d26a3 100644 --- a/ui/events/test/device_data_manager_test_api.h +++ b/ui/events/test/device_data_manager_test_api.h
@@ -6,6 +6,7 @@ #define UI_EVENTS_TEST_DEVICE_DATA_MANAGER_TEST_API_H_ #include <memory> +#include <vector> #include "base/macros.h" #include "ui/events/devices/events_devices_export.h" @@ -14,6 +15,8 @@ class DeviceDataManager; enum class StylusState; +struct InputDevice; +struct TouchscreenDevice; namespace test { @@ -34,6 +37,13 @@ void NotifyObserversStylusStateChanged(StylusState stylus_state); void OnDeviceListsComplete(); + // Methods for updating DeviceDataManager's device lists. Notify* methods must + // be invoked separately to notify observers after making changes. + void SetTouchscreenDevices(const std::vector<TouchscreenDevice>& devices); + void SetKeyboardDevices(const std::vector<InputDevice>& devices); + void SetMouseDevices(const std::vector<InputDevice>& devices); + void SetTouchpadDevices(const std::vector<InputDevice>& devices); + private: DISALLOW_COPY_AND_ASSIGN(DeviceDataManagerTestAPI); };
diff --git a/ui/events/test/device_data_manager_test_api_impl.cc b/ui/events/test/device_data_manager_test_api_impl.cc index 2f37366a..58fbde5 100644 --- a/ui/events/test/device_data_manager_test_api_impl.cc +++ b/ui/events/test/device_data_manager_test_api_impl.cc
@@ -53,5 +53,25 @@ DeviceDataManager::GetInstance()->OnDeviceListsComplete(); } +void DeviceDataManagerTestAPI::SetTouchscreenDevices( + const std::vector<TouchscreenDevice>& devices) { + DeviceDataManager::GetInstance()->touchscreen_devices_ = devices; +} + +void DeviceDataManagerTestAPI::SetKeyboardDevices( + const std::vector<InputDevice>& devices) { + DeviceDataManager::GetInstance()->keyboard_devices_ = devices; +} + +void DeviceDataManagerTestAPI::SetMouseDevices( + const std::vector<InputDevice>& devices) { + DeviceDataManager::GetInstance()->mouse_devices_ = devices; +} + +void DeviceDataManagerTestAPI::SetTouchpadDevices( + const std::vector<InputDevice>& devices) { + DeviceDataManager::GetInstance()->touchpad_devices_ = devices; +} + } // namespace test } // namespace ui
diff --git a/ui/events/test/device_data_manager_test_api_stub.cc b/ui/events/test/device_data_manager_test_api_stub.cc index fa8ae97..a16b05f 100644 --- a/ui/events/test/device_data_manager_test_api_stub.cc +++ b/ui/events/test/device_data_manager_test_api_stub.cc
@@ -48,5 +48,25 @@ NOTREACHED(); } +void DeviceDataManagerTestAPI::SetTouchscreenDevices( + const std::vector<TouchscreenDevice>& devices) { + NOTREACHED(); +} + +void DeviceDataManagerTestAPI::SetKeyboardDevices( + const std::vector<InputDevice>& devices) { + NOTREACHED(); +} + +void DeviceDataManagerTestAPI::SetMouseDevices( + const std::vector<InputDevice>& devices) { + NOTREACHED(); +} + +void DeviceDataManagerTestAPI::SetTouchpadDevices( + const std::vector<InputDevice>& devices) { + NOTREACHED(); +} + } // namespace test } // namespace ui
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index e369ae8..e579efd7 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -522,6 +522,7 @@ "native_pixmap.h", "native_pixmap_handle.cc", "native_pixmap_handle.h", + "overlay_transform.h", ] if (!is_ios) {
diff --git a/ui/gfx/mojo/BUILD.gn b/ui/gfx/mojo/BUILD.gn index 7a90efb..9722968c 100644 --- a/ui/gfx/mojo/BUILD.gn +++ b/ui/gfx/mojo/BUILD.gn
@@ -10,6 +10,7 @@ "buffer_types.mojom", "color_space.mojom", "icc_profile.mojom", + "overlay_transform.mojom", "selection_bound.mojom", "transform.mojom", ]
diff --git a/ui/gfx/mojo/overlay_transform.mojom b/ui/gfx/mojo/overlay_transform.mojom new file mode 100644 index 0000000..af64e362 --- /dev/null +++ b/ui/gfx/mojo/overlay_transform.mojom
@@ -0,0 +1,17 @@ +// 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. + +module gfx.mojom; + +// gfx::OverlayTransform +enum OverlayTransform { + OVERLAY_TRANSFORM_INVALID, + OVERLAY_TRANSFORM_NONE, + OVERLAY_TRANSFORM_FLIP_HORIZONTAL, + OVERLAY_TRANSFORM_FLIP_VERTICAL, + OVERLAY_TRANSFORM_ROTATE_90, + OVERLAY_TRANSFORM_ROTATE_180, + OVERLAY_TRANSFORM_ROTATE_270, + OVERLAY_TRANSFORM_LAST = OVERLAY_TRANSFORM_ROTATE_270 +};
diff --git a/ui/gfx/mojo/overlay_transform.typemap b/ui/gfx/mojo/overlay_transform.typemap new file mode 100644 index 0000000..8dd9e1b --- /dev/null +++ b/ui/gfx/mojo/overlay_transform.typemap
@@ -0,0 +1,11 @@ +# 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. + +mojom = "//ui/gfx/mojo/overlay_transform.mojom" +public_headers = [ "//ui/gfx/overlay_transform.h" ] +traits_headers = [ "//ui/gfx/mojo/overlay_transform_struct_traits.h" ] +public_deps = [ + "//ui/gfx", +] +type_mappings = [ "gfx.mojom.OverlayTransform=gfx::OverlayTransform" ]
diff --git a/ui/gfx/mojo/overlay_transform_struct_traits.h b/ui/gfx/mojo/overlay_transform_struct_traits.h new file mode 100644 index 0000000..e26f2db4 --- /dev/null +++ b/ui/gfx/mojo/overlay_transform_struct_traits.h
@@ -0,0 +1,68 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_MOJO_OVERLAY_TRANSFORM_STRUCT_TRAITS_H_ +#define UI_GFX_MOJO_OVERLAY_TRANSFORM_STRUCT_TRAITS_H_ + +#include "ui/gfx/mojo/overlay_transform.mojom.h" +#include "ui/gfx/overlay_transform.h" + +namespace mojo { + +template <> +struct EnumTraits<gfx::mojom::OverlayTransform, gfx::OverlayTransform> { + static gfx::mojom::OverlayTransform ToMojom(gfx::OverlayTransform format) { + switch (format) { + case gfx::OverlayTransform::OVERLAY_TRANSFORM_INVALID: + return gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_INVALID; + case gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE: + return gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_NONE; + case gfx::OverlayTransform::OVERLAY_TRANSFORM_FLIP_HORIZONTAL: + return gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_FLIP_HORIZONTAL; + case gfx::OverlayTransform::OVERLAY_TRANSFORM_FLIP_VERTICAL: + return gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_FLIP_VERTICAL; + case gfx::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_90: + return gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_90; + case gfx::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_180: + return gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_180; + case gfx::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_270: + return gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_270; + } + NOTREACHED(); + return gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_INVALID; + } + + static bool FromMojom(gfx::mojom::OverlayTransform input, + gfx::OverlayTransform* out) { + switch (input) { + case gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_INVALID: + *out = gfx::OverlayTransform::OVERLAY_TRANSFORM_INVALID; + return true; + case gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_NONE: + *out = gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE; + return true; + case gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_FLIP_HORIZONTAL: + *out = gfx::OverlayTransform::OVERLAY_TRANSFORM_FLIP_HORIZONTAL; + return true; + case gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_FLIP_VERTICAL: + *out = gfx::OverlayTransform::OVERLAY_TRANSFORM_FLIP_VERTICAL; + return true; + case gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_90: + *out = gfx::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_90; + return true; + case gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_180: + *out = gfx::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_180; + return true; + case gfx::mojom::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_270: + *out = gfx::OverlayTransform::OVERLAY_TRANSFORM_ROTATE_270; + return true; + } + NOTREACHED(); + return false; + } +}; + +} // namespace mojo + +#endif // UI_GFX_MOJO_OVERLAY_TRANSFORM_STRUCT_TRAITS_H_
diff --git a/ui/gfx/typemaps.gni b/ui/gfx/typemaps.gni index d86ae08..375f74db 100644 --- a/ui/gfx/typemaps.gni +++ b/ui/gfx/typemaps.gni
@@ -9,6 +9,7 @@ "//ui/gfx/mojo/buffer_types.typemap", "//ui/gfx/mojo/color_space.typemap", "//ui/gfx/mojo/icc_profile.typemap", + "//ui/gfx/mojo/overlay_transform.typemap", "//ui/gfx/mojo/selection_bound.typemap", "//ui/gfx/mojo/transform.typemap", "//ui/gfx/range/mojo/range.typemap",
diff --git a/ui/ozone/BUILD.gn b/ui/ozone/BUILD.gn index 5047e94a..815c785 100644 --- a/ui/ozone/BUILD.gn +++ b/ui/ozone/BUILD.gn
@@ -65,6 +65,8 @@ "public/overlay_candidates_ozone.cc", "public/overlay_candidates_ozone.h", "public/overlay_manager_ozone.h", + "public/overlay_surface_candidate.cc", + "public/overlay_surface_candidate.h", "public/ozone_switches.cc", "public/ozone_switches.h", "public/surface_factory_ozone.cc", @@ -97,8 +99,9 @@ # things that would otherwise create a cycle. "//ui/base", "//ui/events/ozone/*", - "//ui/ozone/platform/*", "//ui/ozone/common/*", + "//ui/ozone/public/interfaces", + "//ui/ozone/platform/*", ] } @@ -145,7 +148,6 @@ deps = [ ":generate_constructor_list", ":generate_ozone_platform_list", - "//ui/ozone/public/interfaces", ] deps += ozone_platform_deps @@ -162,6 +164,7 @@ visibility = [ "*" ] public_deps = [ ":platform", + "//ui/ozone/public/interfaces", ] } @@ -211,15 +214,14 @@ } test("ozone_unittests") { - sources = [ - "run_all_unittests.cc", - ] - deps = [ "//base/test:test_support", + "//mojo/edk/test:run_all_unittests", + "//mojo/public/cpp/bindings", "//testing/gtest", "//ui/gfx:test_support", "//ui/gfx/geometry", + "//ui/ozone/public/interfaces:struct_trait_unit_test", ] # Add tests of platform internals.
diff --git a/ui/ozone/DEPS b/ui/ozone/DEPS index 1ac3a7a..bcaff46e 100644 --- a/ui/ozone/DEPS +++ b/ui/ozone/DEPS
@@ -10,3 +10,8 @@ "+ui/gl", "+ui/platform_window", ] +specific_include_rules = { + "run_all_unittests\.cc": [ + "+mojo/edk/embedder/embedder.h", + ], +}
diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.cc b/ui/ozone/common/gpu/ozone_gpu_message_params.cc index 7924ee0..29692cac 100644 --- a/ui/ozone/common/gpu/ozone_gpu_message_params.cc +++ b/ui/ozone/common/gpu/ozone_gpu_message_params.cc
@@ -7,16 +7,15 @@ #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/ipc/gfx_param_traits.h" #include "ui/gfx/ipc/skia/gfx_skia_param_traits.h" +#include "ui/ozone/public/overlay_surface_candidate.h" namespace ui { -DisplayMode_Params::DisplayMode_Params() { -} +DisplayMode_Params::DisplayMode_Params() {} DisplayMode_Params::~DisplayMode_Params() {} -DisplaySnapshot_Params::DisplaySnapshot_Params() { -} +DisplaySnapshot_Params::DisplaySnapshot_Params() {} DisplaySnapshot_Params::DisplaySnapshot_Params( const DisplaySnapshot_Params& other) = default; @@ -26,7 +25,7 @@ OverlayCheck_Params::OverlayCheck_Params() {} OverlayCheck_Params::OverlayCheck_Params( - const OverlayCandidatesOzone::OverlaySurfaceCandidate& candidate) + const ui::OverlaySurfaceCandidate& candidate) : buffer_size(candidate.buffer_size), transform(candidate.transform), format(candidate.format), @@ -37,8 +36,7 @@ OverlayCheck_Params::OverlayCheck_Params(const OverlayCheck_Params& other) = default; -OverlayCheck_Params::~OverlayCheck_Params() { -} +OverlayCheck_Params::~OverlayCheck_Params() {} bool OverlayCheck_Params::operator<(const OverlayCheck_Params& param) const { int lwidth = buffer_size.width();
diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.h b/ui/ozone/common/gpu/ozone_gpu_message_params.h index 0d2e8e3..0ad90a8 100644 --- a/ui/ozone/common/gpu/ozone_gpu_message_params.h +++ b/ui/ozone/common/gpu/ozone_gpu_message_params.h
@@ -19,6 +19,7 @@ #include "ui/ozone/public/overlay_candidates_ozone.h" namespace ui { +class OverlaySurfaceCandidate; struct DisplayMode_Params { DisplayMode_Params(); @@ -56,8 +57,7 @@ struct OverlayCheck_Params { OverlayCheck_Params(); - OverlayCheck_Params( - const OverlayCandidatesOzone::OverlaySurfaceCandidate& candidate); + OverlayCheck_Params(const OverlaySurfaceCandidate& candidate); OverlayCheck_Params(const OverlayCheck_Params& other); ~OverlayCheck_Params();
diff --git a/ui/ozone/demo/surfaceless_gl_renderer.cc b/ui/ozone/demo/surfaceless_gl_renderer.cc index 549c7ac..7930d017 100644 --- a/ui/ozone/demo/surfaceless_gl_renderer.cc +++ b/ui/ozone/demo/surfaceless_gl_renderer.cc
@@ -131,7 +131,7 @@ gfx::RectF display_rect(bounds_rect.x(), bounds_rect.y(), bounds_rect.width(), bounds_rect.height()); - OverlayCandidatesOzone::OverlaySurfaceCandidate overlay_candidate; + OverlaySurfaceCandidate overlay_candidate; // The bounds rectangle of the candidate overlay buffer. overlay_candidate.buffer_size = bounds_rect.size();
diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.cc b/ui/ozone/platform/drm/host/drm_overlay_manager.cc index 9d5a968..b03f6f3e 100644 --- a/ui/ozone/platform/drm/host/drm_overlay_manager.cc +++ b/ui/ozone/platform/drm/host/drm_overlay_manager.cc
@@ -15,13 +15,13 @@ #include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h" #include "ui/ozone/platform/drm/host/drm_window_host.h" #include "ui/ozone/platform/drm/host/drm_window_host_manager.h" +#include "ui/ozone/public/overlay_surface_candidate.h" #include "ui/ozone/public/ozone_switches.h" namespace ui { -typedef OverlayCandidatesOzone::OverlaySurfaceCandidateList - OverlaySurfaceCandidateList; -typedef OverlayCandidatesOzone::OverlaySurfaceCandidate OverlaySurfaceCandidate; +using OverlaySurfaceCandidateList = + OverlayCandidatesOzone::OverlaySurfaceCandidateList; namespace { const size_t kMaxCacheSize = 200;
diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.h b/ui/ozone/platform/drm/host/drm_overlay_manager.h index 6e5a0ac..de51495 100644 --- a/ui/ozone/platform/drm/host/drm_overlay_manager.h +++ b/ui/ozone/platform/drm/host/drm_overlay_manager.h
@@ -17,6 +17,7 @@ namespace ui { class DrmWindowHostManager; +class OverlaySurfaceCandidate; class DrmOverlayManager : public OverlayManagerOzone { public: @@ -48,9 +49,8 @@ void SendOverlayValidationRequest( const std::vector<OverlayCheck_Params>& new_params, gfx::AcceleratedWidget widget) const; - bool CanHandleCandidate( - const OverlayCandidatesOzone::OverlaySurfaceCandidate& candidate, - gfx::AcceleratedWidget widget) const; + bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate, + gfx::AcceleratedWidget widget) const; GpuThreadAdapter* proxy_; // Not owned. DrmWindowHostManager* window_manager_; // Not owned.
diff --git a/ui/ozone/public/interfaces/BUILD.gn b/ui/ozone/public/interfaces/BUILD.gn index 7c9d6e9..48221f51 100644 --- a/ui/ozone/public/interfaces/BUILD.gn +++ b/ui/ozone/public/interfaces/BUILD.gn
@@ -7,11 +7,7 @@ mojom("interfaces") { sources = [ "device_cursor.mojom", - ] - - import_dirs = [ - get_path_info("../../../..", "abspath"), - "//mojo/services", + "overlay_surface_candidate.mojom", ] public_deps = [ @@ -20,3 +16,32 @@ "//ui/gfx/mojo", ] } + +source_set("struct_traits") { + sources = [ + "overlay_surface_candidate_struct_traits.h", + ] + deps = [ + "//ui/gfx/geometry/mojo:mojo", + "//ui/gfx/mojo:mojo", + ] + public_deps = [ + ":interfaces", + ":interfaces_shared_cpp_sources", + "//mojo/public/cpp/bindings", + ] +} + +source_set("struct_trait_unit_test") { + testonly = true + + sources = [ + "overlay_surface_candidate_struct_traits_unittest.cc", + ] + + deps = [ + ":interfaces", + "//testing/gtest", + "//ui/gfx/geometry", + ] +}
diff --git a/ui/ozone/public/interfaces/DEPS b/ui/ozone/public/interfaces/DEPS new file mode 100644 index 0000000..ef8ad28 --- /dev/null +++ b/ui/ozone/public/interfaces/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+mojo/public", +]
diff --git a/ui/ozone/public/interfaces/OWNERS b/ui/ozone/public/interfaces/OWNERS index 08850f4..2c44a46 100644 --- a/ui/ozone/public/interfaces/OWNERS +++ b/ui/ozone/public/interfaces/OWNERS
@@ -1,2 +1,6 @@ per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_struct_traits*.*=set noparent +per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/ui/ozone/public/interfaces/overlay_surface_candidate.mojom b/ui/ozone/public/interfaces/overlay_surface_candidate.mojom new file mode 100644 index 0000000..4903dce6 --- /dev/null +++ b/ui/ozone/public/interfaces/overlay_surface_candidate.mojom
@@ -0,0 +1,37 @@ +// 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. + +module ui.ozone.mojom; + +import "ui/gfx/geometry/mojo/geometry.mojom"; +import "ui/gfx/mojo/buffer_types.mojom"; +import "ui/gfx/mojo/overlay_transform.mojom"; + +struct OverlaySurfaceCandidate { + // Transformation to apply to layer during composition. + gfx.mojom.OverlayTransform transform; + // Format of the buffer to composite. + gfx.mojom.BufferFormat format; + // Size of the buffer, in pixels. + gfx.mojom.Size buffer_size; + // Rect on the display to position the overlay to. Input rectangle may + // not have integer coordinates, but when accepting for overlay, must + // be modified by CheckOverlaySupport to output integer values. + gfx.mojom.RectF display_rect; + // Crop within the buffer to be placed inside |display_rect|. + gfx.mojom.RectF crop_rect; + // Quad geometry rect after applying the quad_transform(). + gfx.mojom.Rect quad_rect_in_target_space; + // Clip rect in the target content space after composition. + gfx.mojom.Rect clip_rect; + // If the quad is clipped after composition. + bool is_clipped; + // Stacking order of the overlay plane relative to the main surface, + // which is 0. Signed to allow for "underlays". + int32 plane_z_order = 0; + + // To be modified by the implementer if this candidate can go into + // an overlay. + bool overlay_handled; +};
diff --git a/ui/ozone/public/interfaces/overlay_surface_candidate.typemap b/ui/ozone/public/interfaces/overlay_surface_candidate.typemap new file mode 100644 index 0000000..6c9f347 --- /dev/null +++ b/ui/ozone/public/interfaces/overlay_surface_candidate.typemap
@@ -0,0 +1,13 @@ +# 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. + +mojom = "//ui/ozone/public/interfaces/overlay_surface_candidate.mojom" +public_headers = [ "//ui/ozone/public/overlay_surface_candidate.h" ] +public_deps = [ + "//ui/ozone:ozone_base", +] +traits_headers = + [ "//ui/ozone/public/interfaces/overlay_surface_candidate_struct_traits.h" ] +type_mappings = + [ "ui.ozone.mojom.OverlaySurfaceCandidate=ui::OverlaySurfaceCandidate" ]
diff --git a/ui/ozone/public/interfaces/overlay_surface_candidate_struct_traits.h b/ui/ozone/public/interfaces/overlay_surface_candidate_struct_traits.h new file mode 100644 index 0000000..53c26839 --- /dev/null +++ b/ui/ozone/public/interfaces/overlay_surface_candidate_struct_traits.h
@@ -0,0 +1,80 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PUBLIC_INTERFACES_OVERLAY_SURFACE_CANDIDATE_STRUCT_TRAITS_H_ +#define UI_OZONE_PUBLIC_INTERFACES_OVERLAY_SURFACE_CANDIDATE_STRUCT_TRAITS_H_ + +#include "ui/gfx/geometry/mojo/geometry_struct_traits.h" +#include "ui/gfx/mojo/buffer_types_struct_traits.h" +#include "ui/gfx/mojo/overlay_transform_struct_traits.h" +#include "ui/ozone/public/interfaces/overlay_surface_candidate.mojom.h" +#include "ui/ozone/public/overlay_surface_candidate.h" + +namespace mojo { + +template <> +struct StructTraits<ui::ozone::mojom::OverlaySurfaceCandidateDataView, + ui::OverlaySurfaceCandidate> { + static const gfx::OverlayTransform& transform( + const ui::OverlaySurfaceCandidate& osc) { + return osc.transform; + } + + static const gfx::BufferFormat& format( + const ui::OverlaySurfaceCandidate& osc) { + return osc.format; + } + + static const gfx::Size& buffer_size(const ui::OverlaySurfaceCandidate& osc) { + return osc.buffer_size; + } + + static const gfx::RectF& display_rect( + const ui::OverlaySurfaceCandidate& osc) { + return osc.display_rect; + } + + static const gfx::RectF& crop_rect(const ui::OverlaySurfaceCandidate& osc) { + return osc.crop_rect; + } + + static const gfx::Rect& quad_rect_in_target_space( + const ui::OverlaySurfaceCandidate& osc) { + return osc.quad_rect_in_target_space; + } + + static const gfx::Rect& clip_rect(const ui::OverlaySurfaceCandidate& osc) { + return osc.clip_rect; + } + + static bool is_clipped(const ui::OverlaySurfaceCandidate& osc) { + return osc.is_clipped; + } + + static int plane_z_order(const ui::OverlaySurfaceCandidate& osc) { + return osc.plane_z_order; + } + + static bool overlay_handled(const ui::OverlaySurfaceCandidate& osc) { + return osc.overlay_handled; + } + + static bool Read(ui::ozone::mojom::OverlaySurfaceCandidateDataView data, + ui::OverlaySurfaceCandidate* out) { + out->is_clipped = data.is_clipped(); + out->plane_z_order = data.plane_z_order(); + out->overlay_handled = data.overlay_handled(); + return data.ReadTransform(&out->transform) && + data.ReadFormat(&out->format) && + data.ReadBufferSize(&out->buffer_size) && + data.ReadDisplayRect(&out->display_rect) && + data.ReadCropRect(&out->crop_rect) && + data.ReadQuadRectInTargetSpace(&out->quad_rect_in_target_space) && + data.ReadClipRect(&out->clip_rect); + } +}; + +} // namespace mojo + +#endif // UI_OZONE_PUBLIC_INTERFACES_OVERLAY_SURFACE_CANDIDATE_STRUCT_TRAITS_H_
diff --git a/ui/ozone/public/interfaces/overlay_surface_candidate_struct_traits_unittest.cc b/ui/ozone/public/interfaces/overlay_surface_candidate_struct_traits_unittest.cc new file mode 100644 index 0000000..8ec1fd0c --- /dev/null +++ b/ui/ozone/public/interfaces/overlay_surface_candidate_struct_traits_unittest.cc
@@ -0,0 +1,73 @@ +// 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 <utility> + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/point.h" +#include "ui/ozone/public/interfaces/overlay_surface_candidate.mojom.h" +#include "ui/ozone/public/interfaces/overlay_surface_candidate_struct_traits.h" +#include "ui/ozone/public/overlay_surface_candidate.h" + +namespace ui { + +namespace { + +class OverlaySurfaceCandidateStructTraitsTest : public testing::Test { + public: + OverlaySurfaceCandidateStructTraitsTest() {} +}; + +} // namespace + +TEST_F(OverlaySurfaceCandidateStructTraitsTest, FieldsEqual) { + ui::OverlaySurfaceCandidate input; + + input.transform = gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL; + input.format = gfx::BufferFormat::YUV_420_BIPLANAR; + input.buffer_size = gfx::Size(6, 7); + input.display_rect = gfx::RectF(1., 2., 3., 4.); + input.crop_rect = gfx::RectF(10., 20., 30., 40.); + input.quad_rect_in_target_space = gfx::Rect(101, 201, 301, 401); + input.clip_rect = gfx::Rect(11, 21, 31, 41); + input.is_clipped = true; + input.plane_z_order = 42; + input.overlay_handled = true; + + ui::OverlaySurfaceCandidate output; + + bool success = ui::ozone::mojom::OverlaySurfaceCandidate::Deserialize( + ui::ozone::mojom::OverlaySurfaceCandidate::Serialize(&input), &output); + + EXPECT_TRUE(success); + + EXPECT_EQ(input.transform, output.transform); + EXPECT_EQ(input.format, output.format); + EXPECT_EQ(input.buffer_size, output.buffer_size); + EXPECT_EQ(input.display_rect, output.display_rect); + EXPECT_EQ(input.crop_rect, output.crop_rect); + EXPECT_EQ(input.quad_rect_in_target_space, output.quad_rect_in_target_space); + EXPECT_EQ(input.clip_rect, output.clip_rect); + EXPECT_EQ(input.is_clipped, output.is_clipped); + EXPECT_EQ(input.plane_z_order, output.plane_z_order); + EXPECT_EQ(input.overlay_handled, output.overlay_handled); +} + +TEST_F(OverlaySurfaceCandidateStructTraitsTest, FalseBools) { + ui::OverlaySurfaceCandidate input; + + input.is_clipped = false; + input.overlay_handled = false; + + ui::OverlaySurfaceCandidate output; + + bool success = ui::ozone::mojom::OverlaySurfaceCandidate::Deserialize( + ui::ozone::mojom::OverlaySurfaceCandidate::Serialize(&input), &output); + + EXPECT_TRUE(success); + EXPECT_EQ(input.is_clipped, output.is_clipped); + EXPECT_EQ(input.overlay_handled, output.overlay_handled); +} + +} // namespace ui
diff --git a/ui/ozone/public/interfaces/typemaps.gni b/ui/ozone/public/interfaces/typemaps.gni new file mode 100644 index 0000000..860a0b3 --- /dev/null +++ b/ui/ozone/public/interfaces/typemaps.gni
@@ -0,0 +1,5 @@ +# 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. + +typemaps = [ "//ui/ozone/public/interfaces/overlay_surface_candidate.typemap" ]
diff --git a/ui/ozone/public/overlay_candidates_ozone.cc b/ui/ozone/public/overlay_candidates_ozone.cc index d6fdc00..e6cc3c8 100644 --- a/ui/ozone/public/overlay_candidates_ozone.cc +++ b/ui/ozone/public/overlay_candidates_ozone.cc
@@ -8,21 +8,11 @@ namespace ui { -OverlayCandidatesOzone::OverlaySurfaceCandidate::OverlaySurfaceCandidate() - : is_clipped(false) {} - -OverlayCandidatesOzone::OverlaySurfaceCandidate::OverlaySurfaceCandidate( - const OverlaySurfaceCandidate& other) = default; - -OverlayCandidatesOzone::OverlaySurfaceCandidate::~OverlaySurfaceCandidate() { -} - void OverlayCandidatesOzone::CheckOverlaySupport( OverlaySurfaceCandidateList* surfaces) { NOTREACHED(); } -OverlayCandidatesOzone::~OverlayCandidatesOzone() { -} +OverlayCandidatesOzone::~OverlayCandidatesOzone() {} } // namespace ui
diff --git a/ui/ozone/public/overlay_candidates_ozone.h b/ui/ozone/public/overlay_candidates_ozone.h index 6637e865..760721fee 100644 --- a/ui/ozone/public/overlay_candidates_ozone.h +++ b/ui/ozone/public/overlay_candidates_ozone.h
@@ -7,12 +7,8 @@ #include <vector> -#include "ui/gfx/buffer_types.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/rect_f.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/overlay_transform.h" #include "ui/ozone/ozone_base_export.h" +#include "ui/ozone/public/overlay_surface_candidate.h" namespace ui { @@ -21,38 +17,6 @@ // class from SurfaceFactoryOzone given an AcceleratedWidget. class OZONE_BASE_EXPORT OverlayCandidatesOzone { public: - struct OverlaySurfaceCandidate { - OverlaySurfaceCandidate(); - OverlaySurfaceCandidate(const OverlaySurfaceCandidate& other); - ~OverlaySurfaceCandidate(); - - // Transformation to apply to layer during composition. - gfx::OverlayTransform transform = gfx::OVERLAY_TRANSFORM_NONE; - // Format of the buffer to composite. - gfx::BufferFormat format = gfx::BufferFormat::BGRA_8888; - // Size of the buffer, in pixels. - gfx::Size buffer_size; - // Rect on the display to position the overlay to. Input rectangle may - // not have integer coordinates, but when accepting for overlay, must - // be modified by CheckOverlaySupport to output integer values. - gfx::RectF display_rect; - // Crop within the buffer to be placed inside |display_rect|. - gfx::RectF crop_rect; - // Quad geometry rect after applying the quad_transform(). - gfx::Rect quad_rect_in_target_space; - // Clip rect in the target content space after composition. - gfx::Rect clip_rect; - // If the quad is clipped after composition. - bool is_clipped; - // Stacking order of the overlay plane relative to the main surface, - // which is 0. Signed to allow for "underlays". - int plane_z_order = 0; - - // To be modified by the implementer if this candidate can go into - // an overlay. - bool overlay_handled = false; - }; - typedef std::vector<OverlaySurfaceCandidate> OverlaySurfaceCandidateList; // A list of possible overlay candidates is presented to this function.
diff --git a/ui/ozone/public/overlay_surface_candidate.cc b/ui/ozone/public/overlay_surface_candidate.cc new file mode 100644 index 0000000..3612d21 --- /dev/null +++ b/ui/ozone/public/overlay_surface_candidate.cc
@@ -0,0 +1,16 @@ +// 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 "ui/ozone/public/overlay_surface_candidate.h" + +namespace ui { + +OverlaySurfaceCandidate::OverlaySurfaceCandidate() : is_clipped(false) {} + +OverlaySurfaceCandidate::OverlaySurfaceCandidate( + const OverlaySurfaceCandidate& other) = default; + +OverlaySurfaceCandidate::~OverlaySurfaceCandidate() {} + +} // namespace ui
diff --git a/ui/ozone/public/overlay_surface_candidate.h b/ui/ozone/public/overlay_surface_candidate.h new file mode 100644 index 0000000..349ec1bd --- /dev/null +++ b/ui/ozone/public/overlay_surface_candidate.h
@@ -0,0 +1,52 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PUBLIC_OVERLAY_SURFACE_CANDIDATE_H_ +#define UI_OZONE_PUBLIC_OVERLAY_SURFACE_CANDIDATE_H_ + +#include "ui/gfx/buffer_types.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/overlay_transform.h" +#include "ui/ozone/ozone_base_export.h" + +namespace ui { + +class OZONE_BASE_EXPORT OverlaySurfaceCandidate { + public: + OverlaySurfaceCandidate(); + OverlaySurfaceCandidate(const OverlaySurfaceCandidate& other); + ~OverlaySurfaceCandidate(); + + // Transformation to apply to layer during composition. + gfx::OverlayTransform transform = gfx::OVERLAY_TRANSFORM_NONE; + // Format of the buffer to composite. + gfx::BufferFormat format = gfx::BufferFormat::BGRA_8888; + // Size of the buffer, in pixels. + gfx::Size buffer_size; + // Rect on the display to position the overlay to. Input rectangle may + // not have integer coordinates, but when accepting for overlay, must + // be modified by CheckOverlaySupport to output integer values. + gfx::RectF display_rect; + // Crop within the buffer to be placed inside |display_rect|. + gfx::RectF crop_rect; + // Quad geometry rect after applying the quad_transform(). + gfx::Rect quad_rect_in_target_space; + // Clip rect in the target content space after composition. + gfx::Rect clip_rect; + // If the quad is clipped after composition. + bool is_clipped; + // Stacking order of the overlay plane relative to the main surface, + // which is 0. Signed to allow for "underlays". + int plane_z_order = 0; + + // To be modified by the implementer if this candidate can go into + // an overlay. + bool overlay_handled = false; +}; + +} // namespace ui + +#endif // UI_OZONE_PUBLIC_OVERLAY_SURFACE_CANDIDATE_H_ \ No newline at end of file
diff --git a/ui/ozone/run_all_unittests.cc b/ui/ozone/run_all_unittests.cc deleted file mode 100644 index 9f2ad71..0000000 --- a/ui/ozone/run_all_unittests.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/bind.h" -#include "base/macros.h" -#include "base/test/launcher/unit_test_launcher.h" -#include "base/test/test_suite.h" -#include "build/build_config.h" - -namespace { - -class OzoneTestSuite : public base::TestSuite { - public: - OzoneTestSuite(int argc, char** argv); - - protected: - // base::TestSuite: - void Initialize() override; - void Shutdown() override; - - private: - DISALLOW_COPY_AND_ASSIGN(OzoneTestSuite); -}; - -OzoneTestSuite::OzoneTestSuite(int argc, char** argv) - : base::TestSuite(argc, argv) {} - -void OzoneTestSuite::Initialize() { - base::TestSuite::Initialize(); -} - -void OzoneTestSuite::Shutdown() { - base::TestSuite::Shutdown(); -} - -} // namespace - -int main(int argc, char** argv) { - OzoneTestSuite test_suite(argc, argv); - - return base::LaunchUnitTests(argc, - argv, - base::Bind(&OzoneTestSuite::Run, - base::Unretained(&test_suite))); -}
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 0fc7e281e..e9125d6 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -627,7 +627,17 @@ SetSelection(part.menu ? part.menu : state_.item, SELECTION_OPEN_SUBMENU); } } else if (part.type == MenuPart::NONE) { - ShowSiblingMenu(source, event.location()); + // If there is a sibling menu, show it. Otherwise, if the user has selected + // a menu item with no accompanying sibling menu or submenu, move selection + // back to the parent menu item. + if (!ShowSiblingMenu(source, event.location())) { + if (!part.is_scroll() && pending_state_.item && + pending_state_.item->GetParentMenuItem() && + !pending_state_.item->SubmenuIsShowing()) { + SetSelection(pending_state_.item->GetParentMenuItem(), + SELECTION_OPEN_SUBMENU); + } + } } UpdateActiveMouseView(source, event, mouse_menu); @@ -1329,8 +1339,7 @@ case ui::VKEY_ESCAPE: if (!state_.item->GetParentMenuItem() || (!state_.item->GetParentMenuItem()->GetParentMenuItem() && - (!state_.item->HasSubmenu() || - !state_.item->GetSubmenu()->IsShowing()))) { + (!state_.item->SubmenuIsShowing()))) { // User pressed escape and current menu has no submenus. If we are // nested, close the current menu on the stack. Otherwise fully exit the // menu. @@ -1633,7 +1642,7 @@ const gfx::Point& screen_loc) { MenuPart part; for (; item; item = item->GetParentMenuItem()) { - if (item->HasSubmenu() && item->GetSubmenu()->IsShowing() && + if (item->SubmenuIsShowing() && GetMenuPartByScreenCoordinateImpl(item->GetSubmenu(), screen_loc, &part)) { return part; @@ -1764,8 +1773,7 @@ } else { state_.submenu_open = false; } - } else if (state_.item->HasSubmenu() && - state_.item->GetSubmenu()->IsShowing()) { + } else if (state_.item->SubmenuIsShowing()) { state_.item->GetSubmenu()->Hide(); } @@ -1775,7 +1783,7 @@ bool found = false; for (MenuItemView* item = state_.item; item && !found; item = item->GetParentMenuItem()) { - found = (item->HasSubmenu() && item->GetSubmenu()->IsShowing() && + found = (item->SubmenuIsShowing() && item->GetSubmenu() == scroll_task_->submenu()); } if (!found) @@ -2184,8 +2192,7 @@ SelectionIncrementDirectionType direction) { MenuItemView* item = pending_state_.item; DCHECK(item); - if (pending_state_.submenu_open && item->HasSubmenu() && - item->GetSubmenu()->IsShowing()) { + if (pending_state_.submenu_open && item->SubmenuIsShowing()) { // A menu is selected and open, but none of its children are selected, // select the first menu item that is visible and enabled. if (item->GetSubmenu()->GetMenuItemCount()) { @@ -2278,7 +2285,7 @@ DCHECK(item); if (!item->GetParentMenuItem()) return; - if (item->HasSubmenu() && item->GetSubmenu()->IsShowing()) + if (item->SubmenuIsShowing()) SetSelection(item, SELECTION_UPDATE_IMMEDIATELY); else if (item->GetParentMenuItem()->GetParentMenuItem()) SetSelection(item->GetParentMenuItem(), SELECTION_UPDATE_IMMEDIATELY); @@ -2346,7 +2353,7 @@ base::char16 char_array[] = { character, 0 }; base::char16 key = base::i18n::ToLower(char_array)[0]; MenuItemView* item = pending_state_.item; - if (!item->HasSubmenu() || !item->GetSubmenu()->IsShowing()) + if (!item->SubmenuIsShowing()) item = item->GetParentMenuItem(); DCHECK(item); DCHECK(item->HasSubmenu()); @@ -2672,8 +2679,7 @@ SetSelection(part.menu, SELECTION_OPEN_SUBMENU); } else if (!part.is_scroll() && pending_state_.item && pending_state_.item->GetParentMenuItem() && - (!pending_state_.item->HasSubmenu() || - !pending_state_.item->GetSubmenu()->IsShowing())) { + !pending_state_.item->SubmenuIsShowing()) { // On exit if the user hasn't selected an item with a submenu, move the // selection back to the parent menu item. SetSelection(pending_state_.item->GetParentMenuItem(),
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc index 7608aeae..c5aa7ab 100644 --- a/ui/views/controls/menu/menu_controller_unittest.cc +++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -1417,6 +1417,47 @@ EXPECT_EQ(menu_controller_delegate(), GetCurrentDelegate()); } +// Drag the mouse from an external view into a menu +// When the mouse leaves the menu while still in the process of dragging +// the menu item view highlight should turn off +TEST_F(MenuControllerTest, DragFromViewIntoMenuAndExit) { + SubmenuView* sub_menu = menu_item()->GetSubmenu(); + MenuItemView* first_item = sub_menu->GetMenuItemAt(0); + + std::unique_ptr<View> drag_view = base::MakeUnique<View>(); + drag_view->SetBoundsRect(gfx::Rect(0, 500, 100, 100)); + sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), false); + gfx::Point press_location(drag_view->bounds().CenterPoint()); + gfx::Point drag_location(first_item->bounds().CenterPoint()); + gfx::Point release_location(200, 50); + + // Begin drag on an external view + ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, press_location, + press_location, ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, 0); + drag_view->OnMousePressed(press_event); + + // Drag into a menu item + ui::MouseEvent drag_event_enter(ui::ET_MOUSE_DRAGGED, drag_location, + drag_location, ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, 0); + ProcessMouseDragged(sub_menu, drag_event_enter); + EXPECT_TRUE(first_item->IsSelected()); + + // Drag out of the menu item + ui::MouseEvent drag_event_exit(ui::ET_MOUSE_DRAGGED, release_location, + release_location, ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, 0); + ProcessMouseDragged(sub_menu, drag_event_exit); + EXPECT_FALSE(first_item->IsSelected()); + + // Complete drag with release + ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, release_location, + release_location, ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, 0); + ProcessMouseReleased(sub_menu, release_event); +} + #endif // defined(USE_AURA) } // namespace test
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index 06be5f0..905690f 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -347,6 +347,10 @@ return submenu_; } +bool MenuItemView::SubmenuIsShowing() const { + return HasSubmenu() && GetSubmenu()->IsShowing(); +} + void MenuItemView::SetTitle(const base::string16& title) { title_ = title; invalidate_dimensions(); // Triggers preferred size recalculation.
diff --git a/ui/views/controls/menu/menu_item_view.h b/ui/views/controls/menu/menu_item_view.h index c80a8db..a23101c 100644 --- a/ui/views/controls/menu/menu_item_view.h +++ b/ui/views/controls/menu/menu_item_view.h
@@ -222,6 +222,9 @@ // Returns the view containing child menu items. virtual SubmenuView* GetSubmenu() const; + // Returns true if this menu item has a submenu and it is showing + virtual bool SubmenuIsShowing() const; + // Returns the parent menu item. MenuItemView* GetParentMenuItem() { return parent_menu_item_; } const MenuItemView* GetParentMenuItem() const { return parent_menu_item_; }
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js index 8827041..016d93d7 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js
@@ -118,12 +118,14 @@ */ setOldImageUrl(imageUrl) { this.oldImageUrl_ = imageUrl; - if (imageUrl) + if (imageUrl) { this.$.selector.select(this.$.selector.indexOf(this.$.oldImage)); - else if (this.cameraSelected_) + this.selectedImageUrl_ = imageUrl; + } else if (this.cameraSelected_) { this.$.selector.select(this.$.selector.indexOf(this.$.cameraImage)); - else if (this.fallbackImage_) + } else if (this.fallbackImage_) { this.selectImage_(this.fallbackImage_, true /* activate */); + } }, /** @@ -135,6 +137,7 @@ if (!this.selectedItem || this.selectedItem.dataset.type != CrPicture.SelectionTypes.CAMERA) { this.$.selector.select(this.$.selector.indexOf(image)); + this.selectedItem = image; } },
diff --git a/ui/webui/resources/cr_elements/paper_button_style_css.html b/ui/webui/resources/cr_elements/paper_button_style_css.html new file mode 100644 index 0000000..c82c822 --- /dev/null +++ b/ui/webui/resources/cr_elements/paper_button_style_css.html
@@ -0,0 +1,28 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> + +<!-- Common paper-button styling for Material Design WebUI. --> +<dom-module id="paper-button-style"> + <template> + <style> + paper-button { + --paper-button: { + -webkit-padding-end: var(--cr-button-edge-spacing); + -webkit-padding-start: var(--cr-button-edge-spacing); + color: var(--paper-grey-600); + font-weight: 500; + min-width: 1em; /* A tighter fit than 5.14em for short buttons. */ + text-decoration: none; + }; + --paper-button-flat-keyboard-focus: { + background: rgba(0, 0, 0, .12); + }; + flex-shrink: 0; + height: 36px; + margin: 0; + } + </style> + </template> +</dom-module>
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html index 4ce2020..224a9476 100644 --- a/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -1,4 +1,5 @@ <link rel="import" href="chrome://resources/html/polymer.html"> + <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <!-- Common css variables for Material Design WebUI. --> @@ -8,6 +9,8 @@ cursor: pointer; }; + --cr-button-edge-spacing: 12px; + /* Spacing between policy (controlledBy) indicator and control. */ --cr-controlled-by-spacing: 24px;
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp index 4cd422e..d9db27b 100644 --- a/ui/webui/resources/cr_elements_resources.grdp +++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -176,6 +176,9 @@ file="../../webui/resources/cr_elements/cr_icons_css.html" flattenhtml="true" type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_PAPER_BUTTON_STYLE_CSS_HTML" + file="../../webui/resources/cr_elements/paper_button_style_css.html" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_SHARED_VARS_CSS_HTML" file="../../webui/resources/cr_elements/shared_vars_css.html" type="chrome_html" />